@pawells/nestjs-shared 1.0.0-dev.3052c75

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,222 @@
1
+ /**
2
+ * Security Bootstrap Factory
3
+ *
4
+ * Provides a comprehensive factory function for applying security middleware and
5
+ * configurations to a NestJS application. This includes compression, MongoDB injection
6
+ * prevention, XSS protection, Helmet.js security headers, CORS, and global validation pipes.
7
+ *
8
+ * All security features are enabled by default and can be selectively disabled via options.
9
+ */
10
+ import { Logger, ValidationPipe } from '@nestjs/common';
11
+ import helmet from 'helmet';
12
+ import compression from 'compression';
13
+ import express from 'express';
14
+ import { sanitizeObject, sanitizeXss } from '../utils/sanitization.utils.js';
15
+ /**
16
+ * Applies comprehensive security middleware and configurations to a NestJS application
17
+ *
18
+ * Configured middleware stack (in order):
19
+ * 0. Body Size Limits - Enforces maximum request body size
20
+ * 1. Compression - Reduces response size for APIs larger than 1KB
21
+ * 2. MongoDB Injection Prevention - Sanitizes request body and params
22
+ * 3. XSS Protection - Sanitizes user input to prevent XSS attacks
23
+ * 4. Helmet.js - Sets security-related HTTP headers (CSP, HSTS, X-Frame-Options, etc)
24
+ * 5. Global Validation Pipe - Validates and transforms incoming data
25
+ * 6. CORS - Enables cross-origin resource sharing with configurable origins
26
+ *
27
+ * @param app The NestJS application instance
28
+ * @param options Configuration options for security bootstrap
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * import { NestFactory } from '@nestjs/core';
33
+ * import { ApplySecurityMiddleware } from '@pawells/nestjs-shared';
34
+ * import { AppModule } from './app.module';
35
+ *
36
+ * async function bootstrap() {
37
+ * const app = await NestFactory.create(AppModule);
38
+ *
39
+ * ApplySecurityMiddleware(app, {
40
+ * corsOrigins: ['https://example.com'],
41
+ * environment: 'production',
42
+ * });
43
+ *
44
+ * await app.listen(3000);
45
+ * }
46
+ *
47
+ * bootstrap();
48
+ * ```
49
+ */
50
+ export function ApplySecurityMiddleware(app, options = {}) {
51
+ const { corsOrigins = [], environment = process.env['NODE_ENV'] ?? 'development', compressionEnabled = true, xssEnabled = true, helmetEnabled = true, mongoDbInjectionPreventionEnabled = true, corsEnabled = true, corsAllowedHeaders = ['Content-Type', 'Authorization', 'X-Requested-With', 'apollographql-client-name', 'apollographql-client-version', 'X-CSRF-Token'], cspConnectSrc = [], cspImgSrc = [], cspStyleSrc = [], cspFontSrc = [], maxBodySize = '10mb', logger = new Logger('SecurityBootstrap'), } = options;
52
+ // Named constants for configuration
53
+ const DEFAULT_COMPRESSION_LEVEL = 6;
54
+ const DEFAULT_COMPRESSION_THRESHOLD = 1024;
55
+ // Step 0: Apply request body size limits
56
+ app.use(express.json({ limit: maxBodySize }));
57
+ app.use(express.urlencoded({ extended: true, limit: maxBodySize }));
58
+ logger.log('Request body size limits applied');
59
+ // Step 1: Apply compression middleware
60
+ if (compressionEnabled) {
61
+ app.use(compression({
62
+ level: DEFAULT_COMPRESSION_LEVEL,
63
+ threshold: DEFAULT_COMPRESSION_THRESHOLD,
64
+ filter: (req, res) => {
65
+ // Don't compress responses with this request header
66
+ if (req.headers['x-no-compression']) {
67
+ return false;
68
+ }
69
+ // Use default compression filter function
70
+ return compression.filter(req, res);
71
+ },
72
+ }));
73
+ logger.log('Compression middleware enabled for API response optimization');
74
+ }
75
+ // Step 2: Apply MongoDB injection prevention middleware
76
+ if (mongoDbInjectionPreventionEnabled) {
77
+ app.use((req, _res, next) => {
78
+ if (req.body) {
79
+ req.body = sanitizeObject(req.body, 0, logger);
80
+ }
81
+ if (req.params) {
82
+ req.params = sanitizeObject(req.params, 0, logger);
83
+ }
84
+ if (req.cookies && typeof req.cookies === 'object') {
85
+ req.cookies = sanitizeObject(req.cookies);
86
+ }
87
+ next();
88
+ });
89
+ logger.log('MongoDB injection prevention middleware applied');
90
+ }
91
+ // Step 3: Apply XSS protection middleware
92
+ if (xssEnabled) {
93
+ app.use((req, _res, next) => {
94
+ if (req.body) {
95
+ req.body = sanitizeXss(req.body, logger);
96
+ }
97
+ if (req.query) {
98
+ req.query = sanitizeXss(req.query, logger);
99
+ }
100
+ if (req.params) {
101
+ req.params = sanitizeXss(req.params, logger);
102
+ }
103
+ next();
104
+ });
105
+ logger.log('XSS sanitization middleware applied');
106
+ }
107
+ // Step 4: Apply Helmet.js for security headers
108
+ if (helmetEnabled) {
109
+ app.use(helmet({
110
+ contentSecurityPolicy: {
111
+ directives: {
112
+ defaultSrc: [...new Set(['\'self\''])],
113
+ scriptSrc: [...new Set(['\'self\''])],
114
+ styleSrc: [...new Set(['\'self\'', ...cspStyleSrc])],
115
+ imgSrc: [...new Set(['\'self\'', ...cspImgSrc])],
116
+ connectSrc: [...new Set(['\'self\'', ...cspConnectSrc])],
117
+ fontSrc: [...new Set(['\'self\'', ...cspFontSrc])],
118
+ baseUri: [...new Set(['\'self\''])],
119
+ objectSrc: [...new Set(['\'none\''])],
120
+ mediaSrc: [...new Set(['\'self\''])],
121
+ frameSrc: [...new Set(['\'none\''])],
122
+ },
123
+ },
124
+ hsts: {
125
+ maxAge: 31536000, // 1 year
126
+ includeSubDomains: true,
127
+ preload: true,
128
+ },
129
+ frameguard: {
130
+ action: 'deny',
131
+ },
132
+ referrerPolicy: {
133
+ policy: 'strict-origin-when-cross-origin',
134
+ },
135
+ noSniff: true,
136
+ xssFilter: true,
137
+ dnsPrefetchControl: {
138
+ allow: false,
139
+ },
140
+ }));
141
+ logger.log('Helmet.js security headers applied');
142
+ }
143
+ // Step 5: Apply global validation pipe
144
+ app.useGlobalPipes(new ValidationPipe({
145
+ whitelist: true,
146
+ forbidNonWhitelisted: true,
147
+ transform: true,
148
+ }));
149
+ logger.log('Global ValidationPipe configured');
150
+ // Step 6: Enable CORS with smart origin validation
151
+ if (corsEnabled) {
152
+ // Apollo Studio origins that need access in development
153
+ const apolloStudioOrigins = [
154
+ 'https://studio.apollographql.com',
155
+ 'https://sandbox.apollo.dev',
156
+ ];
157
+ /**
158
+ * Smart CORS origin validation algorithm.
159
+ *
160
+ * This validator implements a layered origin checking strategy that balances
161
+ * development convenience with production security:
162
+ *
163
+ * 1. **No-origin requests**: Allows requests without an Origin header
164
+ * (typical for same-origin, curl, Postman, and other non-browser clients).
165
+ * These requests are safe and do not require CORS validation.
166
+ *
167
+ * 2. **Development localhost origins**: In development mode, permits all localhost origins
168
+ * (http://localhost:*) to enable rapid iteration without configuration.
169
+ * This includes any port number (e.g., http://localhost:3000, http://localhost:5173).
170
+ *
171
+ * 3. **Development Apollo Studio origins**: In development mode, explicitly allows
172
+ * Apollo Studio (https://studio.apollographql.com) and Apollo Sandbox (https://sandbox.apollo.dev)
173
+ * to facilitate GraphQL IDE testing without additional setup.
174
+ *
175
+ * 4. **Configured production origins**: Allows explicitly configured origins from the
176
+ * corsOrigins option. This is the primary enforcement mechanism in production.
177
+ *
178
+ * 5. **Default rejection**: Any origin not matching the above is rejected with an
179
+ * "Not allowed by CORS" error.
180
+ *
181
+ * **Security notes:**
182
+ * - Development mode origins (localhost, Apollo Studio) are disabled in production
183
+ * - Configured origins are checked case-insensitively for robustness
184
+ * - Wildcard origins (e.g., *.example.com) are not supported; specify each origin explicitly
185
+ */
186
+ app.enableCors({
187
+ origin: (origin, callback) => {
188
+ // Allow requests with no origin (same-origin, curl, Postman, etc.)
189
+ if (!origin) {
190
+ callback(null, true);
191
+ return;
192
+ }
193
+ // In development, allow all localhost origins (strict match: must be http://localhost or http://localhost:PORT)
194
+ if (environment === 'development' && /^http:\/\/localhost(?::\d+)?$/.test(origin)) {
195
+ callback(null, true);
196
+ return;
197
+ }
198
+ // In development, allow Apollo Studio origins
199
+ if (environment === 'development' && apolloStudioOrigins.includes(origin)) {
200
+ callback(null, true);
201
+ return;
202
+ }
203
+ // Check against configured allowed origins list (case-insensitive)
204
+ if (corsOrigins.some(allowed => allowed.toLowerCase() === origin.toLowerCase())) {
205
+ callback(null, true);
206
+ return;
207
+ }
208
+ // Reject unknown origins
209
+ callback(new Error('Not allowed by CORS'));
210
+ },
211
+ credentials: true,
212
+ methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
213
+ allowedHeaders: corsAllowedHeaders,
214
+ exposedHeaders: ['X-Total-Count', 'X-Page-Number'],
215
+ maxAge: 3600,
216
+ });
217
+ logger.log(corsOrigins.length > 0
218
+ ? `CORS configured for environment: ${environment}, Allowed origins: ${corsOrigins.join(', ')}`
219
+ : `CORS configured for environment: ${environment}, Using smart origin validation`);
220
+ }
221
+ }
222
+ //# sourceMappingURL=security-bootstrap.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-bootstrap.factory.js","sourceRoot":"","sources":["../../../src/common/factories/security-bootstrap.factory.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAEH,OAAO,EAAoB,MAAM,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,WAAW,MAAM,aAAa,CAAC;AACtC,OAAO,OAA4C,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAiC7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,uBAAuB,CACtC,GAAqB,EACrB,UAAoC,EAAE;IAEtC,MAAM,EACL,WAAW,GAAG,EAAE,EAChB,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,aAAa,EACtD,kBAAkB,GAAG,IAAI,EACzB,UAAU,GAAG,IAAI,EACjB,aAAa,GAAG,IAAI,EACpB,iCAAiC,GAAG,IAAI,EACxC,WAAW,GAAG,IAAI,EAClB,kBAAkB,GAAG,CAAC,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,cAAc,CAAC,EACvJ,aAAa,GAAG,EAAE,EAClB,SAAS,GAAG,EAAE,EACd,WAAW,GAAG,EAAE,EAChB,UAAU,GAAG,EAAE,EACf,WAAW,GAAG,MAAM,EACpB,MAAM,GAAG,IAAI,MAAM,CAAC,mBAAmB,CAAC,GACxC,GAAG,OAAO,CAAC;IAEZ,oCAAoC;IACpC,MAAM,yBAAyB,GAAG,CAAC,CAAC;IACpC,MAAM,6BAA6B,GAAG,IAAI,CAAC;IAE3C,yCAAyC;IACzC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IAC9C,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAE/C,uCAAuC;IACvC,IAAI,kBAAkB,EAAE,CAAC;QACxB,GAAG,CAAC,GAAG,CACN,WAAW,CAAC;YACX,KAAK,EAAE,yBAAyB;YAChC,SAAS,EAAE,6BAA6B;YACxC,MAAM,EAAE,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;gBACvC,oDAAoD;gBACpD,IAAI,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;oBACrC,OAAO,KAAK,CAAC;gBACd,CAAC;gBACD,0CAA0C;gBAC1C,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACrC,CAAC;SACD,CAAC,CACF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC5E,CAAC;IAED,wDAAwD;IACxD,IAAI,iCAAiC,EAAE,CAAC;QACvC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAY,EAAE,IAAc,EAAE,IAAkB,EAAE,EAAE;YAC5D,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;gBACd,GAAG,CAAC,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YAChD,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;YACpD,CAAC;YACD,IAAI,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACpD,GAAG,CAAC,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC3C,CAAC;YACD,IAAI,EAAE,CAAC;QACR,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC/D,CAAC;IAED,0CAA0C;IAC1C,IAAI,UAAU,EAAE,CAAC;QAChB,GAAG,CAAC,GAAG,CAAC,CAAC,GAAY,EAAE,IAAc,EAAE,IAAkB,EAAE,EAAE;YAC5D,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;gBACd,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC;YACD,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAsD,CAAC;YACjG,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAA2B,CAAC;YACxE,CAAC;YACD,IAAI,EAAE,CAAC;QACR,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,CAAC;IAED,+CAA+C;IAC/C,IAAI,aAAa,EAAE,CAAC;QACnB,GAAG,CAAC,GAAG,CACN,MAAM,CAAC;YACN,qBAAqB,EAAE;gBACtB,UAAU,EAAE;oBACX,UAAU,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;oBACtC,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;oBACrC,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC;oBACpD,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;oBAChD,UAAU,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC;oBACxD,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;oBAClD,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;oBACnC,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;oBACrC,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;oBACpC,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;iBACpC;aACD;YACD,IAAI,EAAE;gBACL,MAAM,EAAE,QAAQ,EAAE,SAAS;gBAC3B,iBAAiB,EAAE,IAAI;gBACvB,OAAO,EAAE,IAAI;aACb;YACD,UAAU,EAAE;gBACX,MAAM,EAAE,MAAM;aACd;YACD,cAAc,EAAE;gBACf,MAAM,EAAE,iCAAiC;aACzC;YACD,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;YACf,kBAAkB,EAAE;gBACnB,KAAK,EAAE,KAAK;aACZ;SACD,CAAC,CACF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,CAAC;IAED,uCAAuC;IACvC,GAAG,CAAC,cAAc,CACjB,IAAI,cAAc,CAAC;QAClB,SAAS,EAAE,IAAI;QACf,oBAAoB,EAAE,IAAI;QAC1B,SAAS,EAAE,IAAI;KACf,CAAC,CACF,CAAC;IACF,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAE/C,mDAAmD;IACnD,IAAI,WAAW,EAAE,CAAC;QACjB,wDAAwD;QACxD,MAAM,mBAAmB,GAAG;YAC3B,kCAAkC;YAClC,4BAA4B;SAC5B,CAAC;QAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA4BG;QACH,GAAG,CAAC,UAAU,CAAC;YACd,MAAM,EAAE,CAAC,MAA0B,EAAE,QAAsD,EAAE,EAAE;gBAC9F,mEAAmE;gBACnE,IAAI,CAAC,MAAM,EAAE,CAAC;oBACb,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACrB,OAAO;gBACR,CAAC;gBAED,gHAAgH;gBAChH,IAAI,WAAW,KAAK,aAAa,IAAI,+BAA+B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACrB,OAAO;gBACR,CAAC;gBAED,8CAA8C;gBAC9C,IAAI,WAAW,KAAK,aAAa,IAAI,mBAAmB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC3E,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACrB,OAAO;gBACR,CAAC;gBAED,mEAAmE;gBACnE,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;oBACjF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACrB,OAAO;gBACR,CAAC;gBAED,yBAAyB;gBACzB,QAAQ,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC5C,CAAC;YACD,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;YAC7D,cAAc,EAAE,kBAAkB;YAClC,cAAc,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC;YAClD,MAAM,EAAE,IAAI;SACZ,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CACT,WAAW,CAAC,MAAM,GAAG,CAAC;YACrB,CAAC,CAAC,oCAAoC,WAAW,sBAAsB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC/F,CAAC,CAAC,oCAAoC,WAAW,iCAAiC,CACnF,CAAC;IACH,CAAC;AACF,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { ExceptionFilter, ArgumentsHost } from '@nestjs/common';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
4
+ /**
5
+ * Standard error response structure for all exceptions.
6
+ */
7
+ export interface ErrorResponseBody {
8
+ success: false;
9
+ error: {
10
+ code: string;
11
+ message: string;
12
+ timestamp: string;
13
+ context?: Record<string, any>;
14
+ stack?: string;
15
+ };
16
+ }
17
+ /**
18
+ * Global Exception Filter.
19
+ * Catches all unhandled exceptions except HttpException (which is handled by HttpExceptionFilter).
20
+ * Standardizes error responses with consistent structure and logs all errors with categorization.
21
+ *
22
+ * Handles:
23
+ * - BaseApplicationError: Standardized application errors with code, status, context
24
+ * - Error: Generic JavaScript errors
25
+ * - Unknown: Unclassified exceptions
26
+ *
27
+ * Error Response Format:
28
+ * - success: false
29
+ * - error.code: Error code for programmatic handling
30
+ * - error.message: Human-readable error message
31
+ * - error.timestamp: ISO timestamp of error occurrence
32
+ * - error.context: Additional context (development only)
33
+ * - error.stack: Stack trace (development only)
34
+ *
35
+ * @remarks
36
+ * - Automatically redacts sensitive information via ErrorSanitizerService
37
+ * - Categorizes errors for logging (transient vs permanent, retryable, strategy)
38
+ * - Development mode includes full context and stack traces
39
+ * - Production mode shows generic error messages for security
40
+ * - Logs request details: method, URL, IP, user-agent
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * // Development response
45
+ * {
46
+ * success: false,
47
+ * error: {
48
+ * code: 'USER_NOT_FOUND',
49
+ * message: 'User with ID 123 not found',
50
+ * timestamp: '2024-01-01T12:00:00.000Z',
51
+ * context: { userId: '123' },
52
+ * stack: '...'
53
+ * }
54
+ * }
55
+ *
56
+ * // Production response
57
+ * {
58
+ * success: false,
59
+ * error: {
60
+ * code: 'USER_NOT_FOUND',
61
+ * message: 'User with ID 123 not found',
62
+ * timestamp: '2024-01-01T12:00:00.000Z'
63
+ * }
64
+ * }
65
+ * ```
66
+ */
67
+ export declare class GlobalExceptionFilter implements ExceptionFilter, LazyModuleRefService {
68
+ private _logger;
69
+ private _errorSanitizer;
70
+ private _errorCategorizer;
71
+ readonly Module: ModuleRef;
72
+ constructor(module: ModuleRef);
73
+ private get Logger();
74
+ private get ErrorSanitizer();
75
+ private get ErrorCategorizer();
76
+ catch(exception: unknown, host: ArgumentsHost): void;
77
+ }
78
+ //# sourceMappingURL=global-exception.filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-exception.filter.d.ts","sourceRoot":"","sources":["../../../src/common/filters/global-exception.filter.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,eAAe,EAEf,aAAa,EAEb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAMzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACF;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,qBACa,qBAAsB,YAAW,eAAe,EAAE,oBAAoB;IAClF,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,eAAe,CAAoC;IAC3D,OAAO,CAAC,iBAAiB,CAAsC;IAC/D,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,MAAM,GAGjB;IAED,OAAO,KAAK,cAAc,GAGzB;IAED,OAAO,KAAK,gBAAgB,GAG3B;IAEM,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;CAuG3D"}
@@ -0,0 +1,192 @@
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 { Catch, HttpStatus, } from '@nestjs/common';
11
+ import { ModuleRef } from '@nestjs/core';
12
+ import { BaseApplicationError } from '../errors/base-application-error.js';
13
+ import { AppLogger } from '../services/logger.service.js';
14
+ import { ErrorSanitizerService } from '../services/error-sanitizer.service.js';
15
+ import { ErrorCategorizerService } from '../services/error-categorizer.service.js';
16
+ /**
17
+ * Development environments where stack traces and full error details are shown
18
+ */
19
+ const DEV_ENVIRONMENTS = new Set(['development', 'dev', 'local', 'test']);
20
+ /**
21
+ * Global Exception Filter.
22
+ * Catches all unhandled exceptions except HttpException (which is handled by HttpExceptionFilter).
23
+ * Standardizes error responses with consistent structure and logs all errors with categorization.
24
+ *
25
+ * Handles:
26
+ * - BaseApplicationError: Standardized application errors with code, status, context
27
+ * - Error: Generic JavaScript errors
28
+ * - Unknown: Unclassified exceptions
29
+ *
30
+ * Error Response Format:
31
+ * - success: false
32
+ * - error.code: Error code for programmatic handling
33
+ * - error.message: Human-readable error message
34
+ * - error.timestamp: ISO timestamp of error occurrence
35
+ * - error.context: Additional context (development only)
36
+ * - error.stack: Stack trace (development only)
37
+ *
38
+ * @remarks
39
+ * - Automatically redacts sensitive information via ErrorSanitizerService
40
+ * - Categorizes errors for logging (transient vs permanent, retryable, strategy)
41
+ * - Development mode includes full context and stack traces
42
+ * - Production mode shows generic error messages for security
43
+ * - Logs request details: method, URL, IP, user-agent
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * // Development response
48
+ * {
49
+ * success: false,
50
+ * error: {
51
+ * code: 'USER_NOT_FOUND',
52
+ * message: 'User with ID 123 not found',
53
+ * timestamp: '2024-01-01T12:00:00.000Z',
54
+ * context: { userId: '123' },
55
+ * stack: '...'
56
+ * }
57
+ * }
58
+ *
59
+ * // Production response
60
+ * {
61
+ * success: false,
62
+ * error: {
63
+ * code: 'USER_NOT_FOUND',
64
+ * message: 'User with ID 123 not found',
65
+ * timestamp: '2024-01-01T12:00:00.000Z'
66
+ * }
67
+ * }
68
+ * ```
69
+ */
70
+ let GlobalExceptionFilter = class GlobalExceptionFilter {
71
+ _logger;
72
+ _errorSanitizer;
73
+ _errorCategorizer;
74
+ Module;
75
+ constructor(module) {
76
+ this.Module = module;
77
+ }
78
+ get Logger() {
79
+ this._logger ??= this.Module.get(AppLogger);
80
+ return this._logger;
81
+ }
82
+ get ErrorSanitizer() {
83
+ this._errorSanitizer ??= this.Module.get(ErrorSanitizerService);
84
+ return this._errorSanitizer;
85
+ }
86
+ get ErrorCategorizer() {
87
+ this._errorCategorizer ??= this.Module.get(ErrorCategorizerService);
88
+ return this._errorCategorizer;
89
+ }
90
+ catch(exception, host) {
91
+ // Handle regular HTTP requests
92
+ const ctx = host.switchToHttp();
93
+ const response = ctx.getResponse();
94
+ const request = ctx.getRequest();
95
+ const isProduction = !DEV_ENVIRONMENTS.has(process.env['NODE_ENV'] ?? '');
96
+ const isDevelopment = !isProduction;
97
+ let status;
98
+ let errorResponse;
99
+ let errorCategory;
100
+ let errorTrace;
101
+ // Standardize error response structure for all exception types
102
+ if (exception instanceof BaseApplicationError) {
103
+ // Standardized application error
104
+ status = exception.statusCode;
105
+ errorResponse = {
106
+ success: false,
107
+ error: {
108
+ code: exception.code,
109
+ message: exception.message,
110
+ timestamp: exception.timestamp.toISOString(),
111
+ ...(isDevelopment ? {
112
+ context: exception.context,
113
+ stack: exception.stack,
114
+ } : {}),
115
+ },
116
+ };
117
+ errorCategory = this.ErrorCategorizer.categorizeError(exception);
118
+ errorTrace = isDevelopment ? exception.stack : undefined;
119
+ }
120
+ else if (exception instanceof Error) {
121
+ // Generic Error
122
+ status = HttpStatus.INTERNAL_SERVER_ERROR;
123
+ errorResponse = {
124
+ success: false,
125
+ error: {
126
+ code: 'INTERNAL_SERVER_ERROR',
127
+ message: isDevelopment ? exception.message : 'An unexpected error occurred',
128
+ timestamp: new Date().toISOString(),
129
+ ...(isDevelopment ? { stack: exception.stack } : {}),
130
+ },
131
+ };
132
+ errorCategory = this.ErrorCategorizer.categorizeError(exception);
133
+ errorTrace = isDevelopment ? exception.stack : undefined;
134
+ }
135
+ else {
136
+ // Unknown exception type
137
+ status = HttpStatus.INTERNAL_SERVER_ERROR;
138
+ errorResponse = {
139
+ success: false,
140
+ error: {
141
+ code: 'UNKNOWN_ERROR',
142
+ message: isDevelopment ? String(exception) : 'An unexpected error occurred',
143
+ timestamp: new Date().toISOString(),
144
+ },
145
+ };
146
+ errorCategory = {
147
+ type: 'permanent',
148
+ retryable: false,
149
+ strategy: 'fail',
150
+ };
151
+ }
152
+ // Log the error with categorization
153
+ this.Logger.error('Global exception caught', errorTrace, undefined, {
154
+ message: errorResponse.error.message,
155
+ status,
156
+ errorType: errorCategory.type,
157
+ retryable: errorCategory.retryable,
158
+ strategy: errorCategory.strategy,
159
+ backoffMs: errorCategory.backoffMs,
160
+ url: request.url,
161
+ method: request.method,
162
+ userAgent: request.get('User-Agent'),
163
+ ip: request.ip,
164
+ });
165
+ // Sanitize error response for production
166
+ // Pass the nested error object (which has .message, .stack, .context) to the sanitizer,
167
+ // then reconstruct the full response envelope with the sanitized inner object.
168
+ const sanitizedInner = this.ErrorSanitizer.sanitizeErrorResponse({
169
+ message: errorResponse.error.message,
170
+ statusCode: status,
171
+ stack: errorResponse.error.stack,
172
+ context: errorResponse.error.context,
173
+ }, isDevelopment);
174
+ const sanitizedError = {
175
+ success: false,
176
+ error: {
177
+ code: errorResponse.error.code,
178
+ message: sanitizedInner.message,
179
+ timestamp: errorResponse.error.timestamp,
180
+ ...(isDevelopment && sanitizedInner.context ? { context: sanitizedInner.context } : {}),
181
+ ...(isDevelopment && sanitizedInner.stack ? { stack: sanitizedInner.stack } : {}),
182
+ },
183
+ };
184
+ response.status(status).json(sanitizedError);
185
+ }
186
+ };
187
+ GlobalExceptionFilter = __decorate([
188
+ Catch(BaseApplicationError, Error),
189
+ __metadata("design:paramtypes", [ModuleRef])
190
+ ], GlobalExceptionFilter);
191
+ export { GlobalExceptionFilter };
192
+ //# sourceMappingURL=global-exception.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-exception.filter.js","sourceRoot":"","sources":["../../../src/common/filters/global-exception.filter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { ExceptionFilter, ArgumentsHost, HttpException } from '@nestjs/common';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
4
+ /**
5
+ * HTTP Exception Filter.
6
+ * Handles all HTTP exceptions (400, 401, 403, 404, etc.) and formats error responses consistently.
7
+ * Complements GlobalExceptionFilter by handling NestJS built-in and thrown HTTP exceptions.
8
+ *
9
+ * Error Response Format:
10
+ * - Preserves original HTTP status code and response body
11
+ * - Sanitizes sensitive information before sending to client
12
+ * - Categorizes error for logging (transient vs permanent)
13
+ *
14
+ * @remarks
15
+ * - Automatically redacts sensitive data via ErrorSanitizerService
16
+ * - Logs error with categorization for monitoring
17
+ * - Preserves original exception response structure
18
+ * - Works in conjunction with GlobalExceptionFilter (processes first)
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * // Handled exceptions
23
+ * throw new BadRequestException('Invalid input'); // 400
24
+ * throw new UnauthorizedException('Invalid token'); // 401
25
+ * throw new ForbiddenException('Access denied'); // 403
26
+ * throw new NotFoundException('User not found'); // 404
27
+ * ```
28
+ */
29
+ export declare class HttpExceptionFilter implements ExceptionFilter, LazyModuleRefService {
30
+ readonly Module: ModuleRef;
31
+ constructor(module: ModuleRef);
32
+ private get Logger();
33
+ private get ErrorSanitizer();
34
+ private get ErrorCategorizer();
35
+ catch(exception: HttpException, host: ArgumentsHost): void;
36
+ }
37
+ //# sourceMappingURL=http-exception.filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-exception.filter.d.ts","sourceRoot":"","sources":["../../../src/common/filters/http-exception.filter.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,eAAe,EAEf,aAAa,EACb,aAAa,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAOrE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBACa,mBAAoB,YAAW,eAAe,EAAE,oBAAoB;IAChF,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,MAAM,GAEjB;IAED,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,gBAAgB,GAE3B;IAEM,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;CAmCjE"}
@@ -0,0 +1,91 @@
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 { Catch, HttpException, } from '@nestjs/common';
11
+ import { ModuleRef } from '@nestjs/core';
12
+ import { AppLogger } from '../services/logger.service.js';
13
+ import { ErrorSanitizerService } from '../services/error-sanitizer.service.js';
14
+ import { ErrorCategorizerService } from '../services/error-categorizer.service.js';
15
+ /**
16
+ * Development environments where stack traces and full error details are shown
17
+ */
18
+ const DEV_ENVIRONMENTS = new Set(['development', 'dev', 'local', 'test']);
19
+ /**
20
+ * HTTP Exception Filter.
21
+ * Handles all HTTP exceptions (400, 401, 403, 404, etc.) and formats error responses consistently.
22
+ * Complements GlobalExceptionFilter by handling NestJS built-in and thrown HTTP exceptions.
23
+ *
24
+ * Error Response Format:
25
+ * - Preserves original HTTP status code and response body
26
+ * - Sanitizes sensitive information before sending to client
27
+ * - Categorizes error for logging (transient vs permanent)
28
+ *
29
+ * @remarks
30
+ * - Automatically redacts sensitive data via ErrorSanitizerService
31
+ * - Logs error with categorization for monitoring
32
+ * - Preserves original exception response structure
33
+ * - Works in conjunction with GlobalExceptionFilter (processes first)
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // Handled exceptions
38
+ * throw new BadRequestException('Invalid input'); // 400
39
+ * throw new UnauthorizedException('Invalid token'); // 401
40
+ * throw new ForbiddenException('Access denied'); // 403
41
+ * throw new NotFoundException('User not found'); // 404
42
+ * ```
43
+ */
44
+ let HttpExceptionFilter = class HttpExceptionFilter {
45
+ Module;
46
+ constructor(module) {
47
+ this.Module = module;
48
+ }
49
+ get Logger() {
50
+ return this.Module.get(AppLogger);
51
+ }
52
+ get ErrorSanitizer() {
53
+ return this.Module.get(ErrorSanitizerService);
54
+ }
55
+ get ErrorCategorizer() {
56
+ return this.Module.get(ErrorCategorizerService);
57
+ }
58
+ catch(exception, host) {
59
+ // Handle regular HTTP requests
60
+ const ctx = host.switchToHttp();
61
+ const response = ctx.getResponse();
62
+ const status = exception.getStatus();
63
+ const isProduction = !DEV_ENVIRONMENTS.has(process.env['NODE_ENV'] ?? '');
64
+ const isDevelopment = !isProduction;
65
+ // Normalize response to object for sanitization
66
+ const exceptionResponse = exception.getResponse();
67
+ const errorObj = typeof exceptionResponse === 'string'
68
+ ? { message: exceptionResponse, statusCode: status }
69
+ : exceptionResponse;
70
+ // Sanitize error response
71
+ const sanitizedError = this.ErrorSanitizer.sanitizeErrorResponse(errorObj, isDevelopment);
72
+ // Categorize and log error
73
+ const errorCategory = this.ErrorCategorizer.categorizeError(exception);
74
+ this.Logger.error('HTTP Exception caught', undefined, undefined, {
75
+ message: exception.message,
76
+ status,
77
+ errorType: errorCategory.type,
78
+ retryable: errorCategory.retryable,
79
+ strategy: errorCategory.strategy,
80
+ backoffMs: errorCategory.backoffMs,
81
+ stack: isDevelopment ? exception.stack : undefined,
82
+ });
83
+ response.status(status).json(sanitizedError);
84
+ }
85
+ };
86
+ HttpExceptionFilter = __decorate([
87
+ Catch(HttpException),
88
+ __metadata("design:paramtypes", [ModuleRef])
89
+ ], HttpExceptionFilter);
90
+ export { HttpExceptionFilter };
91
+ //# sourceMappingURL=http-exception.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-exception.filter.js","sourceRoot":"","sources":["../../../src/common/filters/http-exception.filter.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAEN,KAAK,EAEL,aAAa,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAGnF;;GAEG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IACf,MAAM,CAAY;IAElC,YAAY,MAAiB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,IAAY,MAAM;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,IAAY,cAAc;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAC/C,CAAC;IAED,IAAY,gBAAgB;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACjD,CAAC;IAEM,KAAK,CAAC,SAAwB,EAAE,IAAmB;QACzD,+BAA+B;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAY,CAAC;QAC7C,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;QAErC,MAAM,YAAY,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,aAAa,GAAG,CAAC,YAAY,CAAC;QAEpC,gDAAgD;QAChD,MAAM,iBAAiB,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,OAAO,iBAAiB,KAAK,QAAQ;YACrD,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,EAAE;YACpD,CAAC,CAAC,iBAAiB,CAAC;QAErB,0BAA0B;QAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAC/D,QAA+B,EAC/B,aAAa,CACb,CAAC;QAEF,2BAA2B;QAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,SAAS,EAAE,SAAS,EAAE;YAChE,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,MAAM;YACN,SAAS,EAAE,aAAa,CAAC,IAAI;YAC7B,SAAS,EAAE,aAAa,CAAC,SAAS;YAClC,QAAQ,EAAE,aAAa,CAAC,QAAQ;YAChC,SAAS,EAAE,aAAa,CAAC,SAAS;YAClC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;SAClD,CAAC,CAAC;QAEH,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC9C,CAAC;CACD,CAAA;AAtDY,mBAAmB;IAD/B,KAAK,CAAC,aAAa,CAAC;qCAIA,SAAS;GAHjB,mBAAmB,CAsD/B"}