2026-04-14-8 auth and commercial
This commit is contained in:
+4
-4
@@ -1,7 +1,7 @@
|
||||
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { AuthService } from '../../auth/auth.service';
|
||||
export declare class ApiKeyGuard implements CanActivate {
|
||||
private configService;
|
||||
constructor(configService: ConfigService);
|
||||
canActivate(context: ExecutionContext): boolean;
|
||||
private authService;
|
||||
constructor(authService: AuthService);
|
||||
canActivate(context: ExecutionContext): Promise<boolean>;
|
||||
}
|
||||
|
||||
+21
-11
@@ -11,25 +11,35 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ApiKeyGuard = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const config_1 = require("@nestjs/config");
|
||||
const auth_service_1 = require("../../auth/auth.service");
|
||||
let ApiKeyGuard = class ApiKeyGuard {
|
||||
configService;
|
||||
constructor(configService) {
|
||||
this.configService = configService;
|
||||
authService;
|
||||
constructor(authService) {
|
||||
this.authService = authService;
|
||||
}
|
||||
canActivate(context) {
|
||||
async canActivate(context) {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const apiKeyHeader = request.headers['x-api-key'];
|
||||
const validApiKey = this.configService.get('API_KEY');
|
||||
if (validApiKey && apiKeyHeader !== validApiKey) {
|
||||
throw new common_1.UnauthorizedException('Invalid or missing API Key');
|
||||
const apiKeyHeader = request.headers['x-api-key'] || request.query['api_key'];
|
||||
if (!apiKeyHeader) {
|
||||
throw new common_1.UnauthorizedException('API Key (x-api-key) is missing');
|
||||
}
|
||||
const origin = request.headers['origin'];
|
||||
const referer = request.headers['referer'];
|
||||
try {
|
||||
const { tenant, apiKey, rateLimit } = await this.authService.validateApiKey(apiKeyHeader, origin, referer);
|
||||
request['tenant'] = tenant;
|
||||
request['apiKey'] = apiKey;
|
||||
request['rateLimit'] = rateLimit;
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
throw new common_1.UnauthorizedException(error.message || 'Invalid API Key');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
exports.ApiKeyGuard = ApiKeyGuard;
|
||||
exports.ApiKeyGuard = ApiKeyGuard = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [config_1.ConfigService])
|
||||
__metadata("design:paramtypes", [auth_service_1.AuthService])
|
||||
], ApiKeyGuard);
|
||||
//# sourceMappingURL=api-key.guard.js.map
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":3,"file":"api-key.guard.js","sourceRoot":"","sources":["../../../src/common/guards/api-key.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AACxB,2CAA+C;AAGxC,IAAM,WAAW,GAAjB,MAAM,WAAW;IACF;IAApB,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAEpD,WAAW,CAAC,OAAyB;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,SAAS,CAAC,CAAC;QAG9D,IAAI,WAAW,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;YAChD,MAAM,IAAI,8BAAqB,CAAC,4BAA4B,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAfY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;qCAEwB,sBAAa;GADrC,WAAW,CAevB"}
|
||||
{"version":3,"file":"api-key.guard.js","sourceRoot":"","sources":["../../../src/common/guards/api-key.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AACxB,0DAAsD;AAG/C,IAAM,WAAW,GAAjB,MAAM,WAAW;IACF;IAApB,YAAoB,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAAG,CAAC;IAEhD,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAGpD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE9E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,8BAAqB,CAAC,gCAAgC,CAAC,CAAC;QACpE,CAAC;QAGD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC;YAEH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CACzE,YAAY,EACZ,MAAM,EACN,OAAO,CACR,CAAC;YAGF,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;YAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;YAC3B,OAAO,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;YAEjC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,8BAAqB,CAAC,KAAK,CAAC,OAAO,IAAI,iBAAiB,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF,CAAA;AAnCY,kCAAW;sBAAX,WAAW;IADvB,IAAA,mBAAU,GAAE;qCAEsB,0BAAW;GADjC,WAAW,CAmCvB"}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { ThrottlerGuard, ThrottlerRequest } from '@nestjs/throttler';
|
||||
export declare class TenantThrottlerGuard extends ThrottlerGuard {
|
||||
protected getTracker(req: Record<string, any>): Promise<string>;
|
||||
protected handleRequest(requestProps: ThrottlerRequest): Promise<boolean>;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TenantThrottlerGuard = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const throttler_1 = require("@nestjs/throttler");
|
||||
let TenantThrottlerGuard = class TenantThrottlerGuard extends throttler_1.ThrottlerGuard {
|
||||
async getTracker(req) {
|
||||
const apiKeyId = req['apiKey']?.id || req.ip;
|
||||
return `throttler:key:${apiKeyId}`;
|
||||
}
|
||||
async handleRequest(requestProps) {
|
||||
const { context, limit } = requestProps;
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const dynamicLimit = request['rateLimit'] || limit;
|
||||
requestProps.limit = dynamicLimit;
|
||||
return super.handleRequest(requestProps);
|
||||
}
|
||||
};
|
||||
exports.TenantThrottlerGuard = TenantThrottlerGuard;
|
||||
exports.TenantThrottlerGuard = TenantThrottlerGuard = __decorate([
|
||||
(0, common_1.Injectable)()
|
||||
], TenantThrottlerGuard);
|
||||
//# sourceMappingURL=rate-limiter.guard.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"rate-limiter.guard.js","sourceRoot":"","sources":["../../../src/common/guards/rate-limiter.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA8D;AAC9D,iDAAqE;AAG9D,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,0BAAc;IAK5C,KAAK,CAAC,UAAU,CAAC,GAAwB;QAEjD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,iBAAiB,QAAQ,EAAE,CAAC;IACrC,CAAC;IAKS,KAAK,CAAC,aAAa,CAC3B,YAA8B;QAE9B,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC;QACxC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAGpD,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC;QAGnD,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC;QAGlC,OAAO,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AA7BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;GACA,oBAAoB,CA6BhC"}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
export declare class TelegramService {
|
||||
private configService;
|
||||
private readonly logger;
|
||||
private readonly botToken;
|
||||
private readonly chatId;
|
||||
constructor(configService: ConfigService);
|
||||
sendMessage(text: string): Promise<boolean>;
|
||||
sendIntelligenceReport(stats: {
|
||||
syncResult: number;
|
||||
updatedSegments: number;
|
||||
discoveredRoads: number;
|
||||
totalPoints: number;
|
||||
days: number;
|
||||
timeProfiles?: number;
|
||||
}): Promise<boolean>;
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var TelegramService_1;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TelegramService = void 0;
|
||||
const common_1 = require("@nestjs/common");
|
||||
const config_1 = require("@nestjs/config");
|
||||
const axios_1 = __importDefault(require("axios"));
|
||||
let TelegramService = TelegramService_1 = class TelegramService {
|
||||
configService;
|
||||
logger = new common_1.Logger(TelegramService_1.name);
|
||||
botToken;
|
||||
chatId;
|
||||
constructor(configService) {
|
||||
this.configService = configService;
|
||||
this.botToken = this.configService.get('TELEGRAM_BOT_TOKEN') || '';
|
||||
this.chatId = this.configService.get('TELEGRAM_CHAT_ID') || '';
|
||||
}
|
||||
async sendMessage(text) {
|
||||
if (!this.botToken || !this.chatId || this.botToken.includes('YOUR_BOT_TOKEN')) {
|
||||
this.logger.warn('Telegram Bot Token or Chat ID not configured. Skipping notification.');
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
this.logger.log('Sending report to Telegram...');
|
||||
const url = `https://api.telegram.org/bot${this.botToken}/sendMessage`;
|
||||
await axios_1.default.post(url, {
|
||||
chat_id: this.chatId,
|
||||
text: text,
|
||||
parse_mode: 'HTML',
|
||||
});
|
||||
this.logger.log('✅ Telegram notification sent successfully.');
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
this.logger.error(`❌ Failed to send Telegram message: ${error.message}`);
|
||||
if (error.response) {
|
||||
this.logger.error(`Status: ${error.response.status}, Data: ${JSON.stringify(error.response.data)}`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async sendIntelligenceReport(stats) {
|
||||
const message = `
|
||||
🚀 <b>Intaleq Map Intelligence Report</b>
|
||||
━━━━━━━━━━━━━━━━━━
|
||||
📅 <b>Window:</b> Last ${stats.days} days
|
||||
📥 <b>Tracks Imported:</b> ${stats.syncResult} points
|
||||
🛣️ <b>Roads Updated:</b> ${stats.updatedSegments} segments
|
||||
✨ <b>New Roads Found:</b> ${stats.discoveredRoads} candidates
|
||||
🕒 <b>Time Profiles:</b> ${stats.timeProfiles || 0} buckets
|
||||
📍 <b>Database Total:</b> ${stats.totalPoints} points
|
||||
━━━━━━━━━━━━━━━━━━
|
||||
✅ <i>Deep Sync and Analysis Complete.</i>
|
||||
`;
|
||||
return this.sendMessage(message);
|
||||
}
|
||||
};
|
||||
exports.TelegramService = TelegramService;
|
||||
exports.TelegramService = TelegramService = TelegramService_1 = __decorate([
|
||||
(0, common_1.Injectable)(),
|
||||
__metadata("design:paramtypes", [config_1.ConfigService])
|
||||
], TelegramService);
|
||||
//# sourceMappingURL=telegram.service.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"telegram.service.js","sourceRoot":"","sources":["../../src/common/telegram.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,2CAA+C;AAC/C,kDAA0B;AAGnB,IAAM,eAAe,uBAArB,MAAM,eAAe;IAKN;IAJH,MAAM,GAAG,IAAI,eAAM,CAAC,iBAAe,CAAC,IAAI,CAAC,CAAC;IAC1C,QAAQ,CAAS;IACjB,MAAM,CAAS;IAEhC,YAAoB,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,oBAAoB,CAAC,IAAI,EAAE,CAAC;QAC3E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAS,kBAAkB,CAAC,IAAI,EAAE,CAAC;IACzE,CAAC;IAMD,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC/E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;YACzF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACjD,MAAM,GAAG,GAAG,+BAA+B,IAAI,CAAC,QAAQ,cAAc,CAAC;YACvE,MAAM,eAAK,CAAC,IAAI,CAAC,GAAG,EAAE;gBACpB,OAAO,EAAE,IAAI,CAAC,MAAM;gBACpB,IAAI,EAAE,IAAI;gBACV,UAAU,EAAE,MAAM;aACnB,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACzE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC,QAAQ,CAAC,MAAM,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtG,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAKD,KAAK,CAAC,sBAAsB,CAAC,KAO5B;QACC,MAAM,OAAO,GAAG;;;yBAGK,KAAK,CAAC,IAAI;6BACN,KAAK,CAAC,UAAU;4BACjB,KAAK,CAAC,eAAe;4BACrB,KAAK,CAAC,eAAe;2BACtB,KAAK,CAAC,YAAY,IAAI,CAAC;4BACtB,KAAK,CAAC,WAAW;;;KAGxC,CAAC;QACF,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACF,CAAA;AAhEY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;qCAMwB,sBAAa;GALrC,eAAe,CAgE3B"}
|
||||
Reference in New Issue
Block a user