@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.
Files changed (286) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +802 -0
  3. package/build/LICENSE +21 -0
  4. package/build/README.md +802 -0
  5. package/build/common/common.module.d.ts +49 -0
  6. package/build/common/common.module.d.ts.map +1 -0
  7. package/build/common/common.module.js +178 -0
  8. package/build/common/common.module.js.map +1 -0
  9. package/build/common/constants/histogram-buckets.constants.d.ts +12 -0
  10. package/build/common/constants/histogram-buckets.constants.d.ts.map +1 -0
  11. package/build/common/constants/histogram-buckets.constants.js +51 -0
  12. package/build/common/constants/histogram-buckets.constants.js.map +1 -0
  13. package/build/common/constants/http-status.constants.d.ts +27 -0
  14. package/build/common/constants/http-status.constants.d.ts.map +1 -0
  15. package/build/common/constants/http-status.constants.js +27 -0
  16. package/build/common/constants/http-status.constants.js.map +1 -0
  17. package/build/common/constants/timeout.constants.d.ts +29 -0
  18. package/build/common/constants/timeout.constants.d.ts.map +1 -0
  19. package/build/common/constants/timeout.constants.js +45 -0
  20. package/build/common/constants/timeout.constants.js.map +1 -0
  21. package/build/common/controllers/metrics.controller.d.ts +23 -0
  22. package/build/common/controllers/metrics.controller.d.ts.map +1 -0
  23. package/build/common/controllers/metrics.controller.js +66 -0
  24. package/build/common/controllers/metrics.controller.js.map +1 -0
  25. package/build/common/decorators/common-decorators.d.ts +90 -0
  26. package/build/common/decorators/common-decorators.d.ts.map +1 -0
  27. package/build/common/decorators/common-decorators.js +101 -0
  28. package/build/common/decorators/common-decorators.js.map +1 -0
  29. package/build/common/decorators/decorator-factory.d.ts +108 -0
  30. package/build/common/decorators/decorator-factory.d.ts.map +1 -0
  31. package/build/common/decorators/decorator-factory.js +104 -0
  32. package/build/common/decorators/decorator-factory.js.map +1 -0
  33. package/build/common/decorators/guard.decorators.d.ts +48 -0
  34. package/build/common/decorators/guard.decorators.d.ts.map +1 -0
  35. package/build/common/decorators/guard.decorators.js +49 -0
  36. package/build/common/decorators/guard.decorators.js.map +1 -0
  37. package/build/common/decorators/index.d.ts +10 -0
  38. package/build/common/decorators/index.d.ts.map +1 -0
  39. package/build/common/decorators/index.js +11 -0
  40. package/build/common/decorators/index.js.map +1 -0
  41. package/build/common/decorators/instrument.decorator.d.ts +128 -0
  42. package/build/common/decorators/instrument.decorator.d.ts.map +1 -0
  43. package/build/common/decorators/instrument.decorator.js +165 -0
  44. package/build/common/decorators/instrument.decorator.js.map +1 -0
  45. package/build/common/decorators/metric.decorators.d.ts +42 -0
  46. package/build/common/decorators/metric.decorators.d.ts.map +1 -0
  47. package/build/common/decorators/metric.decorators.js +85 -0
  48. package/build/common/decorators/metric.decorators.js.map +1 -0
  49. package/build/common/decorators/request-property.decorator.d.ts +65 -0
  50. package/build/common/decorators/request-property.decorator.d.ts.map +1 -0
  51. package/build/common/decorators/request-property.decorator.js +102 -0
  52. package/build/common/decorators/request-property.decorator.js.map +1 -0
  53. package/build/common/errors/base-application-error.d.ts +98 -0
  54. package/build/common/errors/base-application-error.d.ts.map +1 -0
  55. package/build/common/errors/base-application-error.js +133 -0
  56. package/build/common/errors/base-application-error.js.map +1 -0
  57. package/build/common/errors/error-factory.d.ts +93 -0
  58. package/build/common/errors/error-factory.d.ts.map +1 -0
  59. package/build/common/errors/error-factory.js +105 -0
  60. package/build/common/errors/error-factory.js.map +1 -0
  61. package/build/common/errors/index.d.ts +13 -0
  62. package/build/common/errors/index.d.ts.map +1 -0
  63. package/build/common/errors/index.js +15 -0
  64. package/build/common/errors/index.js.map +1 -0
  65. package/build/common/factories/index.d.ts +5 -0
  66. package/build/common/factories/index.d.ts.map +1 -0
  67. package/build/common/factories/index.js +3 -0
  68. package/build/common/factories/index.js.map +1 -0
  69. package/build/common/factories/module-factory.d.ts +178 -0
  70. package/build/common/factories/module-factory.d.ts.map +1 -0
  71. package/build/common/factories/module-factory.js +253 -0
  72. package/build/common/factories/module-factory.js.map +1 -0
  73. package/build/common/factories/rate-limit-config.factory.d.ts +79 -0
  74. package/build/common/factories/rate-limit-config.factory.d.ts.map +1 -0
  75. package/build/common/factories/rate-limit-config.factory.js +115 -0
  76. package/build/common/factories/rate-limit-config.factory.js.map +1 -0
  77. package/build/common/factories/security-bootstrap.factory.d.ts +77 -0
  78. package/build/common/factories/security-bootstrap.factory.d.ts.map +1 -0
  79. package/build/common/factories/security-bootstrap.factory.js +222 -0
  80. package/build/common/factories/security-bootstrap.factory.js.map +1 -0
  81. package/build/common/filters/global-exception.filter.d.ts +78 -0
  82. package/build/common/filters/global-exception.filter.d.ts.map +1 -0
  83. package/build/common/filters/global-exception.filter.js +192 -0
  84. package/build/common/filters/global-exception.filter.js.map +1 -0
  85. package/build/common/filters/http-exception.filter.d.ts +37 -0
  86. package/build/common/filters/http-exception.filter.d.ts.map +1 -0
  87. package/build/common/filters/http-exception.filter.js +91 -0
  88. package/build/common/filters/http-exception.filter.js.map +1 -0
  89. package/build/common/guards/csrf.guard.d.ts +53 -0
  90. package/build/common/guards/csrf.guard.d.ts.map +1 -0
  91. package/build/common/guards/csrf.guard.js +109 -0
  92. package/build/common/guards/csrf.guard.js.map +1 -0
  93. package/build/common/guards/metrics.guard.d.ts +42 -0
  94. package/build/common/guards/metrics.guard.d.ts.map +1 -0
  95. package/build/common/guards/metrics.guard.js +124 -0
  96. package/build/common/guards/metrics.guard.js.map +1 -0
  97. package/build/common/index.d.ts +43 -0
  98. package/build/common/index.d.ts.map +1 -0
  99. package/build/common/index.js +50 -0
  100. package/build/common/index.js.map +1 -0
  101. package/build/common/interceptors/http-client.interceptor.d.ts +11 -0
  102. package/build/common/interceptors/http-client.interceptor.d.ts.map +1 -0
  103. package/build/common/interceptors/http-client.interceptor.js +69 -0
  104. package/build/common/interceptors/http-client.interceptor.js.map +1 -0
  105. package/build/common/interceptors/http-instrumentation.interceptor.d.ts +64 -0
  106. package/build/common/interceptors/http-instrumentation.interceptor.d.ts.map +1 -0
  107. package/build/common/interceptors/http-instrumentation.interceptor.js +148 -0
  108. package/build/common/interceptors/http-instrumentation.interceptor.js.map +1 -0
  109. package/build/common/interceptors/http-metrics.interceptor.d.ts +46 -0
  110. package/build/common/interceptors/http-metrics.interceptor.d.ts.map +1 -0
  111. package/build/common/interceptors/http-metrics.interceptor.js +120 -0
  112. package/build/common/interceptors/http-metrics.interceptor.js.map +1 -0
  113. package/build/common/interceptors/logging.interceptor.d.ts +22 -0
  114. package/build/common/interceptors/logging.interceptor.d.ts.map +1 -0
  115. package/build/common/interceptors/logging.interceptor.js +67 -0
  116. package/build/common/interceptors/logging.interceptor.js.map +1 -0
  117. package/build/common/interfaces/cache-provider.interface.d.ts +54 -0
  118. package/build/common/interfaces/cache-provider.interface.d.ts.map +1 -0
  119. package/build/common/interfaces/cache-provider.interface.js +6 -0
  120. package/build/common/interfaces/cache-provider.interface.js.map +1 -0
  121. package/build/common/interfaces/index.d.ts +7 -0
  122. package/build/common/interfaces/index.d.ts.map +1 -0
  123. package/build/common/interfaces/index.js +3 -0
  124. package/build/common/interfaces/index.js.map +1 -0
  125. package/build/common/interfaces/log-context.interface.d.ts +77 -0
  126. package/build/common/interfaces/log-context.interface.d.ts.map +1 -0
  127. package/build/common/interfaces/log-context.interface.js +2 -0
  128. package/build/common/interfaces/log-context.interface.js.map +1 -0
  129. package/build/common/interfaces/log-entry.interface.d.ts +26 -0
  130. package/build/common/interfaces/log-entry.interface.d.ts.map +1 -0
  131. package/build/common/interfaces/log-entry.interface.js +33 -0
  132. package/build/common/interfaces/log-entry.interface.js.map +1 -0
  133. package/build/common/interfaces/logger.interface.d.ts +62 -0
  134. package/build/common/interfaces/logger.interface.d.ts.map +1 -0
  135. package/build/common/interfaces/logger.interface.js +2 -0
  136. package/build/common/interfaces/logger.interface.js.map +1 -0
  137. package/build/common/interfaces/metrics-exporter.interface.d.ts +275 -0
  138. package/build/common/interfaces/metrics-exporter.interface.d.ts.map +1 -0
  139. package/build/common/interfaces/metrics-exporter.interface.js +8 -0
  140. package/build/common/interfaces/metrics-exporter.interface.js.map +1 -0
  141. package/build/common/metrics/base-metrics-collector.d.ts +81 -0
  142. package/build/common/metrics/base-metrics-collector.d.ts.map +1 -0
  143. package/build/common/metrics/base-metrics-collector.js +88 -0
  144. package/build/common/metrics/base-metrics-collector.js.map +1 -0
  145. package/build/common/metrics/index.d.ts +2 -0
  146. package/build/common/metrics/index.d.ts.map +1 -0
  147. package/build/common/metrics/index.js +2 -0
  148. package/build/common/metrics/index.js.map +1 -0
  149. package/build/common/metrics.module.d.ts +50 -0
  150. package/build/common/metrics.module.d.ts.map +1 -0
  151. package/build/common/metrics.module.js +77 -0
  152. package/build/common/metrics.module.js.map +1 -0
  153. package/build/common/modules/throttler.module.d.ts +69 -0
  154. package/build/common/modules/throttler.module.d.ts.map +1 -0
  155. package/build/common/modules/throttler.module.js +117 -0
  156. package/build/common/modules/throttler.module.js.map +1 -0
  157. package/build/common/pipes/base-validation.pipe.d.ts +67 -0
  158. package/build/common/pipes/base-validation.pipe.d.ts.map +1 -0
  159. package/build/common/pipes/base-validation.pipe.js +95 -0
  160. package/build/common/pipes/base-validation.pipe.js.map +1 -0
  161. package/build/common/pipes/validation.pipe.d.ts +32 -0
  162. package/build/common/pipes/validation.pipe.d.ts.map +1 -0
  163. package/build/common/pipes/validation.pipe.js +60 -0
  164. package/build/common/pipes/validation.pipe.js.map +1 -0
  165. package/build/common/registry/instrumentation-registry.d.ts +227 -0
  166. package/build/common/registry/instrumentation-registry.d.ts.map +1 -0
  167. package/build/common/registry/instrumentation-registry.js +414 -0
  168. package/build/common/registry/instrumentation-registry.js.map +1 -0
  169. package/build/common/services/audit-logger.service.d.ts +91 -0
  170. package/build/common/services/audit-logger.service.d.ts.map +1 -0
  171. package/build/common/services/audit-logger.service.js +180 -0
  172. package/build/common/services/audit-logger.service.js.map +1 -0
  173. package/build/common/services/csrf.service.d.ts +202 -0
  174. package/build/common/services/csrf.service.d.ts.map +1 -0
  175. package/build/common/services/csrf.service.js +478 -0
  176. package/build/common/services/csrf.service.js.map +1 -0
  177. package/build/common/services/error-categorizer.service.d.ts +82 -0
  178. package/build/common/services/error-categorizer.service.d.ts.map +1 -0
  179. package/build/common/services/error-categorizer.service.js +339 -0
  180. package/build/common/services/error-categorizer.service.js.map +1 -0
  181. package/build/common/services/error-sanitizer.service.d.ts +146 -0
  182. package/build/common/services/error-sanitizer.service.d.ts.map +1 -0
  183. package/build/common/services/error-sanitizer.service.js +287 -0
  184. package/build/common/services/error-sanitizer.service.js.map +1 -0
  185. package/build/common/services/health-check.service.d.ts +86 -0
  186. package/build/common/services/health-check.service.d.ts.map +1 -0
  187. package/build/common/services/health-check.service.js +132 -0
  188. package/build/common/services/health-check.service.js.map +1 -0
  189. package/build/common/services/http-client.service.d.ts +113 -0
  190. package/build/common/services/http-client.service.d.ts.map +1 -0
  191. package/build/common/services/http-client.service.js +294 -0
  192. package/build/common/services/http-client.service.js.map +1 -0
  193. package/build/common/services/logger.service.d.ts +189 -0
  194. package/build/common/services/logger.service.d.ts.map +1 -0
  195. package/build/common/services/logger.service.js +423 -0
  196. package/build/common/services/logger.service.js.map +1 -0
  197. package/build/common/services/metrics-registry.service.d.ts +98 -0
  198. package/build/common/services/metrics-registry.service.d.ts.map +1 -0
  199. package/build/common/services/metrics-registry.service.js +262 -0
  200. package/build/common/services/metrics-registry.service.js.map +1 -0
  201. package/build/common/services/nest-logger-adapter.service.d.ts +62 -0
  202. package/build/common/services/nest-logger-adapter.service.d.ts.map +1 -0
  203. package/build/common/services/nest-logger-adapter.service.js +120 -0
  204. package/build/common/services/nest-logger-adapter.service.js.map +1 -0
  205. package/build/common/utils/error.utils.d.ts +16 -0
  206. package/build/common/utils/error.utils.d.ts.map +1 -0
  207. package/build/common/utils/error.utils.js +26 -0
  208. package/build/common/utils/error.utils.js.map +1 -0
  209. package/build/common/utils/lazy-getter.types.d.ts +190 -0
  210. package/build/common/utils/lazy-getter.types.d.ts.map +1 -0
  211. package/build/common/utils/lazy-getter.types.js +114 -0
  212. package/build/common/utils/lazy-getter.types.js.map +1 -0
  213. package/build/common/utils/module.utils.d.ts +33 -0
  214. package/build/common/utils/module.utils.d.ts.map +1 -0
  215. package/build/common/utils/module.utils.js +48 -0
  216. package/build/common/utils/module.utils.js.map +1 -0
  217. package/build/common/utils/sanitization.utils.d.ts +69 -0
  218. package/build/common/utils/sanitization.utils.d.ts.map +1 -0
  219. package/build/common/utils/sanitization.utils.js +141 -0
  220. package/build/common/utils/sanitization.utils.js.map +1 -0
  221. package/build/config/config.module.d.ts +30 -0
  222. package/build/config/config.module.d.ts.map +1 -0
  223. package/build/config/config.module.js +49 -0
  224. package/build/config/config.module.js.map +1 -0
  225. package/build/config/config.service.d.ts +74 -0
  226. package/build/config/config.service.d.ts.map +1 -0
  227. package/build/config/config.service.js +145 -0
  228. package/build/config/config.service.js.map +1 -0
  229. package/build/config/config.types.d.ts +143 -0
  230. package/build/config/config.types.d.ts.map +1 -0
  231. package/build/config/config.types.js +2 -0
  232. package/build/config/config.types.js.map +1 -0
  233. package/build/config/decorators/config.decorators.d.ts +43 -0
  234. package/build/config/decorators/config.decorators.d.ts.map +1 -0
  235. package/build/config/decorators/config.decorators.js +68 -0
  236. package/build/config/decorators/config.decorators.js.map +1 -0
  237. package/build/config/decorators/index.d.ts +2 -0
  238. package/build/config/decorators/index.d.ts.map +1 -0
  239. package/build/config/decorators/index.js +2 -0
  240. package/build/config/decorators/index.js.map +1 -0
  241. package/build/config/index.d.ts +7 -0
  242. package/build/config/index.d.ts.map +1 -0
  243. package/build/config/index.js +9 -0
  244. package/build/config/index.js.map +1 -0
  245. package/build/config/validation.utils.d.ts +136 -0
  246. package/build/config/validation.utils.d.ts.map +1 -0
  247. package/build/config/validation.utils.js +263 -0
  248. package/build/config/validation.utils.js.map +1 -0
  249. package/build/errors/index.d.ts +9 -0
  250. package/build/errors/index.d.ts.map +1 -0
  251. package/build/errors/index.js +12 -0
  252. package/build/errors/index.js.map +1 -0
  253. package/build/guards/custom-throttle.guard.d.ts +28 -0
  254. package/build/guards/custom-throttle.guard.d.ts.map +1 -0
  255. package/build/guards/custom-throttle.guard.js +52 -0
  256. package/build/guards/custom-throttle.guard.js.map +1 -0
  257. package/build/guards/index.d.ts +2 -0
  258. package/build/guards/index.d.ts.map +1 -0
  259. package/build/guards/index.js +2 -0
  260. package/build/guards/index.js.map +1 -0
  261. package/build/index.d.ts +53 -0
  262. package/build/index.d.ts.map +1 -0
  263. package/build/index.js +61 -0
  264. package/build/index.js.map +1 -0
  265. package/build/logging/index.d.ts +7 -0
  266. package/build/logging/index.d.ts.map +1 -0
  267. package/build/logging/index.js +7 -0
  268. package/build/logging/index.js.map +1 -0
  269. package/build/metrics/index.d.ts +6 -0
  270. package/build/metrics/index.d.ts.map +1 -0
  271. package/build/metrics/index.js +11 -0
  272. package/build/metrics/index.js.map +1 -0
  273. package/build/package.json +72 -0
  274. package/build/security/index.d.ts +8 -0
  275. package/build/security/index.d.ts.map +1 -0
  276. package/build/security/index.js +11 -0
  277. package/build/security/index.js.map +1 -0
  278. package/build/test-setup.d.ts +2 -0
  279. package/build/test-setup.d.ts.map +1 -0
  280. package/build/test-setup.js +40 -0
  281. package/build/test-setup.js.map +1 -0
  282. package/build/validation/index.d.ts +6 -0
  283. package/build/validation/index.d.ts.map +1 -0
  284. package/build/validation/index.js +8 -0
  285. package/build/validation/index.js.map +1 -0
  286. package/package.json +71 -0
@@ -0,0 +1,91 @@
1
+ import { ModuleRef } from '@nestjs/core';
2
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
3
+ import { AppLogger } from './logger.service.js';
4
+ /**
5
+ * Audit log entry for security events.
6
+ */
7
+ export interface AuditLogEntry {
8
+ timestamp: Date;
9
+ userId?: string;
10
+ action: string;
11
+ resource: string;
12
+ result: 'success' | 'failure';
13
+ details?: Record<string, any>;
14
+ ipAddress?: string;
15
+ userAgent?: string;
16
+ }
17
+ /**
18
+ * Audit Logger Service.
19
+ * Specialized logging for security-related events: authentication, authorization, token operations,
20
+ * CSRF violations, rate limiting, and configuration changes.
21
+ *
22
+ * All audit events are logged at INFO level (or WARN for failures) with structured JSON data
23
+ * for easy parsing by log aggregation systems (Loki, Splunk, etc.).
24
+ *
25
+ * @remarks
26
+ * - Automatically redacts sensitive fields (passwords, tokens) via AppLogger
27
+ * - All events include ISO timestamps and structured event data
28
+ * - Integrates with log aggregation for compliance and forensics
29
+ * - Available globally via CommonModule
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Log authentication attempt
34
+ * auditLogger.logAuthenticationAttempt('user@example.com', true, '192.168.1.1');
35
+ *
36
+ * // Log CSRF violation
37
+ * auditLogger.logCsrfViolation('192.168.1.1', '/api/users');
38
+ *
39
+ * // Log custom security event
40
+ * auditLogger.logSecurityEvent({
41
+ * userId: 'user-123',
42
+ * action: 'delete_user',
43
+ * resource: 'users/456',
44
+ * result: 'failure',
45
+ * ipAddress: '192.168.1.1'
46
+ * });
47
+ * ```
48
+ */
49
+ export declare class AuditLoggerService implements LazyModuleRefService {
50
+ private _contextualLogger;
51
+ readonly Module: ModuleRef;
52
+ constructor(module: ModuleRef);
53
+ get Logger(): AppLogger;
54
+ /**
55
+ * Log authentication attempt
56
+ */
57
+ logAuthenticationAttempt(email: string, success: boolean, ipAddress?: string, reason?: string): void;
58
+ /**
59
+ * Log authorization failure
60
+ */
61
+ logAuthorizationFailure(userId: string, resource: string, action: string, ipAddress?: string): void;
62
+ /**
63
+ * Log token generation
64
+ */
65
+ logTokenGeneration(userId: string, tokenType: 'access' | 'refresh'): void;
66
+ /**
67
+ * Log token revocation
68
+ */
69
+ logTokenRevocation(userId: string, reason: string): void;
70
+ /**
71
+ * Log rate limit violation
72
+ */
73
+ logRateLimitViolation(endpoint: string, ipAddress: string, limit: number): void;
74
+ /**
75
+ * Log CSRF violation
76
+ */
77
+ logCsrfViolation(ipAddress: string, endpoint: string): void;
78
+ /**
79
+ * Log security configuration change
80
+ */
81
+ logConfigurationChange(userId: string, config: string, oldValue: any, newValue: any): void;
82
+ /**
83
+ * Log data access
84
+ */
85
+ logDataAccess(userId: string, resource: string, action: string): void;
86
+ /**
87
+ * Log security event
88
+ */
89
+ logSecurityEvent(entry: AuditLogEntry): void;
90
+ }
91
+ //# sourceMappingURL=audit-logger.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.service.d.ts","sourceRoot":"","sources":["../../../src/common/services/audit-logger.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBACa,kBAAmB,YAAW,oBAAoB;IAC9D,OAAO,CAAC,iBAAiB,CAAwB;IAEjD,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,IAAW,MAAM,IAAI,SAAS,CAM7B;IAED;;OAEG;IACI,wBAAwB,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,MAAM,GACb,IAAI;IAeP;;OAEG;IACI,uBAAuB,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GAChB,IAAI;IAeP;;OAEG;IACI,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI;IAahF;;OAEG;IACI,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAa/D;;OAEG;IACI,qBAAqB,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACX,IAAI;IAcP;;OAEG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAalE;;OAEG;IACI,sBAAsB,CAC5B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,GAAG,GACX,IAAI;IAeP;;OAEG;IACI,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAc5E;;OAEG;IACI,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;CAUnD"}
@@ -0,0 +1,180 @@
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 AuditLoggerService_1;
11
+ import { Injectable } from '@nestjs/common';
12
+ import { ModuleRef } from '@nestjs/core';
13
+ import { AppLogger } from './logger.service.js';
14
+ import { escapeNewlines } from '../utils/sanitization.utils.js';
15
+ /**
16
+ * Audit Logger Service.
17
+ * Specialized logging for security-related events: authentication, authorization, token operations,
18
+ * CSRF violations, rate limiting, and configuration changes.
19
+ *
20
+ * All audit events are logged at INFO level (or WARN for failures) with structured JSON data
21
+ * for easy parsing by log aggregation systems (Loki, Splunk, etc.).
22
+ *
23
+ * @remarks
24
+ * - Automatically redacts sensitive fields (passwords, tokens) via AppLogger
25
+ * - All events include ISO timestamps and structured event data
26
+ * - Integrates with log aggregation for compliance and forensics
27
+ * - Available globally via CommonModule
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Log authentication attempt
32
+ * auditLogger.logAuthenticationAttempt('user@example.com', true, '192.168.1.1');
33
+ *
34
+ * // Log CSRF violation
35
+ * auditLogger.logCsrfViolation('192.168.1.1', '/api/users');
36
+ *
37
+ * // Log custom security event
38
+ * auditLogger.logSecurityEvent({
39
+ * userId: 'user-123',
40
+ * action: 'delete_user',
41
+ * resource: 'users/456',
42
+ * result: 'failure',
43
+ * ipAddress: '192.168.1.1'
44
+ * });
45
+ * ```
46
+ */
47
+ let AuditLoggerService = AuditLoggerService_1 = class AuditLoggerService {
48
+ _contextualLogger;
49
+ Module;
50
+ constructor(module) {
51
+ this.Module = module;
52
+ }
53
+ get Logger() {
54
+ if (!this._contextualLogger) {
55
+ const baseLogger = this.Module.get(AppLogger);
56
+ this._contextualLogger = baseLogger.createContextualLogger(AuditLoggerService_1.name);
57
+ }
58
+ return this._contextualLogger;
59
+ }
60
+ /**
61
+ * Log authentication attempt
62
+ */
63
+ logAuthenticationAttempt(email, success, ipAddress, reason) {
64
+ const auditData = {
65
+ event: 'authentication',
66
+ email,
67
+ success,
68
+ ipAddress,
69
+ reason,
70
+ timestamp: new Date().toISOString(),
71
+ };
72
+ this.Logger.info(`Authentication ${success ? 'SUCCESS' : 'FAILURE'}: ${escapeNewlines(email)}${reason ? ` - ${escapeNewlines(reason)}` : ''} | ${JSON.stringify(auditData)}`, 'AuditLogger');
73
+ }
74
+ /**
75
+ * Log authorization failure
76
+ */
77
+ logAuthorizationFailure(userId, resource, action, ipAddress) {
78
+ const auditData = {
79
+ event: 'authorization_failure',
80
+ userId,
81
+ resource,
82
+ action,
83
+ ipAddress,
84
+ timestamp: new Date().toISOString(),
85
+ };
86
+ this.Logger.warn(`Authorization FAILURE: User ${escapeNewlines(userId)} attempted ${escapeNewlines(action)} on ${escapeNewlines(resource)} | ${JSON.stringify(auditData)}`, 'AuditLogger');
87
+ }
88
+ /**
89
+ * Log token generation
90
+ */
91
+ logTokenGeneration(userId, tokenType) {
92
+ const auditData = {
93
+ event: 'token_generation',
94
+ userId,
95
+ tokenType,
96
+ timestamp: new Date().toISOString(),
97
+ };
98
+ this.Logger.info(`Token GENERATED: ${tokenType} token for user ${escapeNewlines(userId)} | ${JSON.stringify(auditData)}`, 'AuditLogger');
99
+ }
100
+ /**
101
+ * Log token revocation
102
+ */
103
+ logTokenRevocation(userId, reason) {
104
+ const auditData = {
105
+ event: 'token_revocation',
106
+ userId,
107
+ reason,
108
+ timestamp: new Date().toISOString(),
109
+ };
110
+ this.Logger.info(`Token REVOCATION: User ${escapeNewlines(userId)} - ${escapeNewlines(reason)} | ${JSON.stringify(auditData)}`, 'AuditLogger');
111
+ }
112
+ /**
113
+ * Log rate limit violation
114
+ */
115
+ logRateLimitViolation(endpoint, ipAddress, limit) {
116
+ const auditData = {
117
+ event: 'rate_limit_violation',
118
+ endpoint,
119
+ ipAddress,
120
+ limit,
121
+ timestamp: new Date().toISOString(),
122
+ };
123
+ this.Logger.warn(`Rate LIMIT VIOLATION: ${escapeNewlines(endpoint)} from ${escapeNewlines(ipAddress)} (limit: ${limit}/min) | ${JSON.stringify(auditData)}`, 'AuditLogger');
124
+ }
125
+ /**
126
+ * Log CSRF violation
127
+ */
128
+ logCsrfViolation(ipAddress, endpoint) {
129
+ const auditData = {
130
+ event: 'csrf_violation',
131
+ ipAddress,
132
+ endpoint,
133
+ timestamp: new Date().toISOString(),
134
+ };
135
+ this.Logger.warn(`CSRF VIOLATION: ${escapeNewlines(endpoint)} from ${escapeNewlines(ipAddress)} | ${JSON.stringify(auditData)}`, 'AuditLogger');
136
+ }
137
+ /**
138
+ * Log security configuration change
139
+ */
140
+ logConfigurationChange(userId, config, oldValue, newValue) {
141
+ const auditData = {
142
+ event: 'config_change',
143
+ userId,
144
+ config,
145
+ oldValue,
146
+ newValue,
147
+ timestamp: new Date().toISOString(),
148
+ };
149
+ this.Logger.info(`Configuration CHANGE: ${escapeNewlines(config)} modified by ${escapeNewlines(userId)} | ${JSON.stringify(auditData)}`, 'AuditLogger');
150
+ }
151
+ /**
152
+ * Log data access
153
+ */
154
+ logDataAccess(userId, resource, action) {
155
+ const auditData = {
156
+ event: 'data_access',
157
+ userId,
158
+ resource,
159
+ action,
160
+ timestamp: new Date().toISOString(),
161
+ };
162
+ this.Logger.info(`Data ACCESS: User ${escapeNewlines(userId)} ${escapeNewlines(action)} ${escapeNewlines(resource)} | ${JSON.stringify(auditData)}`, 'AuditLogger');
163
+ }
164
+ /**
165
+ * Log security event
166
+ */
167
+ logSecurityEvent(entry) {
168
+ const auditData = {
169
+ ...entry,
170
+ timestamp: new Date().toISOString(),
171
+ };
172
+ this.Logger.info(`Security EVENT: ${escapeNewlines(entry.action)} on ${escapeNewlines(entry.resource)} - ${entry.result} | ${JSON.stringify(auditData)}`, 'AuditLogger');
173
+ }
174
+ };
175
+ AuditLoggerService = AuditLoggerService_1 = __decorate([
176
+ Injectable(),
177
+ __metadata("design:paramtypes", [ModuleRef])
178
+ ], AuditLoggerService);
179
+ export { AuditLoggerService };
180
+ //# sourceMappingURL=audit-logger.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.service.js","sourceRoot":"","sources":["../../../src/common/services/audit-logger.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,202 @@
1
+ import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
2
+ import { ConfigService } from '@nestjs/config';
3
+ import { Request, Response, NextFunction } from 'express';
4
+ /**
5
+ * Configuration options for CSRF protection.
6
+ */
7
+ export interface CSRFServiceOptions {
8
+ /**
9
+ * Whether to trust X-Forwarded-For header for client IP detection.
10
+ * Set to true when running behind a reverse proxy (nginx, Apache, load balancer, etc.)
11
+ * to correctly identify the real client IP for rate limiting.
12
+ *
13
+ * Security note: Only enable if your reverse proxy is trusted and properly configured
14
+ * to set X-Forwarded-For. Enabling this on an untrusted proxy allows IP spoofing attacks.
15
+ *
16
+ * Default: false (use direct socket IP)
17
+ */
18
+ trustProxy?: boolean;
19
+ }
20
+ /**
21
+ * CSRF Service.
22
+ * Provides CSRF token generation and validation using the Double Submit Cookie pattern.
23
+ * Uses cryptographic signing and per-session/IP binding for secure token verification.
24
+ *
25
+ * Features:
26
+ * - Double-CSRF token pattern (cookie + request header/body)
27
+ * - Per-IP rate limiting: 10 tokens per 60 seconds
28
+ * - Session binding (when available) or IP-based fallback
29
+ * - Automatic pruning of stale timestamps
30
+ * - Capacity monitoring with safety margin (80% threshold)
31
+ * - SSL-only, HTTPOnly cookies in production
32
+ *
33
+ * Configuration requirements:
34
+ * - CSRF_SECRET: Min 32 characters, cryptographically random, high entropy
35
+ * - Express app with cookie parser middleware
36
+ * - Optional: trustProxy for reverse proxy environments
37
+ *
38
+ * @remarks
39
+ * - In-memory rate limiting supports ~10,000 concurrent IPs per instance
40
+ * - For distributed deployments, use Redis-backed SharedThrottlerModule instead
41
+ * - Token generation timeout: 30 seconds (queue timeout)
42
+ * - Token timestamp pruning interval: 10 seconds
43
+ * - IP map capacity threshold: 80% (8,000 IPs) before pruning
44
+ * - Returns 503 Service Unavailable if at capacity after pruning
45
+ * - Returns 429 Too Many Requests if rate limit exceeded
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Generate token for form
50
+ * const token = await csrfService.generateToken(req, res);
51
+ * res.render('form', { csrfToken: token });
52
+ *
53
+ * // Validate incoming request (done automatically by CSRFGuard)
54
+ * const isValid = csrfService.validateToken(req);
55
+ *
56
+ * // Refresh token after sensitive operation (login, password change)
57
+ * const newToken = await csrfService.refreshToken(req, res);
58
+ * ```
59
+ */
60
+ export declare class CSRFService implements OnModuleInit, OnModuleDestroy {
61
+ private readonly configService?;
62
+ private static readonly MIN_SECRET_LENGTH;
63
+ private static readonly MIN_CHARACTER_SET_DIVERSITY;
64
+ private static readonly ANONYMOUS_TOKEN_RANDOMNESS_BYTES;
65
+ private static readonly RATE_LIMIT_WINDOW_MS;
66
+ private static readonly RATE_LIMIT_COUNT;
67
+ /**
68
+ * Maximum number of unique IP addresses tracked for rate limiting.
69
+ * This in-memory strategy supports ~10,000 concurrent IPs per instance.
70
+ *
71
+ * **Scaling guidance**: For deployments exceeding 10,000 concurrent unique IPs,
72
+ * migrate to a Redis-backed rate limiting solution via SharedThrottlerModule:
73
+ * - Configure SharedThrottlerModule with Redis backend
74
+ * - Adjust limits and TTL for your traffic pattern
75
+ *
76
+ * **Memory management**: When the tracked IPs map reaches 80% capacity
77
+ * (8,000 IPs), the pruning logic removes stale entries (>60s old).
78
+ * If after pruning the map remains >= 10,000 IPs, token generation is
79
+ * rejected with HTTP 503 to prevent unbounded memory growth.
80
+ * The 80% threshold provides a safety margin before hard limits are hit.
81
+ *
82
+ * @see SharedThrottlerModule for Redis-backed distributed rate limiting
83
+ */
84
+ private static readonly MAX_TRACKED_IPS;
85
+ private static readonly TIMESTAMP_PRUNING_INTERVAL_MS;
86
+ private static readonly IP_LOCK_TIMEOUT_MS;
87
+ private static readonly CAPACITY_THRESHOLD_PERCENT;
88
+ private csrfProtection;
89
+ private readonly logger;
90
+ private readonly tokenGenTimestamps;
91
+ private readonly ipLocks;
92
+ private readonly trustProxy;
93
+ private capacityThresholdCrossedCount;
94
+ private pruneIntervalHandle;
95
+ private _isPruning;
96
+ constructor(configService?: ConfigService | undefined, options?: CSRFServiceOptions);
97
+ /**
98
+ * NestJS lifecycle hook: validate required CSRF_SECRET environment variable
99
+ * at application bootstrap time
100
+ */
101
+ onModuleInit(): void;
102
+ /**
103
+ * NestJS lifecycle hook: clear the pruning interval on module destroy
104
+ */
105
+ onModuleDestroy(): void;
106
+ /**
107
+ * Validate trust proxy configuration to detect mismatches early
108
+ * Checks if X-Forwarded-For header support is configured correctly in both directions:
109
+ * - If trustProxy=false but X-Forwarded-For is present: may miss real client IP
110
+ * - If trustProxy=true but X-Forwarded-For is absent: proxy may not be configured correctly
111
+ */
112
+ private validateTrustProxyConfiguration;
113
+ /**
114
+ * Calculate Shannon entropy of a string to measure randomness.
115
+ * Higher entropy indicates better randomness quality.
116
+ *
117
+ * The minimum threshold of 4.0 bits/char is chosen because:
118
+ * - A uniformly random string from a 16-character alphabet (hex: 0-9a-f) has log2(16) = 4.0 bits/char
119
+ * - This ensures the CSRF_SECRET has sufficient entropy for cryptographic purposes
120
+ * - Values below 4.0 bits/char indicate the secret uses a limited character set or has patterns
121
+ *
122
+ * @param str - Input string to analyze
123
+ * @returns Entropy in bits per character
124
+ */
125
+ private calculateEntropy;
126
+ /**
127
+ * Check if the secret contains obviously weak patterns
128
+ */
129
+ private isWeakSecret;
130
+ /**
131
+ * Get session identifier for CSRF token binding
132
+ * Prefers session ID if available, falls back to IP address
133
+ * @param req - Express request object
134
+ * @returns Session identifier
135
+ */
136
+ private getSessionIdentifier;
137
+ /**
138
+ * Extract client IP address from request, respecting trustProxy setting
139
+ *
140
+ * **Note on Express vs Fastify**: This implementation uses `req.ip` (Express-specific).
141
+ * For Fastify deployments, ensure the `trustProxy` option is properly configured:
142
+ * - In Fastify, use `app.register(require('@fastify/proxy'), { ...config })`
143
+ * - Or set the Fastify instance option: `fastify({ trustProxy: true })`
144
+ * - Without correct Fastify configuration, IP detection will fail
145
+ *
146
+ * @param req - Express request object
147
+ * @returns Client IP address or null if unavailable
148
+ */
149
+ private extractClientIp;
150
+ /**
151
+ * Prune old token generation timestamps to prevent unbounded map growth
152
+ * Removes entries older than 60 seconds and cleans up idle IPs from both
153
+ * tokenGenTimestamps and ipLocks to prevent memory accumulation.
154
+ */
155
+ private pruneTokenTimestamps;
156
+ /**
157
+ * Generate CSRF token with per-IP rate limiting
158
+ * Limits to 10 token generations per IP per 60 seconds
159
+ * Uses per-IP locking to serialize concurrent requests from the same IP,
160
+ * preventing race conditions in rate limit checks.
161
+ * @param req - Express request object
162
+ * @param res - Express response object
163
+ * @returns CSRF token
164
+ * @throws Error if CSRF_SECRET was not initialized in onModuleInit
165
+ * @throws {HttpException} 429 - When rate limit exceeded for this IP
166
+ * @throws {HttpException} 503 - When service is at capacity
167
+ */
168
+ generateToken(req: Request, res: Response): Promise<string>;
169
+ /**
170
+ * Perform rate-limited token generation for a single IP.
171
+ * This method is called within an IP-serialized lock to ensure atomicity.
172
+ * @param req - Express request object
173
+ * @param res - Express response object
174
+ * @returns CSRF token
175
+ * @throws HttpException with 429 status if rate limit exceeded
176
+ */
177
+ private performRateLimitedTokenGeneration;
178
+ /**
179
+ * Validate CSRF token
180
+ * @param req - Express request object
181
+ * @returns true if token is valid, false otherwise
182
+ * @throws Error if CSRF_SECRET was not initialized in onModuleInit
183
+ */
184
+ validateToken(req: Request): boolean;
185
+ /**
186
+ * Refresh CSRF token by invalidating the current one and generating a new one
187
+ * Use this after sensitive operations like login, password change, or privilege escalation
188
+ * to ensure the user has a fresh token that cannot be replayed from before the operation
189
+ * @param req - Express request object
190
+ * @param res - Express response object
191
+ * @returns New CSRF token
192
+ * @throws Error if CSRF_SECRET was not initialized in onModuleInit
193
+ */
194
+ refreshToken(req: Request, res: Response): Promise<string>;
195
+ /**
196
+ * Get CSRF middleware
197
+ * @returns CSRF protection middleware
198
+ * @throws Error if CSRF_SECRET was not initialized in onModuleInit
199
+ */
200
+ getMiddleware(): (req: Request, res: Response, next: NextFunction) => void;
201
+ }
202
+ //# sourceMappingURL=csrf.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.service.d.ts","sourceRoot":"","sources":["../../../src/common/services/csrf.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,eAAe,EAAuD,MAAM,gBAAgB,CAAC;AAChI,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBACa,WAAY,YAAW,YAAY,EAAE,eAAe;IAgD5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IA7CnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAM;IAE/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAK;IAExD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gCAAgC,CAAK;IAE7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAU;IAEtD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAC9C;;;;;;;;;;;;;;;;OAgBG;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEhD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,6BAA6B,CAAa;IAElE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAU;IAEpD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAO;IAEzD,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA+B;IAClE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,6BAA6B,CAAK;IAC1C,OAAO,CAAC,mBAAmB,CAA6C;IACxE,OAAO,CAAC,UAAU,CAAS;gBAG0B,aAAa,CAAC,EAAE,aAAa,YAAA,EACrE,OAAO,CAAC,EAAE,kBAAkB;IAOzC;;;OAGG;IACI,YAAY,IAAI,IAAI;IA2D3B;;OAEG;IACI,eAAe,IAAI,IAAI;IAU9B;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IAyBvC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,eAAe;IA4BvB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;;;;;;;;;;OAWG;IACU,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IA6CxE;;;;;;;OAOG;IACH,OAAO,CAAC,iCAAiC;IAiEzC;;;;;OAKG;IACI,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAa3C;;;;;;;;OAQG;IAEI,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAWjE;;;;OAIG;IACI,aAAa,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI;CAOjF"}