@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,287 @@
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 ErrorSanitizerService_1;
11
+ import { Injectable } from '@nestjs/common';
12
+ import { HTTP_STATUS_INTERNAL_SERVER_ERROR } from '../constants/http-status.constants.js';
13
+ import { ModuleRef } from '@nestjs/core';
14
+ /**
15
+ * Injection token for ErrorSanitizerService configuration.
16
+ */
17
+ export const ERROR_SANITIZER_OPTIONS = 'ERROR_SANITIZER_OPTIONS';
18
+ /**
19
+ * Error Sanitizer Service.
20
+ * Sanitizes error responses and error context to prevent information disclosure in production.
21
+ * Removes sensitive information like stack traces, file paths, database URIs, API keys, email addresses,
22
+ * IP addresses, and custom sensitive fields.
23
+ *
24
+ * Implements defense-in-depth by sanitizing:
25
+ * - Error messages (via regex patterns)
26
+ * - Nested context objects (via field name matching)
27
+ * - Stack traces (removed in production)
28
+ *
29
+ * Sensitive patterns redacted:
30
+ * - File paths (e.g., `/home/user/app.ts` -> `[FILE]`)
31
+ * - Database URIs (e.g., `mongodb://...` -> `[REDACTED]`)
32
+ * - API keys and tokens (e.g., `Bearer sk_live_...` -> `Bearer [REDACTED]`)
33
+ * - Email addresses (e.g., `user@example.com` -> `[EMAIL]`)
34
+ * - IP addresses (IPv4 and IPv6) -> `[IP]`
35
+ * - Sensitive field values (passwords, tokens, API keys, etc.) -> `***REDACTED***`
36
+ *
37
+ * @remarks
38
+ * - Maximum message length: 5000 chars (prevents ReDoS attacks on regex patterns)
39
+ * - Maximum context depth: 5 levels (prevents deeply nested structure processing)
40
+ * - Circular reference detection prevents infinite loops
41
+ * - Case-insensitive field name matching for sensitivity
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const error = {
46
+ * message: 'Error at /home/user/app.ts, Bearer sk_live_abc123',
47
+ * context: { password: 'secret123', userId: '456' }
48
+ * };
49
+ * const sanitized = errorSanitizer.sanitizeErrorResponse(error, false);
50
+ * // message: 'Error at [FILE], Bearer [REDACTED]'
51
+ * // context: { password: '***REDACTED***', userId: '456' }
52
+ * ```
53
+ */
54
+ let ErrorSanitizerService = class ErrorSanitizerService {
55
+ static { ErrorSanitizerService_1 = this; }
56
+ /**
57
+ * Maximum length for error messages before truncation.
58
+ * Prevents ReDoS (Regular Expression Denial of Service) attacks by limiting
59
+ * the input size to regex patterns used in message sanitization.
60
+ */
61
+ // eslint-disable-next-line no-magic-numbers
62
+ static MAX_MESSAGE_LENGTH = 5000;
63
+ /**
64
+ * Maximum nesting depth for context object serialization.
65
+ * Prevents deeply nested structures from causing performance issues.
66
+ */
67
+ // eslint-disable-next-line no-magic-numbers
68
+ static MAX_CONTEXT_DEPTH = 5;
69
+ /**
70
+ * Precompiled regex pattern for matching file paths with code extensions
71
+ * Used to redact file paths from error messages
72
+ */
73
+ static FILE_PATH_REGEX = /\/[a-zA-Z0-9_./:-]{0,200}\.(?:ts|js|json|py|go|rb|java|cs|php)/g;
74
+ /**
75
+ * Precompiled regex pattern for matching IPv4 addresses
76
+ */
77
+ static IPV4_REGEX = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
78
+ /**
79
+ * Precompiled regex pattern for matching IPv6 addresses
80
+ * Covers various IPv6 formats: full form, compressed form, ::1, ::ffff:IPv4, bare ::
81
+ * Uses a simpler, non-backtracking pattern to avoid ReDoS (Regular Expression Denial of Service)
82
+ */
83
+ static IPV6_REGEX = /(?:::(?:ffff(?::0{1,4})?:)?(?:25[0-5]|(?:2[0-4]|1?[0-9])?[0-9])(?:\.(?:25[0-5]|(?:2[0-4]|1?[0-9])?[0-9])){3}|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?::[0-9a-fA-F]{1,4}){1,7}|::)/gi;
84
+ /**
85
+ * Default sensitive field names that are always redacted from context
86
+ * Stored as lowercase for case-insensitive matching
87
+ */
88
+ static DEFAULT_SENSITIVE_KEYS = [
89
+ 'password',
90
+ 'pwd',
91
+ 'passwd',
92
+ 'pass',
93
+ 'token',
94
+ 'secret',
95
+ 'key',
96
+ 'credential',
97
+ 'apikey',
98
+ 'api_key',
99
+ 'api-key',
100
+ 'authorization',
101
+ 'auth',
102
+ 'jwt',
103
+ 'refreshtoken',
104
+ 'accesstoken',
105
+ 'private_key',
106
+ 'privatekey',
107
+ 'secret_key',
108
+ 'client_secret',
109
+ 'access_token',
110
+ 'refresh_token',
111
+ 'bearer',
112
+ 'ssn',
113
+ 'credit_card',
114
+ 'creditcard',
115
+ 'card_number',
116
+ 'cardnumber',
117
+ 'cvv',
118
+ 'pin',
119
+ ];
120
+ Module;
121
+ constructor(module) {
122
+ this.Module = module;
123
+ }
124
+ get Options() {
125
+ try {
126
+ return this.Module.get(ERROR_SANITIZER_OPTIONS, { strict: false });
127
+ }
128
+ catch {
129
+ return undefined;
130
+ }
131
+ }
132
+ /**
133
+ * Sanitize error response for client
134
+ * Removes sensitive information like stack traces, file paths, etc.
135
+ */
136
+ sanitizeErrorResponse(error, isDevelopment = false) {
137
+ const sanitized = {
138
+ message: this.sanitizeMessage(error.message),
139
+ statusCode: error.statusCode ?? HTTP_STATUS_INTERNAL_SERVER_ERROR,
140
+ timestamp: new Date().toISOString(),
141
+ };
142
+ // Only include stack trace in development
143
+ if (isDevelopment && error.stack) {
144
+ sanitized.stack = error.stack;
145
+ }
146
+ // Sanitize context if present
147
+ if (error.context) {
148
+ sanitized.context = this.sanitizeContext(error.context);
149
+ }
150
+ return sanitized;
151
+ }
152
+ /**
153
+ * Sanitize an error message to remove sensitive information.
154
+ * Redacts file paths, database connection strings, API keys, Bearer tokens,
155
+ * email addresses, and IP addresses. Truncates overly long messages to prevent
156
+ * ReDoS attacks and ensure reasonable log sizes.
157
+ *
158
+ * @param message - The error message string to sanitize
159
+ * @returns Sanitized message with sensitive patterns replaced by placeholder strings
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * const msg = 'Error at /home/user/app.ts, Bearer sk_live_abc123';
164
+ * const sanitized = sanitizeMessage(msg);
165
+ * // Returns: 'Error at [FILE], Bearer [REDACTED]'
166
+ * ```
167
+ */
168
+ sanitizeMessage(message) {
169
+ if (!message)
170
+ return 'An error occurred';
171
+ // Ensure message is a string
172
+ let safeMessage = message;
173
+ if (typeof safeMessage !== 'string') {
174
+ safeMessage = String(safeMessage);
175
+ }
176
+ // Truncate message to prevent ReDoS attacks on regex patterns
177
+ const truncated = safeMessage.length > ErrorSanitizerService_1.MAX_MESSAGE_LENGTH
178
+ ? `${safeMessage.substring(0, ErrorSanitizerService_1.MAX_MESSAGE_LENGTH)}... [truncated]`
179
+ : safeMessage;
180
+ // Remove file paths - match paths with code file extensions
181
+ let sanitized = truncated.replace(ErrorSanitizerService_1.FILE_PATH_REGEX, '[FILE]');
182
+ // Remove database connection strings
183
+ sanitized = sanitized.replace(/mongodb:\/\/[^\s/]+/gi, '[REDACTED]');
184
+ sanitized = sanitized.replace(/postgres(?:ql)?:\/\/[^\s/]+/gi, '[REDACTED]');
185
+ // Remove API keys and tokens
186
+ sanitized = sanitized.replace(/Bearer\s+[a-zA-Z0-9._-]+/gi, 'Bearer [REDACTED]');
187
+ sanitized = sanitized.replace(/(?:api[_-]?key|sk_live|sk_test|pk_live|pk_test)[\s=:]*[a-zA-Z0-9._-]+/gi, '[REDACTED]');
188
+ // Remove email addresses - more restrictive pattern
189
+ sanitized = sanitized.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, '[EMAIL]');
190
+ // Remove IP addresses (both IPv4 and IPv6)
191
+ sanitized = sanitized.replace(ErrorSanitizerService_1.IPV4_REGEX, '[IP]');
192
+ sanitized = sanitized.replace(ErrorSanitizerService_1.IPV6_REGEX, '[IP]');
193
+ return sanitized;
194
+ }
195
+ /**
196
+ * Recursively sanitize an error context object to remove sensitive field values.
197
+ * Identifies sensitive fields by name (e.g., password, token, secret) and replaces
198
+ * their values with a redaction marker. Handles nested objects and arrays while
199
+ * detecting circular references to prevent infinite loops.
200
+ *
201
+ * @param context - The context object to sanitize
202
+ * @returns Sanitized context with sensitive field values replaced
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * const ctx = { user: 'john', password: 'secret123', nested: { apiKey: 'sk_live' } };
207
+ * const sanitized = sanitizeContext(ctx);
208
+ * // Returns: { user: 'john', password: '***REDACTED***', nested: { apiKey: '***REDACTED***' } }
209
+ * ```
210
+ */
211
+ sanitizeContext(context) {
212
+ const seen = new Set();
213
+ const result = this.serializeWithDepthLimit(context, ErrorSanitizerService_1.MAX_CONTEXT_DEPTH, 0, seen);
214
+ return result ?? {};
215
+ }
216
+ /**
217
+ * Recursively serialize an object with depth limiting and circular reference detection.
218
+ * Handles nested objects and arrays while preventing infinite loops.
219
+ *
220
+ * @param obj - The object to serialize
221
+ * @param maxDepth - Maximum nesting depth (default 5)
222
+ * @param currentDepth - Current recursion depth
223
+ * @param seen - Set of already-visited objects to detect cycles
224
+ * @returns Serialized object with sensitive fields redacted
225
+ */
226
+ serializeWithDepthLimit(obj, maxDepth, currentDepth, seen) {
227
+ // Return non-object values as-is
228
+ if (typeof obj !== 'object' || obj === null) {
229
+ if (typeof obj === 'string') {
230
+ return this.sanitizeMessage(obj);
231
+ }
232
+ return obj;
233
+ }
234
+ // Check for circular reference
235
+ if (seen.has(obj)) {
236
+ return '[CIRCULAR_REF]';
237
+ }
238
+ // Check for max depth
239
+ if (currentDepth >= maxDepth) {
240
+ return '[MAX_DEPTH]';
241
+ }
242
+ // Mark object as visited immediately after circular check, before recursing
243
+ seen.add(obj);
244
+ // Handle arrays
245
+ if (Array.isArray(obj)) {
246
+ return obj.map(item => this.serializeWithDepthLimit(item, maxDepth, currentDepth + 1, seen));
247
+ }
248
+ // Handle objects
249
+ const sanitized = {};
250
+ for (const [key, value] of Object.entries(obj)) {
251
+ // Skip sensitive fields
252
+ if (this.isSensitiveField(key)) {
253
+ sanitized[key] = '***REDACTED***';
254
+ }
255
+ else if (typeof value === 'object' && value !== null) {
256
+ // For objects and arrays, recurse with depth check
257
+ sanitized[key] = this.serializeWithDepthLimit(value, maxDepth, currentDepth + 1, seen);
258
+ }
259
+ else if (typeof value === 'string') {
260
+ // Sanitize string values
261
+ sanitized[key] = this.sanitizeMessage(value);
262
+ }
263
+ else {
264
+ // Return primitive values as-is
265
+ sanitized[key] = value;
266
+ }
267
+ }
268
+ return sanitized;
269
+ }
270
+ /**
271
+ * Check if field is sensitive (case-insensitive comparison)
272
+ */
273
+ isSensitiveField(fieldName) {
274
+ const fieldNameLower = fieldName.toLowerCase();
275
+ const allSensitiveFields = [
276
+ ...ErrorSanitizerService_1.DEFAULT_SENSITIVE_KEYS,
277
+ ...(this.Options?.additionalSensitiveKeys ?? []),
278
+ ];
279
+ return allSensitiveFields.some(field => fieldNameLower.includes(field.toLowerCase()));
280
+ }
281
+ };
282
+ ErrorSanitizerService = ErrorSanitizerService_1 = __decorate([
283
+ Injectable(),
284
+ __metadata("design:paramtypes", [ModuleRef])
285
+ ], ErrorSanitizerService);
286
+ export { ErrorSanitizerService };
287
+ //# sourceMappingURL=error-sanitizer.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-sanitizer.service.js","sourceRoot":"","sources":["../../../src/common/services/error-sanitizer.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAkBzC;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGI,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;;IACjC;;;;OAIG;IACH,4CAA4C;IACpC,MAAM,CAAU,kBAAkB,GAAG,IAAI,CAAC;IAElD;;;OAGG;IACH,4CAA4C;IACpC,MAAM,CAAU,iBAAiB,GAAG,CAAC,CAAC;IAE9C;;;OAGG;IACK,MAAM,CAAU,eAAe,GAAG,iEAAiE,CAAC;IAE5G;;OAEG;IACK,MAAM,CAAU,UAAU,GAAG,8BAA8B,CAAC;IAEpE;;;;OAIG;IACK,MAAM,CAAU,UAAU,GAAG,igBAAigB,CAAC;IAEviB;;;OAGG;IACK,MAAM,CAAU,sBAAsB,GAAG;QAChD,UAAU;QACV,KAAK;QACL,QAAQ;QACR,MAAM;QACN,OAAO;QACP,QAAQ;QACR,KAAK;QACL,YAAY;QACZ,QAAQ;QACR,SAAS;QACT,SAAS;QACT,eAAe;QACf,MAAM;QACN,KAAK;QACL,cAAc;QACd,aAAa;QACb,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,eAAe;QACf,cAAc;QACd,eAAe;QACf,QAAQ;QACR,KAAK;QACL,aAAa;QACb,YAAY;QACZ,aAAa;QACb,YAAY;QACZ,KAAK;QACL,KAAK;KACL,CAAC;IAEc,MAAM,CAAY;IAElC,YAAY,MAAiB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,IAAY,OAAO;QAClB,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,qBAAqB,CAAC,KAA0B,EAAE,gBAAyB,KAAK;QACtF,MAAM,SAAS,GAAwB;YACtC,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;YAC5C,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,iCAAiC;YACjE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC;QAEF,0CAA0C;QAC1C,IAAI,aAAa,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAClC,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC/B,CAAC;QAED,8BAA8B;QAC9B,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACK,eAAe,CAAC,OAAe;QACtC,IAAI,CAAC,OAAO;YAAE,OAAO,mBAAmB,CAAC;QAEzC,6BAA6B;QAC7B,IAAI,WAAW,GAAG,OAAO,CAAC;QAC1B,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACrC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACnC,CAAC;QAED,8DAA8D;QAC9D,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,GAAG,uBAAqB,CAAC,kBAAkB;YAC9E,CAAC,CAAC,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,uBAAqB,CAAC,kBAAkB,CAAC,iBAAiB;YACxF,CAAC,CAAC,WAAW,CAAC;QAEf,4DAA4D;QAC5D,IAAI,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,uBAAqB,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;QAEnF,qCAAqC;QACrC,SAAS,GAAG,SAAS,CAAC,OAAO,CAC5B,uBAAuB,EACvB,YAAY,CACZ,CAAC;QACF,SAAS,GAAG,SAAS,CAAC,OAAO,CAC5B,+BAA+B,EAC/B,YAAY,CACZ,CAAC;QAEF,6BAA6B;QAC7B,SAAS,GAAG,SAAS,CAAC,OAAO,CAC5B,4BAA4B,EAC5B,mBAAmB,CACnB,CAAC;QACF,SAAS,GAAG,SAAS,CAAC,OAAO,CAC5B,yEAAyE,EACzE,YAAY,CACZ,CAAC;QAEF,oDAAoD;QACpD,SAAS,GAAG,SAAS,CAAC,OAAO,CAC5B,iDAAiD,EACjD,SAAS,CACT,CAAC;QAEF,2CAA2C;QAC3C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,uBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACxE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,uBAAqB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAExE,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACK,eAAe,CAAC,OAA4B;QACnD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,uBAAuB,CAC1C,OAAO,EACP,uBAAqB,CAAC,iBAAiB,EACvC,CAAC,EACD,IAAI,CACJ,CAAC;QACF,OAAQ,MAA8B,IAAI,EAAE,CAAC;IAC9C,CAAC;IAED;;;;;;;;;OASG;IACK,uBAAuB,CAC9B,GAAY,EACZ,QAAgB,EAChB,YAAoB,EACpB,IAAiB;QAEjB,iCAAiC;QACjC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,+BAA+B;QAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,OAAO,gBAAgB,CAAC;QACzB,CAAC;QAED,sBAAsB;QACtB,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;YAC9B,OAAO,aAAa,CAAC;QACtB,CAAC;QAED,4EAA4E;QAC5E,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEd,gBAAgB;QAChB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACrB,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,GAAG,CAAC,EAAE,IAAI,CAAC,CACpE,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,MAAM,SAAS,GAAwB,EAAE,CAAC;QAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,wBAAwB;YACxB,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,SAAS,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC;YACnC,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACxD,mDAAmD;gBACnD,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,uBAAuB,CAC5C,KAAK,EACL,QAAQ,EACR,YAAY,GAAG,CAAC,EAChB,IAAI,CACJ,CAAC;YACH,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACtC,yBAAyB;gBACzB,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACP,gCAAgC;gBAChC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACxB,CAAC;QACF,CAAC;QAED,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,SAAiB;QACzC,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,kBAAkB,GAAG;YAC1B,GAAG,uBAAqB,CAAC,sBAAsB;YAC/C,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,uBAAuB,IAAI,EAAE,CAAC;SAChD,CAAC;QAEF,OAAO,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACtC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAC5C,CAAC;IACH,CAAC;;AA9RW,qBAAqB;IADjC,UAAU,EAAE;qCA0EQ,SAAS;GAzEjB,qBAAqB,CA+RjC"}
@@ -0,0 +1,86 @@
1
+ import { ModuleRef } from '@nestjs/core';
2
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
3
+ /**
4
+ * Health status enumeration for standardized health check responses.
5
+ */
6
+ export declare enum HealthStatus {
7
+ OK = "ok",
8
+ READY = "ready",
9
+ ALIVE = "alive"
10
+ }
11
+ /**
12
+ * Health check response interface.
13
+ */
14
+ export interface IHealthCheck {
15
+ status: string;
16
+ timestamp: string;
17
+ service?: string;
18
+ version?: string;
19
+ checks?: Record<string, string>;
20
+ }
21
+ /**
22
+ * Health Check Service.
23
+ * Provides standardized health, readiness, and liveness checks for Kubernetes probes and monitoring.
24
+ *
25
+ * Probe types:
26
+ * - **Health/Status**: General application health (used by load balancers)
27
+ * - **Readiness**: Determines if service should receive traffic (Kubernetes readiness probe)
28
+ * - **Liveness**: Confirms service is alive and responsive (Kubernetes liveness probe)
29
+ *
30
+ * @remarks
31
+ * - All responses include ISO timestamps for log correlation
32
+ * - Supports optional service name and version strings
33
+ * - Readiness probe can include custom checks (database, cache, etc.)
34
+ * - All checks automatically logged via AppLogger for monitoring
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // In a health controller
39
+ * @Get('/')
40
+ * health() {
41
+ * return this.healthService.getHealth('my-service', '1.0.0');
42
+ * }
43
+ *
44
+ * @Get('/ready')
45
+ * readiness() {
46
+ * const checks = {
47
+ * database: HealthStatus.OK,
48
+ * cache: HealthStatus.OK,
49
+ * };
50
+ * return this.healthService.getReadiness(checks);
51
+ * }
52
+ *
53
+ * @Get('/live')
54
+ * liveness() {
55
+ * return this.healthService.getLiveness();
56
+ * }
57
+ * ```
58
+ */
59
+ export declare class HealthCheckService implements LazyModuleRefService {
60
+ private _contextualLogger;
61
+ readonly Module: ModuleRef;
62
+ constructor(module: ModuleRef);
63
+ private get Logger();
64
+ /**
65
+ * Get application health status
66
+ * Used for general health checks
67
+ * @param serviceName - Optional service name
68
+ * @param version - Optional version string
69
+ * @returns Health check response
70
+ */
71
+ getHealth(serviceName?: string, version?: string): IHealthCheck;
72
+ /**
73
+ * Get application readiness status
74
+ * Used for Kubernetes readiness probes to determine if service should receive traffic
75
+ * @param checks - Optional custom health checks (e.g., database, cache status)
76
+ * @returns Readiness check response
77
+ */
78
+ getReadiness(checks?: Record<string, string>): IHealthCheck;
79
+ /**
80
+ * Get application liveness status
81
+ * Used for Kubernetes liveness probes to determine if service is alive
82
+ * @returns Liveness check response
83
+ */
84
+ getLiveness(): IHealthCheck;
85
+ }
86
+ //# sourceMappingURL=health-check.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.service.d.ts","sourceRoot":"","sources":["../../../src/common/services/health-check.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE;;GAEG;AACH,oBAAY,YAAY;IACvB,EAAE,OAAO;IACT,KAAK,UAAU;IACf,KAAK,UAAU;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBACa,kBAAmB,YAAW,oBAAoB;IAC9D,OAAO,CAAC,iBAAiB,CAAwB;IAEjD,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,SAAS;IAI7B,OAAO,KAAK,MAAM,GAMjB;IAED;;;;;;OAMG;IACI,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY;IAoBtE;;;;;OAKG;IACI,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY;IAalE;;;;OAIG;IACI,WAAW,IAAI,YAAY;CAWlC"}
@@ -0,0 +1,132 @@
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 HealthCheckService_1;
11
+ import { Injectable } from '@nestjs/common';
12
+ import { ModuleRef } from '@nestjs/core';
13
+ import { AppLogger } from './logger.service.js';
14
+ /**
15
+ * Health status enumeration for standardized health check responses.
16
+ */
17
+ export var HealthStatus;
18
+ (function (HealthStatus) {
19
+ HealthStatus["OK"] = "ok";
20
+ HealthStatus["READY"] = "ready";
21
+ HealthStatus["ALIVE"] = "alive";
22
+ })(HealthStatus || (HealthStatus = {}));
23
+ /**
24
+ * Health Check Service.
25
+ * Provides standardized health, readiness, and liveness checks for Kubernetes probes and monitoring.
26
+ *
27
+ * Probe types:
28
+ * - **Health/Status**: General application health (used by load balancers)
29
+ * - **Readiness**: Determines if service should receive traffic (Kubernetes readiness probe)
30
+ * - **Liveness**: Confirms service is alive and responsive (Kubernetes liveness probe)
31
+ *
32
+ * @remarks
33
+ * - All responses include ISO timestamps for log correlation
34
+ * - Supports optional service name and version strings
35
+ * - Readiness probe can include custom checks (database, cache, etc.)
36
+ * - All checks automatically logged via AppLogger for monitoring
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // In a health controller
41
+ * @Get('/')
42
+ * health() {
43
+ * return this.healthService.getHealth('my-service', '1.0.0');
44
+ * }
45
+ *
46
+ * @Get('/ready')
47
+ * readiness() {
48
+ * const checks = {
49
+ * database: HealthStatus.OK,
50
+ * cache: HealthStatus.OK,
51
+ * };
52
+ * return this.healthService.getReadiness(checks);
53
+ * }
54
+ *
55
+ * @Get('/live')
56
+ * liveness() {
57
+ * return this.healthService.getLiveness();
58
+ * }
59
+ * ```
60
+ */
61
+ let HealthCheckService = HealthCheckService_1 = class HealthCheckService {
62
+ _contextualLogger;
63
+ Module;
64
+ constructor(module) {
65
+ this.Module = module;
66
+ }
67
+ get Logger() {
68
+ if (!this._contextualLogger) {
69
+ const baseLogger = this.Module.get(AppLogger);
70
+ this._contextualLogger = baseLogger.createContextualLogger(HealthCheckService_1.name);
71
+ }
72
+ return this._contextualLogger;
73
+ }
74
+ /**
75
+ * Get application health status
76
+ * Used for general health checks
77
+ * @param serviceName - Optional service name
78
+ * @param version - Optional version string
79
+ * @returns Health check response
80
+ */
81
+ getHealth(serviceName, version) {
82
+ this.Logger.debug('Health check requested');
83
+ const response = {
84
+ status: HealthStatus.OK,
85
+ timestamp: new Date().toISOString(),
86
+ };
87
+ if (serviceName) {
88
+ response.service = serviceName;
89
+ }
90
+ if (version) {
91
+ response.version = version;
92
+ }
93
+ this.Logger.debug(`Health check response: ${JSON.stringify(response)}`);
94
+ return response;
95
+ }
96
+ /**
97
+ * Get application readiness status
98
+ * Used for Kubernetes readiness probes to determine if service should receive traffic
99
+ * @param checks - Optional custom health checks (e.g., database, cache status)
100
+ * @returns Readiness check response
101
+ */
102
+ getReadiness(checks) {
103
+ this.Logger.debug('Readiness check requested');
104
+ const response = {
105
+ status: HealthStatus.READY,
106
+ timestamp: new Date().toISOString(),
107
+ checks: checks ?? {},
108
+ };
109
+ this.Logger.debug(`Readiness check response: ${JSON.stringify(response)}`);
110
+ return response;
111
+ }
112
+ /**
113
+ * Get application liveness status
114
+ * Used for Kubernetes liveness probes to determine if service is alive
115
+ * @returns Liveness check response
116
+ */
117
+ getLiveness() {
118
+ this.Logger.debug('Liveness check requested');
119
+ const response = {
120
+ status: HealthStatus.ALIVE,
121
+ timestamp: new Date().toISOString(),
122
+ };
123
+ this.Logger.debug(`Liveness check response: ${JSON.stringify(response)}`);
124
+ return response;
125
+ }
126
+ };
127
+ HealthCheckService = HealthCheckService_1 = __decorate([
128
+ Injectable(),
129
+ __metadata("design:paramtypes", [ModuleRef])
130
+ ], HealthCheckService);
131
+ export { HealthCheckService };
132
+ //# sourceMappingURL=health-check.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.service.js","sourceRoot":"","sources":["../../../src/common/services/health-check.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD;;GAEG;AACH,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACvB,yBAAS,CAAA;IACT,+BAAe,CAAA;IACf,+BAAe,CAAA;AAChB,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEI,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IACtB,iBAAiB,CAAwB;IAEjC,MAAM,CAAY;IAElC,YAAY,MAAiB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,IAAY,MAAM;QACjB,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC9C,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,sBAAsB,CAAC,oBAAkB,CAAC,IAAI,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAC/B,CAAC;IAED;;;;;;OAMG;IACI,SAAS,CAAC,WAAoB,EAAE,OAAgB;QACtD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAiB;YAC9B,MAAM,EAAE,YAAY,CAAC,EAAE;YACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC;QAEF,IAAI,WAAW,EAAE,CAAC;YACjB,QAAQ,CAAC,OAAO,GAAG,WAAW,CAAC;QAChC,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACb,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACxE,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;;OAKG;IACI,YAAY,CAAC,MAA+B;QAClD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAiB;YAC9B,MAAM,EAAE,YAAY,CAAC,KAAK;YAC1B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,MAAM,IAAI,EAAE;SACpB,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC3E,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACI,WAAW;QACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAE9C,MAAM,QAAQ,GAAiB;YAC9B,MAAM,EAAE,YAAY,CAAC,KAAK;YAC1B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACnC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1E,OAAO,QAAQ,CAAC;IACjB,CAAC;CACD,CAAA;AA/EY,kBAAkB;IAD9B,UAAU,EAAE;qCAMQ,SAAS;GALjB,kBAAkB,CA+E9B"}
@@ -0,0 +1,113 @@
1
+ import { ModuleRef } from '@nestjs/core';
2
+ import { LazyModuleRefService } from '../utils/lazy-getter.types.js';
3
+ import { AppLogger } from './logger.service.js';
4
+ /**
5
+ * HTTP request options.
6
+ */
7
+ interface HttpRequestOptions {
8
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
9
+ url: string;
10
+ headers?: Record<string, string>;
11
+ data?: Record<string, unknown> | string;
12
+ timeout?: number;
13
+ correlationId?: string;
14
+ /**
15
+ * Whether to reject unauthorized (self-signed) SSL/TLS certificates.
16
+ * Default: true (recommended for production)
17
+ *
18
+ * Security Warning: Setting this to false allows Man-in-the-Middle (MITM) attacks
19
+ * in production environments. Only use for development or testing with known certificates.
20
+ *
21
+ * @default true
22
+ */
23
+ rejectUnauthorized?: boolean;
24
+ /**
25
+ * Custom Certificate Authority (CA) certificate for SSL/TLS validation.
26
+ * Can be a PEM-encoded certificate as a string or Buffer.
27
+ * Useful for environments using self-signed or internal CAs.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const cert = fs.readFileSync('/path/to/ca.pem');
32
+ * await client.request({
33
+ * url: 'https://internal-api.local',
34
+ * ca: cert,
35
+ * });
36
+ * ```
37
+ */
38
+ ca?: Buffer | string;
39
+ }
40
+ /**
41
+ * HTTP response wrapper.
42
+ */
43
+ interface HttpResponse<T = Record<string, unknown>> {
44
+ data: T;
45
+ status: number;
46
+ statusText: string;
47
+ headers: Record<string, string>;
48
+ duration: number;
49
+ }
50
+ /**
51
+ * HTTP Client Service.
52
+ * Provides a robust HTTP client with timeout handling, SSL/TLS configuration, payload size limits,
53
+ * and comprehensive logging with sensitive data redaction.
54
+ *
55
+ * Features:
56
+ * - Configurable timeouts (default: HTTP_CLIENT_TIMEOUT)
57
+ * - SSL/TLS certificate validation (default: strict)
58
+ * - Custom CA certificate support for self-signed certs
59
+ * - Payload size limit enforcement (10MB default)
60
+ * - Automatic content-type parsing (JSON, text)
61
+ * - Correlation ID support for request tracing
62
+ * - Sensitive data redaction in logs (passwords, tokens, auth headers)
63
+ * - Request/response duration tracking
64
+ *
65
+ * @remarks
66
+ * - Maximum payload size: 10MB (prevents memory exhaustion from large responses)
67
+ * - Timeout error handling with clear error messages
68
+ * - Content-type validation before JSON parsing
69
+ * - All sensitive headers (Authorization, Cookie, X-API-Key) redacted in logs
70
+ * - URLs with embedded credentials are sanitized before logging
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // Simple GET request
75
+ * const response = await client.get('https://api.example.com/users');
76
+ *
77
+ * // POST with custom timeout and correlation ID
78
+ * const response = await client.post('https://api.example.com/users',
79
+ * { name: 'John', email: 'john@example.com' },
80
+ * { timeout: 5000, correlationId: 'req-123' }
81
+ * );
82
+ *
83
+ * // HTTPS with custom CA certificate
84
+ * const cert = fs.readFileSync('/path/to/ca.pem');
85
+ * const response = await client.get('https://internal-api.local/data', { ca: cert });
86
+ * ```
87
+ */
88
+ export declare class HttpClientService implements LazyModuleRefService {
89
+ private _contextualLogger;
90
+ readonly Module: ModuleRef;
91
+ constructor(module: ModuleRef);
92
+ get Logger(): AppLogger;
93
+ /**
94
+ * Makes an HTTP request. URLs with embedded credentials and sensitive headers
95
+ * are sanitized before logging.
96
+ */
97
+ request<T = Record<string, unknown>>(options: HttpRequestOptions): Promise<HttpResponse<T>>;
98
+ get<T = Record<string, unknown>>(url: string, options?: Omit<HttpRequestOptions, 'method' | 'url'>): Promise<HttpResponse<T>>;
99
+ post<T = Record<string, unknown>>(url: string, data?: Record<string, unknown> | string, options?: Omit<HttpRequestOptions, 'method' | 'url' | 'data'>): Promise<HttpResponse<T>>;
100
+ put<T = Record<string, unknown>>(url: string, data?: Record<string, unknown> | string, options?: Omit<HttpRequestOptions, 'method' | 'url' | 'data'>): Promise<HttpResponse<T>>;
101
+ delete<T = Record<string, unknown>>(url: string, options?: Omit<HttpRequestOptions, 'method' | 'url'>): Promise<HttpResponse<T>>;
102
+ /**
103
+ * Sanitize a URL to remove embedded credentials (e.g., https://user:pass@host/)
104
+ */
105
+ private sanitizeUrl;
106
+ /**
107
+ * Redacts sensitive headers (authorization, cookies, API keys, CSRF tokens)
108
+ * before logging.
109
+ */
110
+ private sanitizeHeaders;
111
+ }
112
+ export {};
113
+ //# sourceMappingURL=http-client.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-client.service.d.ts","sourceRoot":"","sources":["../../../src/common/services/http-client.service.ts"],"names":[],"mappings":"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"}