@pawells/nestjs-shared 1.0.0-dev.4c8c698
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +802 -0
- package/build/LICENSE +21 -0
- package/build/README.md +802 -0
- package/build/common/common.module.d.ts +49 -0
- package/build/common/common.module.d.ts.map +1 -0
- package/build/common/common.module.js +178 -0
- package/build/common/common.module.js.map +1 -0
- package/build/common/constants/histogram-buckets.constants.d.ts +12 -0
- package/build/common/constants/histogram-buckets.constants.d.ts.map +1 -0
- package/build/common/constants/histogram-buckets.constants.js +51 -0
- package/build/common/constants/histogram-buckets.constants.js.map +1 -0
- package/build/common/constants/http-status.constants.d.ts +27 -0
- package/build/common/constants/http-status.constants.d.ts.map +1 -0
- package/build/common/constants/http-status.constants.js +27 -0
- package/build/common/constants/http-status.constants.js.map +1 -0
- package/build/common/constants/timeout.constants.d.ts +29 -0
- package/build/common/constants/timeout.constants.d.ts.map +1 -0
- package/build/common/constants/timeout.constants.js +45 -0
- package/build/common/constants/timeout.constants.js.map +1 -0
- package/build/common/controllers/metrics.controller.d.ts +23 -0
- package/build/common/controllers/metrics.controller.d.ts.map +1 -0
- package/build/common/controllers/metrics.controller.js +66 -0
- package/build/common/controllers/metrics.controller.js.map +1 -0
- package/build/common/decorators/common-decorators.d.ts +90 -0
- package/build/common/decorators/common-decorators.d.ts.map +1 -0
- package/build/common/decorators/common-decorators.js +101 -0
- package/build/common/decorators/common-decorators.js.map +1 -0
- package/build/common/decorators/decorator-factory.d.ts +108 -0
- package/build/common/decorators/decorator-factory.d.ts.map +1 -0
- package/build/common/decorators/decorator-factory.js +104 -0
- package/build/common/decorators/decorator-factory.js.map +1 -0
- package/build/common/decorators/guard.decorators.d.ts +48 -0
- package/build/common/decorators/guard.decorators.d.ts.map +1 -0
- package/build/common/decorators/guard.decorators.js +49 -0
- package/build/common/decorators/guard.decorators.js.map +1 -0
- package/build/common/decorators/index.d.ts +10 -0
- package/build/common/decorators/index.d.ts.map +1 -0
- package/build/common/decorators/index.js +11 -0
- package/build/common/decorators/index.js.map +1 -0
- package/build/common/decorators/instrument.decorator.d.ts +128 -0
- package/build/common/decorators/instrument.decorator.d.ts.map +1 -0
- package/build/common/decorators/instrument.decorator.js +165 -0
- package/build/common/decorators/instrument.decorator.js.map +1 -0
- package/build/common/decorators/metric.decorators.d.ts +42 -0
- package/build/common/decorators/metric.decorators.d.ts.map +1 -0
- package/build/common/decorators/metric.decorators.js +85 -0
- package/build/common/decorators/metric.decorators.js.map +1 -0
- package/build/common/decorators/request-property.decorator.d.ts +65 -0
- package/build/common/decorators/request-property.decorator.d.ts.map +1 -0
- package/build/common/decorators/request-property.decorator.js +102 -0
- package/build/common/decorators/request-property.decorator.js.map +1 -0
- package/build/common/errors/base-application-error.d.ts +98 -0
- package/build/common/errors/base-application-error.d.ts.map +1 -0
- package/build/common/errors/base-application-error.js +133 -0
- package/build/common/errors/base-application-error.js.map +1 -0
- package/build/common/errors/error-factory.d.ts +93 -0
- package/build/common/errors/error-factory.d.ts.map +1 -0
- package/build/common/errors/error-factory.js +105 -0
- package/build/common/errors/error-factory.js.map +1 -0
- package/build/common/errors/index.d.ts +13 -0
- package/build/common/errors/index.d.ts.map +1 -0
- package/build/common/errors/index.js +15 -0
- package/build/common/errors/index.js.map +1 -0
- package/build/common/factories/index.d.ts +5 -0
- package/build/common/factories/index.d.ts.map +1 -0
- package/build/common/factories/index.js +3 -0
- package/build/common/factories/index.js.map +1 -0
- package/build/common/factories/module-factory.d.ts +178 -0
- package/build/common/factories/module-factory.d.ts.map +1 -0
- package/build/common/factories/module-factory.js +253 -0
- package/build/common/factories/module-factory.js.map +1 -0
- package/build/common/factories/rate-limit-config.factory.d.ts +79 -0
- package/build/common/factories/rate-limit-config.factory.d.ts.map +1 -0
- package/build/common/factories/rate-limit-config.factory.js +115 -0
- package/build/common/factories/rate-limit-config.factory.js.map +1 -0
- package/build/common/factories/security-bootstrap.factory.d.ts +77 -0
- package/build/common/factories/security-bootstrap.factory.d.ts.map +1 -0
- package/build/common/factories/security-bootstrap.factory.js +222 -0
- package/build/common/factories/security-bootstrap.factory.js.map +1 -0
- package/build/common/filters/global-exception.filter.d.ts +78 -0
- package/build/common/filters/global-exception.filter.d.ts.map +1 -0
- package/build/common/filters/global-exception.filter.js +192 -0
- package/build/common/filters/global-exception.filter.js.map +1 -0
- package/build/common/filters/http-exception.filter.d.ts +37 -0
- package/build/common/filters/http-exception.filter.d.ts.map +1 -0
- package/build/common/filters/http-exception.filter.js +91 -0
- package/build/common/filters/http-exception.filter.js.map +1 -0
- package/build/common/guards/csrf.guard.d.ts +53 -0
- package/build/common/guards/csrf.guard.d.ts.map +1 -0
- package/build/common/guards/csrf.guard.js +109 -0
- package/build/common/guards/csrf.guard.js.map +1 -0
- package/build/common/guards/metrics.guard.d.ts +42 -0
- package/build/common/guards/metrics.guard.d.ts.map +1 -0
- package/build/common/guards/metrics.guard.js +124 -0
- package/build/common/guards/metrics.guard.js.map +1 -0
- package/build/common/index.d.ts +43 -0
- package/build/common/index.d.ts.map +1 -0
- package/build/common/index.js +50 -0
- package/build/common/index.js.map +1 -0
- package/build/common/interceptors/http-client.interceptor.d.ts +11 -0
- package/build/common/interceptors/http-client.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/http-client.interceptor.js +69 -0
- package/build/common/interceptors/http-client.interceptor.js.map +1 -0
- package/build/common/interceptors/http-instrumentation.interceptor.d.ts +64 -0
- package/build/common/interceptors/http-instrumentation.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/http-instrumentation.interceptor.js +148 -0
- package/build/common/interceptors/http-instrumentation.interceptor.js.map +1 -0
- package/build/common/interceptors/http-metrics.interceptor.d.ts +46 -0
- package/build/common/interceptors/http-metrics.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/http-metrics.interceptor.js +120 -0
- package/build/common/interceptors/http-metrics.interceptor.js.map +1 -0
- package/build/common/interceptors/logging.interceptor.d.ts +22 -0
- package/build/common/interceptors/logging.interceptor.d.ts.map +1 -0
- package/build/common/interceptors/logging.interceptor.js +67 -0
- package/build/common/interceptors/logging.interceptor.js.map +1 -0
- package/build/common/interfaces/cache-provider.interface.d.ts +54 -0
- package/build/common/interfaces/cache-provider.interface.d.ts.map +1 -0
- package/build/common/interfaces/cache-provider.interface.js +6 -0
- package/build/common/interfaces/cache-provider.interface.js.map +1 -0
- package/build/common/interfaces/index.d.ts +7 -0
- package/build/common/interfaces/index.d.ts.map +1 -0
- package/build/common/interfaces/index.js +3 -0
- package/build/common/interfaces/index.js.map +1 -0
- package/build/common/interfaces/log-context.interface.d.ts +77 -0
- package/build/common/interfaces/log-context.interface.d.ts.map +1 -0
- package/build/common/interfaces/log-context.interface.js +2 -0
- package/build/common/interfaces/log-context.interface.js.map +1 -0
- package/build/common/interfaces/log-entry.interface.d.ts +26 -0
- package/build/common/interfaces/log-entry.interface.d.ts.map +1 -0
- package/build/common/interfaces/log-entry.interface.js +33 -0
- package/build/common/interfaces/log-entry.interface.js.map +1 -0
- package/build/common/interfaces/logger.interface.d.ts +62 -0
- package/build/common/interfaces/logger.interface.d.ts.map +1 -0
- package/build/common/interfaces/logger.interface.js +2 -0
- package/build/common/interfaces/logger.interface.js.map +1 -0
- package/build/common/interfaces/metrics-exporter.interface.d.ts +275 -0
- package/build/common/interfaces/metrics-exporter.interface.d.ts.map +1 -0
- package/build/common/interfaces/metrics-exporter.interface.js +8 -0
- package/build/common/interfaces/metrics-exporter.interface.js.map +1 -0
- package/build/common/metrics/base-metrics-collector.d.ts +81 -0
- package/build/common/metrics/base-metrics-collector.d.ts.map +1 -0
- package/build/common/metrics/base-metrics-collector.js +88 -0
- package/build/common/metrics/base-metrics-collector.js.map +1 -0
- package/build/common/metrics/index.d.ts +2 -0
- package/build/common/metrics/index.d.ts.map +1 -0
- package/build/common/metrics/index.js +2 -0
- package/build/common/metrics/index.js.map +1 -0
- package/build/common/metrics.module.d.ts +50 -0
- package/build/common/metrics.module.d.ts.map +1 -0
- package/build/common/metrics.module.js +77 -0
- package/build/common/metrics.module.js.map +1 -0
- package/build/common/modules/throttler.module.d.ts +69 -0
- package/build/common/modules/throttler.module.d.ts.map +1 -0
- package/build/common/modules/throttler.module.js +117 -0
- package/build/common/modules/throttler.module.js.map +1 -0
- package/build/common/pipes/base-validation.pipe.d.ts +67 -0
- package/build/common/pipes/base-validation.pipe.d.ts.map +1 -0
- package/build/common/pipes/base-validation.pipe.js +95 -0
- package/build/common/pipes/base-validation.pipe.js.map +1 -0
- package/build/common/pipes/validation.pipe.d.ts +32 -0
- package/build/common/pipes/validation.pipe.d.ts.map +1 -0
- package/build/common/pipes/validation.pipe.js +60 -0
- package/build/common/pipes/validation.pipe.js.map +1 -0
- package/build/common/registry/instrumentation-registry.d.ts +227 -0
- package/build/common/registry/instrumentation-registry.d.ts.map +1 -0
- package/build/common/registry/instrumentation-registry.js +414 -0
- package/build/common/registry/instrumentation-registry.js.map +1 -0
- package/build/common/services/audit-logger.service.d.ts +91 -0
- package/build/common/services/audit-logger.service.d.ts.map +1 -0
- package/build/common/services/audit-logger.service.js +180 -0
- package/build/common/services/audit-logger.service.js.map +1 -0
- package/build/common/services/csrf.service.d.ts +202 -0
- package/build/common/services/csrf.service.d.ts.map +1 -0
- package/build/common/services/csrf.service.js +478 -0
- package/build/common/services/csrf.service.js.map +1 -0
- package/build/common/services/error-categorizer.service.d.ts +82 -0
- package/build/common/services/error-categorizer.service.d.ts.map +1 -0
- package/build/common/services/error-categorizer.service.js +339 -0
- package/build/common/services/error-categorizer.service.js.map +1 -0
- package/build/common/services/error-sanitizer.service.d.ts +146 -0
- package/build/common/services/error-sanitizer.service.d.ts.map +1 -0
- package/build/common/services/error-sanitizer.service.js +287 -0
- package/build/common/services/error-sanitizer.service.js.map +1 -0
- package/build/common/services/health-check.service.d.ts +86 -0
- package/build/common/services/health-check.service.d.ts.map +1 -0
- package/build/common/services/health-check.service.js +132 -0
- package/build/common/services/health-check.service.js.map +1 -0
- package/build/common/services/http-client.service.d.ts +113 -0
- package/build/common/services/http-client.service.d.ts.map +1 -0
- package/build/common/services/http-client.service.js +294 -0
- package/build/common/services/http-client.service.js.map +1 -0
- package/build/common/services/logger.service.d.ts +189 -0
- package/build/common/services/logger.service.d.ts.map +1 -0
- package/build/common/services/logger.service.js +423 -0
- package/build/common/services/logger.service.js.map +1 -0
- package/build/common/services/metrics-registry.service.d.ts +98 -0
- package/build/common/services/metrics-registry.service.d.ts.map +1 -0
- package/build/common/services/metrics-registry.service.js +262 -0
- package/build/common/services/metrics-registry.service.js.map +1 -0
- package/build/common/services/nest-logger-adapter.service.d.ts +62 -0
- package/build/common/services/nest-logger-adapter.service.d.ts.map +1 -0
- package/build/common/services/nest-logger-adapter.service.js +120 -0
- package/build/common/services/nest-logger-adapter.service.js.map +1 -0
- package/build/common/utils/error.utils.d.ts +16 -0
- package/build/common/utils/error.utils.d.ts.map +1 -0
- package/build/common/utils/error.utils.js +26 -0
- package/build/common/utils/error.utils.js.map +1 -0
- package/build/common/utils/lazy-getter.types.d.ts +190 -0
- package/build/common/utils/lazy-getter.types.d.ts.map +1 -0
- package/build/common/utils/lazy-getter.types.js +114 -0
- package/build/common/utils/lazy-getter.types.js.map +1 -0
- package/build/common/utils/module.utils.d.ts +33 -0
- package/build/common/utils/module.utils.d.ts.map +1 -0
- package/build/common/utils/module.utils.js +48 -0
- package/build/common/utils/module.utils.js.map +1 -0
- package/build/common/utils/sanitization.utils.d.ts +69 -0
- package/build/common/utils/sanitization.utils.d.ts.map +1 -0
- package/build/common/utils/sanitization.utils.js +141 -0
- package/build/common/utils/sanitization.utils.js.map +1 -0
- package/build/config/config.module.d.ts +30 -0
- package/build/config/config.module.d.ts.map +1 -0
- package/build/config/config.module.js +49 -0
- package/build/config/config.module.js.map +1 -0
- package/build/config/config.service.d.ts +74 -0
- package/build/config/config.service.d.ts.map +1 -0
- package/build/config/config.service.js +145 -0
- package/build/config/config.service.js.map +1 -0
- package/build/config/config.types.d.ts +143 -0
- package/build/config/config.types.d.ts.map +1 -0
- package/build/config/config.types.js +2 -0
- package/build/config/config.types.js.map +1 -0
- package/build/config/decorators/config.decorators.d.ts +43 -0
- package/build/config/decorators/config.decorators.d.ts.map +1 -0
- package/build/config/decorators/config.decorators.js +68 -0
- package/build/config/decorators/config.decorators.js.map +1 -0
- package/build/config/decorators/index.d.ts +2 -0
- package/build/config/decorators/index.d.ts.map +1 -0
- package/build/config/decorators/index.js +2 -0
- package/build/config/decorators/index.js.map +1 -0
- package/build/config/index.d.ts +7 -0
- package/build/config/index.d.ts.map +1 -0
- package/build/config/index.js +9 -0
- package/build/config/index.js.map +1 -0
- package/build/config/validation.utils.d.ts +136 -0
- package/build/config/validation.utils.d.ts.map +1 -0
- package/build/config/validation.utils.js +263 -0
- package/build/config/validation.utils.js.map +1 -0
- package/build/errors/index.d.ts +9 -0
- package/build/errors/index.d.ts.map +1 -0
- package/build/errors/index.js +12 -0
- package/build/errors/index.js.map +1 -0
- package/build/guards/custom-throttle.guard.d.ts +28 -0
- package/build/guards/custom-throttle.guard.d.ts.map +1 -0
- package/build/guards/custom-throttle.guard.js +52 -0
- package/build/guards/custom-throttle.guard.js.map +1 -0
- package/build/guards/index.d.ts +2 -0
- package/build/guards/index.d.ts.map +1 -0
- package/build/guards/index.js +2 -0
- package/build/guards/index.js.map +1 -0
- package/build/index.d.ts +53 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +61 -0
- package/build/index.js.map +1 -0
- package/build/logging/index.d.ts +7 -0
- package/build/logging/index.d.ts.map +1 -0
- package/build/logging/index.js +7 -0
- package/build/logging/index.js.map +1 -0
- package/build/metrics/index.d.ts +6 -0
- package/build/metrics/index.d.ts.map +1 -0
- package/build/metrics/index.js +11 -0
- package/build/metrics/index.js.map +1 -0
- package/build/package.json +72 -0
- package/build/security/index.d.ts +8 -0
- package/build/security/index.d.ts.map +1 -0
- package/build/security/index.js +11 -0
- package/build/security/index.js.map +1 -0
- package/build/test-setup.d.ts +2 -0
- package/build/test-setup.d.ts.map +1 -0
- package/build/test-setup.js +40 -0
- package/build/test-setup.js.map +1 -0
- package/build/validation/index.d.ts +6 -0
- package/build/validation/index.d.ts.map +1 -0
- package/build/validation/index.js +8 -0
- package/build/validation/index.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* CSRF Guard.
|
|
6
|
+
* Validates CSRF tokens on requests to prevent Cross-Site Request Forgery attacks.
|
|
7
|
+
* Automatically bypasses validation for safe HTTP methods (GET, HEAD, OPTIONS) and enforces
|
|
8
|
+
* token validation for state-changing operations (POST, PUT, DELETE, PATCH).
|
|
9
|
+
*
|
|
10
|
+
* CSRF validation:
|
|
11
|
+
* - Safe methods (GET, HEAD, OPTIONS): Always allowed
|
|
12
|
+
* - State-changing methods (POST, PUT, DELETE, PATCH): Token validation required
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* - Registered globally by CommonModule
|
|
16
|
+
* - Uses CSRFService for token generation and validation
|
|
17
|
+
* - Logs failed validations via AppLogger and AuditLoggerService
|
|
18
|
+
* - Throws ForbiddenException (403) on token validation failure
|
|
19
|
+
* - CSRF_SECRET environment variable required (validated by CSRFService.onModuleInit)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Automatically applied globally when CommonModule is imported
|
|
24
|
+
* // No decorator needed on endpoints
|
|
25
|
+
*
|
|
26
|
+
* // Manual application to specific controller
|
|
27
|
+
* @UseGuards(CSRFGuard)
|
|
28
|
+
* @Controller('api')
|
|
29
|
+
* export class ApiController {
|
|
30
|
+
* @Post()
|
|
31
|
+
* updateData() { ... }
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class CSRFGuard implements CanActivate, LazyModuleRefService {
|
|
36
|
+
readonly Module: ModuleRef;
|
|
37
|
+
constructor(module: ModuleRef);
|
|
38
|
+
private get CsrfService();
|
|
39
|
+
private get Logger();
|
|
40
|
+
private get AuditLogger();
|
|
41
|
+
/**
|
|
42
|
+
* Evaluate whether the current request is authorized based on CSRF token validity.
|
|
43
|
+
* Allows safe methods (GET, HEAD, OPTIONS) without validation. For state-changing
|
|
44
|
+
* requests, validates the CSRF token and logs failures for audit trails.
|
|
45
|
+
*
|
|
46
|
+
* @param context - The execution context containing request/response objects
|
|
47
|
+
* @returns true if request is authorized or safe method; throws ForbiddenException if validation fails
|
|
48
|
+
*
|
|
49
|
+
* @throws ForbiddenException when CSRF token validation fails on state-changing requests
|
|
50
|
+
*/
|
|
51
|
+
canActivate(context: ExecutionContext): boolean;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=csrf.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf.guard.d.ts","sourceRoot":"","sources":["../../../src/common/guards/csrf.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,WAAW,EAAE,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,qBACa,SAAU,YAAW,WAAW,EAAE,oBAAoB;IAClE,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,MAAM,GAMjB;IAED,OAAO,KAAK,WAAW,GAMtB;IAED;;;;;;;;;OASG;IAEI,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CA6BtD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Injectable, ForbiddenException } from '@nestjs/common';
|
|
11
|
+
import { ModuleRef } from '@nestjs/core';
|
|
12
|
+
import { CSRFService } from '../services/csrf.service.js';
|
|
13
|
+
import { AppLogger } from '../services/logger.service.js';
|
|
14
|
+
import { AuditLoggerService } from '../services/audit-logger.service.js';
|
|
15
|
+
/**
|
|
16
|
+
* CSRF Guard.
|
|
17
|
+
* Validates CSRF tokens on requests to prevent Cross-Site Request Forgery attacks.
|
|
18
|
+
* Automatically bypasses validation for safe HTTP methods (GET, HEAD, OPTIONS) and enforces
|
|
19
|
+
* token validation for state-changing operations (POST, PUT, DELETE, PATCH).
|
|
20
|
+
*
|
|
21
|
+
* CSRF validation:
|
|
22
|
+
* - Safe methods (GET, HEAD, OPTIONS): Always allowed
|
|
23
|
+
* - State-changing methods (POST, PUT, DELETE, PATCH): Token validation required
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* - Registered globally by CommonModule
|
|
27
|
+
* - Uses CSRFService for token generation and validation
|
|
28
|
+
* - Logs failed validations via AppLogger and AuditLoggerService
|
|
29
|
+
* - Throws ForbiddenException (403) on token validation failure
|
|
30
|
+
* - CSRF_SECRET environment variable required (validated by CSRFService.onModuleInit)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Automatically applied globally when CommonModule is imported
|
|
35
|
+
* // No decorator needed on endpoints
|
|
36
|
+
*
|
|
37
|
+
* // Manual application to specific controller
|
|
38
|
+
* @UseGuards(CSRFGuard)
|
|
39
|
+
* @Controller('api')
|
|
40
|
+
* export class ApiController {
|
|
41
|
+
* @Post()
|
|
42
|
+
* updateData() { ... }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
let CSRFGuard = class CSRFGuard {
|
|
47
|
+
Module;
|
|
48
|
+
constructor(module) {
|
|
49
|
+
this.Module = module;
|
|
50
|
+
}
|
|
51
|
+
get CsrfService() {
|
|
52
|
+
return this.Module.get(CSRFService);
|
|
53
|
+
}
|
|
54
|
+
get Logger() {
|
|
55
|
+
try {
|
|
56
|
+
return this.Module.get(AppLogger, { strict: false });
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
get AuditLogger() {
|
|
63
|
+
try {
|
|
64
|
+
return this.Module.get(AuditLoggerService, { strict: false });
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Evaluate whether the current request is authorized based on CSRF token validity.
|
|
72
|
+
* Allows safe methods (GET, HEAD, OPTIONS) without validation. For state-changing
|
|
73
|
+
* requests, validates the CSRF token and logs failures for audit trails.
|
|
74
|
+
*
|
|
75
|
+
* @param context - The execution context containing request/response objects
|
|
76
|
+
* @returns true if request is authorized or safe method; throws ForbiddenException if validation fails
|
|
77
|
+
*
|
|
78
|
+
* @throws ForbiddenException when CSRF token validation fails on state-changing requests
|
|
79
|
+
*/
|
|
80
|
+
canActivate(context) {
|
|
81
|
+
const request = context.switchToHttp().getRequest();
|
|
82
|
+
// Skip CSRF validation for GET, HEAD, OPTIONS
|
|
83
|
+
if (['GET', 'HEAD', 'OPTIONS'].includes(request.method)) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
// Validate CSRF token
|
|
87
|
+
if (!this.CsrfService.validateToken(request)) {
|
|
88
|
+
// Extract IP address from request — prefer request.ip which respects trustProxy
|
|
89
|
+
const ipAddress = request.ip ?? request.socket?.remoteAddress ?? 'unknown';
|
|
90
|
+
const endpoint = request.path ?? request.url ?? 'unknown';
|
|
91
|
+
// Log via audit logger if available
|
|
92
|
+
this.AuditLogger?.logCsrfViolation(ipAddress, endpoint);
|
|
93
|
+
// Also log via app logger for backward compatibility
|
|
94
|
+
this.Logger?.warn('CSRF token validation failed', 'CSRFGuard', {
|
|
95
|
+
ip: ipAddress,
|
|
96
|
+
path: endpoint,
|
|
97
|
+
method: request.method,
|
|
98
|
+
});
|
|
99
|
+
throw new ForbiddenException('Invalid CSRF token');
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
CSRFGuard = __decorate([
|
|
105
|
+
Injectable(),
|
|
106
|
+
__metadata("design:paramtypes", [ModuleRef])
|
|
107
|
+
], CSRFGuard);
|
|
108
|
+
export { CSRFGuard };
|
|
109
|
+
//# sourceMappingURL=csrf.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf.guard.js","sourceRoot":"","sources":["../../../src/common/guards/csrf.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAiC,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAGzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGI,IAAM,SAAS,GAAf,MAAM,SAAS;IACL,MAAM,CAAY;IAElC,YAAY,MAAiB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,IAAY,WAAW;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAED,IAAY,MAAM;QACjB,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED,IAAY,WAAW;QACtB,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED;;;;;;;;;OASG;IAEI,WAAW,CAAC,OAAyB;QAC3C,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;QAE7D,8CAA8C;QAC9C,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,OAAO,IAAI,CAAC;QACb,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,gFAAgF;YAChF,MAAM,SAAS,GAAG,OAAO,CAAC,EAAE,IAAK,OAAO,CAAC,MAAiD,EAAE,aAAa,IAAI,SAAS,CAAC;YACvH,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,SAAS,CAAC;YAE1D,oCAAoC;YACpC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAExD,qDAAqD;YACrD,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,8BAA8B,EAAE,WAAW,EAAE;gBAC9D,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,OAAO,CAAC,MAAM;aACtB,CAAC,CAAC;YAEH,MAAM,IAAI,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAA;AAnEY,SAAS;IADrB,UAAU,EAAE;qCAIQ,SAAS;GAHjB,SAAS,CAmErB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Optional API key guard for the /metrics endpoint
|
|
6
|
+
*
|
|
7
|
+
* This guard checks for a configurable API key if the METRICS_API_KEY environment
|
|
8
|
+
* variable is set. If METRICS_API_KEY is not configured, all requests are allowed
|
|
9
|
+
* (backward compatible behavior).
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* @Controller()
|
|
14
|
+
* export class MetricsController {
|
|
15
|
+
* @Get('metrics')
|
|
16
|
+
* @UseGuards(MetricsGuard)
|
|
17
|
+
* getMetrics(@Res() response: Response) {
|
|
18
|
+
* // ...
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Environment Variables:
|
|
24
|
+
* - METRICS_API_KEY: Optional. If set, requires this API key in the Authorization header
|
|
25
|
+
* or X-API-Key header. Format: "Bearer <api-key>" or header "X-API-Key: <api-key>"
|
|
26
|
+
*/
|
|
27
|
+
export declare class MetricsGuard implements CanActivate, LazyModuleRefService {
|
|
28
|
+
readonly Module: ModuleRef;
|
|
29
|
+
constructor(module: ModuleRef);
|
|
30
|
+
private get Config();
|
|
31
|
+
private get AuditLogger();
|
|
32
|
+
private get metricsApiKey();
|
|
33
|
+
/**
|
|
34
|
+
* Timing-safe comparison of two strings to prevent timing attacks
|
|
35
|
+
* @param a First string to compare
|
|
36
|
+
* @param b Second string to compare
|
|
37
|
+
* @returns true if strings are equal, false otherwise
|
|
38
|
+
*/
|
|
39
|
+
private timingSafeCompare;
|
|
40
|
+
canActivate(context: ExecutionContext): boolean;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=metrics.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.guard.d.ts","sourceRoot":"","sources":["../../../src/common/guards/metrics.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,WAAW,EAAE,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBACa,YAAa,YAAW,WAAW,EAAE,oBAAoB;IACrE,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,MAAM,GAEjB;IAED,OAAO,KAAK,WAAW,GAMtB;IAED,OAAO,KAAK,aAAa,GAExB;IAED;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAmBlB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CA2CtD"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Injectable, ForbiddenException } from '@nestjs/common';
|
|
11
|
+
import { ModuleRef } from '@nestjs/core';
|
|
12
|
+
import { timingSafeEqual } from 'crypto';
|
|
13
|
+
import { ConfigService } from '../../config/config.service.js';
|
|
14
|
+
import { AuditLoggerService } from '../services/audit-logger.service.js';
|
|
15
|
+
/**
|
|
16
|
+
* Optional API key guard for the /metrics endpoint
|
|
17
|
+
*
|
|
18
|
+
* This guard checks for a configurable API key if the METRICS_API_KEY environment
|
|
19
|
+
* variable is set. If METRICS_API_KEY is not configured, all requests are allowed
|
|
20
|
+
* (backward compatible behavior).
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* ```typescript
|
|
24
|
+
* @Controller()
|
|
25
|
+
* export class MetricsController {
|
|
26
|
+
* @Get('metrics')
|
|
27
|
+
* @UseGuards(MetricsGuard)
|
|
28
|
+
* getMetrics(@Res() response: Response) {
|
|
29
|
+
* // ...
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Environment Variables:
|
|
35
|
+
* - METRICS_API_KEY: Optional. If set, requires this API key in the Authorization header
|
|
36
|
+
* or X-API-Key header. Format: "Bearer <api-key>" or header "X-API-Key: <api-key>"
|
|
37
|
+
*/
|
|
38
|
+
let MetricsGuard = class MetricsGuard {
|
|
39
|
+
Module;
|
|
40
|
+
constructor(module) {
|
|
41
|
+
this.Module = module;
|
|
42
|
+
}
|
|
43
|
+
get Config() {
|
|
44
|
+
return this.Module.get(ConfigService);
|
|
45
|
+
}
|
|
46
|
+
get AuditLogger() {
|
|
47
|
+
try {
|
|
48
|
+
return this.Module.get(AuditLoggerService, { strict: false });
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
get metricsApiKey() {
|
|
55
|
+
return this.Config.get('METRICS_API_KEY');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Timing-safe comparison of two strings to prevent timing attacks
|
|
59
|
+
* @param a First string to compare
|
|
60
|
+
* @param b Second string to compare
|
|
61
|
+
* @returns true if strings are equal, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
timingSafeCompare(a, b) {
|
|
64
|
+
if (!b) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const bufferA = Buffer.from(a);
|
|
69
|
+
const bufferB = Buffer.from(b);
|
|
70
|
+
if (bufferA.length !== bufferB.length) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return timingSafeEqual(bufferA, bufferB);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
canActivate(context) {
|
|
80
|
+
// If no API key is configured, allow all requests
|
|
81
|
+
if (!this.metricsApiKey) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
const request = context.switchToHttp().getRequest();
|
|
85
|
+
// Check Authorization header (Bearer token)
|
|
86
|
+
const authHeader = request.headers.authorization;
|
|
87
|
+
if (authHeader) {
|
|
88
|
+
const [scheme, token] = authHeader.split(' ');
|
|
89
|
+
if (scheme?.toLowerCase() === 'bearer' && token && this.timingSafeCompare(token, this.metricsApiKey)) {
|
|
90
|
+
this.AuditLogger?.logSecurityEvent({
|
|
91
|
+
timestamp: new Date(),
|
|
92
|
+
action: 'metrics_access',
|
|
93
|
+
resource: '/metrics',
|
|
94
|
+
result: 'success',
|
|
95
|
+
ipAddress: request.ip,
|
|
96
|
+
userAgent: request.get('User-Agent'),
|
|
97
|
+
details: { authMethod: 'bearer' },
|
|
98
|
+
});
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Check X-API-Key header
|
|
103
|
+
const apiKeyHeader = request.headers['x-api-key'];
|
|
104
|
+
if (apiKeyHeader && this.timingSafeCompare(apiKeyHeader, this.metricsApiKey)) {
|
|
105
|
+
this.AuditLogger?.logSecurityEvent({
|
|
106
|
+
timestamp: new Date(),
|
|
107
|
+
action: 'metrics_access',
|
|
108
|
+
resource: '/metrics',
|
|
109
|
+
result: 'success',
|
|
110
|
+
ipAddress: request.ip,
|
|
111
|
+
userAgent: request.get('User-Agent'),
|
|
112
|
+
details: { authMethod: 'x-api-key' },
|
|
113
|
+
});
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
throw new ForbiddenException('Invalid or missing metrics API key');
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
MetricsGuard = __decorate([
|
|
120
|
+
Injectable(),
|
|
121
|
+
__metadata("design:paramtypes", [ModuleRef])
|
|
122
|
+
], MetricsGuard);
|
|
123
|
+
export { MetricsGuard };
|
|
124
|
+
//# sourceMappingURL=metrics.guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.guard.js","sourceRoot":"","sources":["../../../src/common/guards/metrics.guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export { GlobalExceptionFilter } from './filters/global-exception.filter.js';
|
|
2
|
+
export { HttpExceptionFilter } from './filters/http-exception.filter.js';
|
|
3
|
+
export { LoggingInterceptor } from './interceptors/logging.interceptor.js';
|
|
4
|
+
export { HTTPMetricsInterceptor } from './interceptors/http-metrics.interceptor.js';
|
|
5
|
+
export { BaseValidationPipe } from './pipes/base-validation.pipe.js';
|
|
6
|
+
export { ValidationPipe } from './pipes/validation.pipe.js';
|
|
7
|
+
export * from './decorators/index.js';
|
|
8
|
+
export type { BaseDecoratorOptions } from './decorators/index.js';
|
|
9
|
+
export * from './decorators/metric.decorators.js';
|
|
10
|
+
export type { LogContext, LogEntry, LogMetadata } from './interfaces/index.js';
|
|
11
|
+
export { LogLevel, LOG_LEVEL_STRINGS } from './interfaces/index.js';
|
|
12
|
+
export type { ILogger, IContextualLogger } from './interfaces/index.js';
|
|
13
|
+
export type { ICacheProvider } from './interfaces/index.js';
|
|
14
|
+
export { CACHE_PROVIDER } from './interfaces/index.js';
|
|
15
|
+
export { AppLogger } from './services/logger.service.js';
|
|
16
|
+
export { NestLoggerAdapter } from './services/nest-logger-adapter.service.js';
|
|
17
|
+
export { AuditLoggerService } from './services/audit-logger.service.js';
|
|
18
|
+
export { ErrorSanitizerService, ERROR_SANITIZER_OPTIONS, type ErrorSanitizerOptions } from './services/error-sanitizer.service.js';
|
|
19
|
+
export { ErrorCategorizerService } from './services/error-categorizer.service.js';
|
|
20
|
+
export { HttpClientService } from './services/http-client.service.js';
|
|
21
|
+
export { CSRFService } from './services/csrf.service.js';
|
|
22
|
+
export { MetricsRegistryService } from './services/metrics-registry.service.js';
|
|
23
|
+
export { HealthCheckService, HealthStatus, type IHealthCheck } from './services/health-check.service.js';
|
|
24
|
+
export { BaseMetricsCollector } from './metrics/index.js';
|
|
25
|
+
export { MetricsController } from './controllers/metrics.controller.js';
|
|
26
|
+
export { CSRFGuard } from './guards/csrf.guard.js';
|
|
27
|
+
export { MetricsGuard } from './guards/metrics.guard.js';
|
|
28
|
+
export { CommonModule } from './common.module.js';
|
|
29
|
+
export { MetricsModule } from './metrics.module.js';
|
|
30
|
+
export { SharedThrottlerModule, type SharedThrottlerConfig } from './modules/throttler.module.js';
|
|
31
|
+
export * from './factories/module-factory.js';
|
|
32
|
+
export { ApplySecurityMiddleware } from './factories/security-bootstrap.factory.js';
|
|
33
|
+
export type { SecurityBootstrapOptions } from './factories/security-bootstrap.factory.js';
|
|
34
|
+
export { CreateRateLimitConfig } from './factories/rate-limit-config.factory.js';
|
|
35
|
+
export type { RateLimitConfig, RateLimitDescriptor } from './factories/rate-limit-config.factory.js';
|
|
36
|
+
export * from './utils/lazy-getter.types.js';
|
|
37
|
+
export { escapeNewlines, sanitizeObject, sanitizeXss, MAX_SANITIZE_DEPTH } from './utils/sanitization.utils.js';
|
|
38
|
+
export { getErrorStack, getErrorMessage } from './utils/error.utils.js';
|
|
39
|
+
export { AsyncModuleOptions, createAsyncOptionsProvider, createAsyncProviders } from './utils/module.utils.js';
|
|
40
|
+
export * from './constants/http-status.constants.js';
|
|
41
|
+
export { GRAFANA_TIMEOUT, LOKI_TIMEOUT, PROMETHEUS_TIMEOUT, HTTP_CLIENT_TIMEOUT, CONFIG_VALIDATION_TIMEOUT, } from './constants/timeout.constants.js';
|
|
42
|
+
export * from './errors/index.js';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAGpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,cAAc,uBAAuB,CAAC;AACtC,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,cAAc,mCAAmC,CAAC;AAGlD,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACpE,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACxE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,KAAK,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AACnI,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAGzG,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAGxE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAGlG,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AACpF,YAAY,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAC1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAGrG,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/G,cAAc,sCAAsC,CAAC;AACrD,OAAO,EACN,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,GACzB,MAAM,kCAAkC,CAAC;AAG1C,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Filters
|
|
2
|
+
export { GlobalExceptionFilter } from './filters/global-exception.filter.js';
|
|
3
|
+
export { HttpExceptionFilter } from './filters/http-exception.filter.js';
|
|
4
|
+
// Interceptors
|
|
5
|
+
export { LoggingInterceptor } from './interceptors/logging.interceptor.js';
|
|
6
|
+
export { HTTPMetricsInterceptor } from './interceptors/http-metrics.interceptor.js';
|
|
7
|
+
// Pipes
|
|
8
|
+
export { BaseValidationPipe } from './pipes/base-validation.pipe.js';
|
|
9
|
+
export { ValidationPipe } from './pipes/validation.pipe.js';
|
|
10
|
+
// Decorators
|
|
11
|
+
export * from './decorators/index.js';
|
|
12
|
+
export * from './decorators/metric.decorators.js';
|
|
13
|
+
export { LogLevel, LOG_LEVEL_STRINGS } from './interfaces/index.js';
|
|
14
|
+
export { CACHE_PROVIDER } from './interfaces/index.js';
|
|
15
|
+
// Services
|
|
16
|
+
export { AppLogger } from './services/logger.service.js';
|
|
17
|
+
export { NestLoggerAdapter } from './services/nest-logger-adapter.service.js';
|
|
18
|
+
export { AuditLoggerService } from './services/audit-logger.service.js';
|
|
19
|
+
export { ErrorSanitizerService, ERROR_SANITIZER_OPTIONS } from './services/error-sanitizer.service.js';
|
|
20
|
+
export { ErrorCategorizerService } from './services/error-categorizer.service.js';
|
|
21
|
+
export { HttpClientService } from './services/http-client.service.js';
|
|
22
|
+
export { CSRFService } from './services/csrf.service.js';
|
|
23
|
+
export { MetricsRegistryService } from './services/metrics-registry.service.js';
|
|
24
|
+
export { HealthCheckService, HealthStatus } from './services/health-check.service.js';
|
|
25
|
+
// Metrics
|
|
26
|
+
export { BaseMetricsCollector } from './metrics/index.js';
|
|
27
|
+
// Controllers
|
|
28
|
+
export { MetricsController } from './controllers/metrics.controller.js';
|
|
29
|
+
// Guards
|
|
30
|
+
export { CSRFGuard } from './guards/csrf.guard.js';
|
|
31
|
+
export { MetricsGuard } from './guards/metrics.guard.js';
|
|
32
|
+
// Modules
|
|
33
|
+
export { CommonModule } from './common.module.js';
|
|
34
|
+
export { MetricsModule } from './metrics.module.js';
|
|
35
|
+
export { SharedThrottlerModule } from './modules/throttler.module.js';
|
|
36
|
+
// Factories
|
|
37
|
+
export * from './factories/module-factory.js';
|
|
38
|
+
export { ApplySecurityMiddleware } from './factories/security-bootstrap.factory.js';
|
|
39
|
+
export { CreateRateLimitConfig } from './factories/rate-limit-config.factory.js';
|
|
40
|
+
// Utils - Lazy Module Ref Pattern
|
|
41
|
+
export * from './utils/lazy-getter.types.js';
|
|
42
|
+
export { escapeNewlines, sanitizeObject, sanitizeXss, MAX_SANITIZE_DEPTH } from './utils/sanitization.utils.js';
|
|
43
|
+
export { getErrorStack, getErrorMessage } from './utils/error.utils.js';
|
|
44
|
+
export { createAsyncOptionsProvider, createAsyncProviders } from './utils/module.utils.js';
|
|
45
|
+
// Constants
|
|
46
|
+
export * from './constants/http-status.constants.js';
|
|
47
|
+
export { GRAFANA_TIMEOUT, LOKI_TIMEOUT, PROMETHEUS_TIMEOUT, HTTP_CLIENT_TIMEOUT, CONFIG_VALIDATION_TIMEOUT, } from './constants/timeout.constants.js';
|
|
48
|
+
// Errors
|
|
49
|
+
export * from './errors/index.js';
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE,eAAe;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAEpF,QAAQ;AACR,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,cAAc,mCAAmC,CAAC;AAIlD,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGpE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,WAAW;AACX,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAA8B,MAAM,uCAAuC,CAAC;AACnI,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAqB,MAAM,oCAAoC,CAAC;AAEzG,UAAU;AACV,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,cAAc;AACd,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAExE,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,UAAU;AACV,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAA8B,MAAM,+BAA+B,CAAC;AAElG,YAAY;AACZ,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAGjF,kCAAkC;AAClC,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAsB,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/G,YAAY;AACZ,cAAc,sCAAsC,CAAC;AACrD,OAAO,EACN,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,GACzB,MAAM,kCAAkC,CAAC;AAE1C,SAAS;AACT,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { AppLogger } from '../services/logger.service.js';
|
|
4
|
+
export declare class HttpClientInterceptor implements NestInterceptor {
|
|
5
|
+
private readonly contextualLogger;
|
|
6
|
+
private readonly logger;
|
|
7
|
+
constructor(logger: AppLogger);
|
|
8
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
9
|
+
private sanitizeHeaders;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=http-client.interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.interceptor.d.ts","sourceRoot":"","sources":["../../../src/common/interceptors/http-client.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAE1D,qBACa,qBAAsB,YAAW,eAAe;IAC5D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAY;IAE7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;gBAEvB,MAAM,EAAE,SAAS;IAKtB,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC;IAsC/E,OAAO,CAAC,eAAe;CAYvB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var HttpClientInterceptor_1;
|
|
11
|
+
import { Injectable } from '@nestjs/common';
|
|
12
|
+
import { tap, catchError } from 'rxjs/operators';
|
|
13
|
+
import { AppLogger } from '../services/logger.service.js';
|
|
14
|
+
let HttpClientInterceptor = HttpClientInterceptor_1 = class HttpClientInterceptor {
|
|
15
|
+
contextualLogger;
|
|
16
|
+
logger;
|
|
17
|
+
constructor(logger) {
|
|
18
|
+
this.logger = logger;
|
|
19
|
+
this.contextualLogger = this.logger.createContextualLogger(HttpClientInterceptor_1.name);
|
|
20
|
+
}
|
|
21
|
+
intercept(context, next) {
|
|
22
|
+
const request = context.switchToHttp().getRequest();
|
|
23
|
+
const startTime = Date.now();
|
|
24
|
+
// Log outgoing request
|
|
25
|
+
this.contextualLogger.debug('HTTP request', JSON.stringify({
|
|
26
|
+
method: request.method,
|
|
27
|
+
url: request.url,
|
|
28
|
+
headers: this.sanitizeHeaders(request.headers),
|
|
29
|
+
correlationId: request.correlationId ?? 'unknown',
|
|
30
|
+
}));
|
|
31
|
+
return next.handle().pipe(tap((response) => {
|
|
32
|
+
const duration = Date.now() - startTime;
|
|
33
|
+
this.contextualLogger.info('HTTP response', JSON.stringify({
|
|
34
|
+
method: request.method,
|
|
35
|
+
url: request.url,
|
|
36
|
+
statusCode: response.statusCode ?? response.status,
|
|
37
|
+
durationMs: duration,
|
|
38
|
+
correlationId: request.correlationId ?? 'unknown',
|
|
39
|
+
}));
|
|
40
|
+
}), catchError((error) => {
|
|
41
|
+
const duration = Date.now() - startTime;
|
|
42
|
+
this.contextualLogger.error('HTTP request failed', JSON.stringify({
|
|
43
|
+
method: request.method,
|
|
44
|
+
url: request.url,
|
|
45
|
+
statusCode: error.status ?? error.response?.status,
|
|
46
|
+
error: error.message,
|
|
47
|
+
durationMs: duration,
|
|
48
|
+
correlationId: request.correlationId ?? 'unknown',
|
|
49
|
+
}));
|
|
50
|
+
throw error;
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
sanitizeHeaders(headers) {
|
|
54
|
+
const sanitized = { ...headers };
|
|
55
|
+
const sensitiveHeaders = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];
|
|
56
|
+
for (const header of sensitiveHeaders) {
|
|
57
|
+
if (sanitized[header]) {
|
|
58
|
+
sanitized[header] = '[REDACTED]';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return sanitized;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
HttpClientInterceptor = HttpClientInterceptor_1 = __decorate([
|
|
65
|
+
Injectable(),
|
|
66
|
+
__metadata("design:paramtypes", [AppLogger])
|
|
67
|
+
], HttpClientInterceptor);
|
|
68
|
+
export { HttpClientInterceptor };
|
|
69
|
+
//# sourceMappingURL=http-client.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.interceptor.js","sourceRoot":"","sources":["../../../src/common/interceptors/http-client.interceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
|
|
5
|
+
/**
|
|
6
|
+
* HTTP Instrumentation Interceptor
|
|
7
|
+
*
|
|
8
|
+
* Backend-agnostic HTTP request metrics collection using InstrumentationRegistry.
|
|
9
|
+
* Records request duration, status code, and request size for all HTTP requests.
|
|
10
|
+
* Skips metrics collection for non-HTTP contexts (GraphQL, WebSocket, RPC, etc.).
|
|
11
|
+
*
|
|
12
|
+
* Metrics recorded:
|
|
13
|
+
* - `http_request_duration_seconds` — Request duration in seconds (histogram)
|
|
14
|
+
* - `http_requests_total` — Total HTTP requests (counter)
|
|
15
|
+
* - `http_request_size_bytes` — Request body size in bytes (histogram, when available)
|
|
16
|
+
*
|
|
17
|
+
* @injectable
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Register in your module
|
|
22
|
+
* @Module({
|
|
23
|
+
* providers: [HTTPInstrumentationInterceptor],
|
|
24
|
+
* })
|
|
25
|
+
* export class MyModule {}
|
|
26
|
+
*
|
|
27
|
+
* // Apply globally in main.ts
|
|
28
|
+
* app.useGlobalInterceptors(app.get(HTTPInstrumentationInterceptor));
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class HTTPInstrumentationInterceptor implements NestInterceptor, LazyModuleRefService {
|
|
32
|
+
readonly Module: ModuleRef;
|
|
33
|
+
constructor(module: ModuleRef);
|
|
34
|
+
private get Registry();
|
|
35
|
+
/**
|
|
36
|
+
* Intercept HTTP requests and record instrumentation metrics.
|
|
37
|
+
* Records request duration, status code, and content length.
|
|
38
|
+
* Skips metrics collection for non-HTTP contexts.
|
|
39
|
+
*
|
|
40
|
+
* @param context - The execution context containing request/response
|
|
41
|
+
* @param next - The next handler in the chain
|
|
42
|
+
* @returns Observable of the response
|
|
43
|
+
*/
|
|
44
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
45
|
+
/**
|
|
46
|
+
* Extract route path from request
|
|
47
|
+
* Tries to get the route from Express first, then falls back to URL path
|
|
48
|
+
*
|
|
49
|
+
* @private
|
|
50
|
+
* @param request - The Express request object
|
|
51
|
+
* @returns The route path or fallback value
|
|
52
|
+
*/
|
|
53
|
+
private getRoute;
|
|
54
|
+
/**
|
|
55
|
+
* Get request content length from headers
|
|
56
|
+
* Parses the content-length header and returns it as a number
|
|
57
|
+
*
|
|
58
|
+
* @private
|
|
59
|
+
* @param request - The Express request object
|
|
60
|
+
* @returns The content length in bytes, or undefined if not available
|
|
61
|
+
*/
|
|
62
|
+
private getContentLength;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=http-instrumentation.interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-instrumentation.interceptor.d.ts","sourceRoot":"","sources":["../../../src/common/interceptors/http-instrumentation.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,eAAe,EACf,gBAAgB,EAChB,WAAW,EAEX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAc,MAAM,MAAM,CAAC;AAK9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBACa,8BAA+B,YAAW,eAAe,EAAE,oBAAoB;IAC3F,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,QAAQ,GAEnB;IAED;;;;;;;;OAQG;IACI,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;IA2DnF;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ;IAWhB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;CAQxB"}
|