hi-secure 1.0.0

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 (210) hide show
  1. package/dist/adapters/ArgonAdapter.d.ts +8 -0
  2. package/dist/adapters/ArgonAdapter.d.ts.map +1 -0
  3. package/dist/adapters/ArgonAdapter.js +45 -0
  4. package/dist/adapters/ArgonAdapter.js.map +1 -0
  5. package/dist/adapters/BcryptAdapter.d.ts +7 -0
  6. package/dist/adapters/BcryptAdapter.d.ts.map +1 -0
  7. package/dist/adapters/BcryptAdapter.js +48 -0
  8. package/dist/adapters/BcryptAdapter.js.map +1 -0
  9. package/dist/adapters/DomPurifyAdapter.d.ts +13 -0
  10. package/dist/adapters/DomPurifyAdapter.d.ts.map +1 -0
  11. package/dist/adapters/DomPurifyAdapter.js +61 -0
  12. package/dist/adapters/DomPurifyAdapter.js.map +1 -0
  13. package/dist/adapters/ExpressRLAdapter.d.ts +13 -0
  14. package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -0
  15. package/dist/adapters/ExpressRLAdapter.js +68 -0
  16. package/dist/adapters/ExpressRLAdapter.js.map +1 -0
  17. package/dist/adapters/ExpressValidatorAdapter.d.ts +6 -0
  18. package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -0
  19. package/dist/adapters/ExpressValidatorAdapter.js +78 -0
  20. package/dist/adapters/ExpressValidatorAdapter.js.map +1 -0
  21. package/dist/adapters/GoggleAdapter.d.ts +15 -0
  22. package/dist/adapters/GoggleAdapter.d.ts.map +1 -0
  23. package/dist/adapters/GoggleAdapter.js +91 -0
  24. package/dist/adapters/GoggleAdapter.js.map +1 -0
  25. package/dist/adapters/GoogleAdapter.d.ts +15 -0
  26. package/dist/adapters/GoogleAdapter.d.ts.map +1 -0
  27. package/dist/adapters/GoogleAdapter.js +159 -0
  28. package/dist/adapters/GoogleAdapter.js.map +1 -0
  29. package/dist/adapters/JWTAdapter.d.ts +28 -0
  30. package/dist/adapters/JWTAdapter.d.ts.map +1 -0
  31. package/dist/adapters/JWTAdapter.js +276 -0
  32. package/dist/adapters/JWTAdapter.js.map +1 -0
  33. package/dist/adapters/RLFlexibleAdapter.d.ts +11 -0
  34. package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -0
  35. package/dist/adapters/RLFlexibleAdapter.js +115 -0
  36. package/dist/adapters/RLFlexibleAdapter.js.map +1 -0
  37. package/dist/adapters/SanitizeHtmlAdapter.d.ts +12 -0
  38. package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -0
  39. package/dist/adapters/SanitizeHtmlAdapter.js +141 -0
  40. package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -0
  41. package/dist/adapters/XSSAdapter.d.ts +33 -0
  42. package/dist/adapters/XSSAdapter.d.ts.map +1 -0
  43. package/dist/adapters/XSSAdapter.js +127 -0
  44. package/dist/adapters/XSSAdapter.js.map +1 -0
  45. package/dist/adapters/ZodAdapter.d.ts +7 -0
  46. package/dist/adapters/ZodAdapter.d.ts.map +1 -0
  47. package/dist/adapters/ZodAdapter.js +39 -0
  48. package/dist/adapters/ZodAdapter.js.map +1 -0
  49. package/dist/core/HiSecure.d.ts +62 -0
  50. package/dist/core/HiSecure.d.ts.map +1 -0
  51. package/dist/core/HiSecure.js +273 -0
  52. package/dist/core/HiSecure.js.map +1 -0
  53. package/dist/core/config.d.ts +3 -0
  54. package/dist/core/config.d.ts.map +1 -0
  55. package/dist/core/config.js +53 -0
  56. package/dist/core/config.js.map +1 -0
  57. package/dist/core/constants.d.ts +37 -0
  58. package/dist/core/constants.d.ts.map +1 -0
  59. package/dist/core/constants.js +67 -0
  60. package/dist/core/constants.js.map +1 -0
  61. package/dist/core/errors/AdapterError.d.ts +5 -0
  62. package/dist/core/errors/AdapterError.d.ts.map +1 -0
  63. package/dist/core/errors/AdapterError.js +15 -0
  64. package/dist/core/errors/AdapterError.js.map +1 -0
  65. package/dist/core/errors/HttpErrror.d.ts +17 -0
  66. package/dist/core/errors/HttpErrror.d.ts.map +1 -0
  67. package/dist/core/errors/HttpErrror.js +36 -0
  68. package/dist/core/errors/HttpErrror.js.map +1 -0
  69. package/dist/core/errors/SanitizerError.d.ts +5 -0
  70. package/dist/core/errors/SanitizerError.d.ts.map +1 -0
  71. package/dist/core/errors/SanitizerError.js +14 -0
  72. package/dist/core/errors/SanitizerError.js.map +1 -0
  73. package/dist/core/errors/SecurityError.d.ts +5 -0
  74. package/dist/core/errors/SecurityError.d.ts.map +1 -0
  75. package/dist/core/errors/SecurityError.js +14 -0
  76. package/dist/core/errors/SecurityError.js.map +1 -0
  77. package/dist/core/errors/ValidationError.d.ts +5 -0
  78. package/dist/core/errors/ValidationError.d.ts.map +1 -0
  79. package/dist/core/errors/ValidationError.js +14 -0
  80. package/dist/core/errors/ValidationError.js.map +1 -0
  81. package/dist/core/types/HiSecureConfig.d.ts +47 -0
  82. package/dist/core/types/HiSecureConfig.d.ts.map +1 -0
  83. package/dist/core/types/HiSecureConfig.js +3 -0
  84. package/dist/core/types/HiSecureConfig.js.map +1 -0
  85. package/dist/core/types/SecureOptions.d.ts +30 -0
  86. package/dist/core/types/SecureOptions.d.ts.map +1 -0
  87. package/dist/core/types/SecureOptions.js +4 -0
  88. package/dist/core/types/SecureOptions.js.map +1 -0
  89. package/dist/core/useSecure.d.ts +10 -0
  90. package/dist/core/useSecure.d.ts.map +1 -0
  91. package/dist/core/useSecure.js +85 -0
  92. package/dist/core/useSecure.js.map +1 -0
  93. package/dist/examples/e1.d.ts +1 -0
  94. package/dist/examples/e1.d.ts.map +1 -0
  95. package/dist/examples/e1.js +3 -0
  96. package/dist/examples/e1.js.map +1 -0
  97. package/dist/index.d.ts +9 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +15 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/logging/index.d.ts +3 -0
  102. package/dist/logging/index.d.ts.map +1 -0
  103. package/dist/logging/index.js +19 -0
  104. package/dist/logging/index.js.map +1 -0
  105. package/dist/logging/morganSetup.d.ts +2 -0
  106. package/dist/logging/morganSetup.d.ts.map +1 -0
  107. package/dist/logging/morganSetup.js +9 -0
  108. package/dist/logging/morganSetup.js.map +1 -0
  109. package/dist/logging/winstonSetup.d.ts +6 -0
  110. package/dist/logging/winstonSetup.d.ts.map +1 -0
  111. package/dist/logging/winstonSetup.js +22 -0
  112. package/dist/logging/winstonSetup.js.map +1 -0
  113. package/dist/managers/AuthManager.d.ts +23 -0
  114. package/dist/managers/AuthManager.d.ts.map +1 -0
  115. package/dist/managers/AuthManager.js +190 -0
  116. package/dist/managers/AuthManager.js.map +1 -0
  117. package/dist/managers/CorsManager.d.ts +9 -0
  118. package/dist/managers/CorsManager.d.ts.map +1 -0
  119. package/dist/managers/CorsManager.js +55 -0
  120. package/dist/managers/CorsManager.js.map +1 -0
  121. package/dist/managers/HashManager.d.ts +22 -0
  122. package/dist/managers/HashManager.d.ts.map +1 -0
  123. package/dist/managers/HashManager.js +319 -0
  124. package/dist/managers/HashManager.js.map +1 -0
  125. package/dist/managers/JsonManager.d.ts +6 -0
  126. package/dist/managers/JsonManager.d.ts.map +1 -0
  127. package/dist/managers/JsonManager.js +142 -0
  128. package/dist/managers/JsonManager.js.map +1 -0
  129. package/dist/managers/RateLimitManager.d.ts +16 -0
  130. package/dist/managers/RateLimitManager.d.ts.map +1 -0
  131. package/dist/managers/RateLimitManager.js +108 -0
  132. package/dist/managers/RateLimitManager.js.map +1 -0
  133. package/dist/managers/SanitizerManager.d.ts +18 -0
  134. package/dist/managers/SanitizerManager.d.ts.map +1 -0
  135. package/dist/managers/SanitizerManager.js +296 -0
  136. package/dist/managers/SanitizerManager.js.map +1 -0
  137. package/dist/managers/ValidatorManager.d.ts +13 -0
  138. package/dist/managers/ValidatorManager.d.ts.map +1 -0
  139. package/dist/managers/ValidatorManager.js +218 -0
  140. package/dist/managers/ValidatorManager.js.map +1 -0
  141. package/dist/middlewares/errorHandler.d.ts +3 -0
  142. package/dist/middlewares/errorHandler.d.ts.map +1 -0
  143. package/dist/middlewares/errorHandler.js +94 -0
  144. package/dist/middlewares/errorHandler.js.map +1 -0
  145. package/dist/middlewares/index.d.ts +3 -0
  146. package/dist/middlewares/index.d.ts.map +1 -0
  147. package/dist/middlewares/index.js +19 -0
  148. package/dist/middlewares/index.js.map +1 -0
  149. package/dist/middlewares/requestLogger.d.ts +2 -0
  150. package/dist/middlewares/requestLogger.d.ts.map +1 -0
  151. package/dist/middlewares/requestLogger.js +8 -0
  152. package/dist/middlewares/requestLogger.js.map +1 -0
  153. package/dist/test/t1.d.ts +1 -0
  154. package/dist/test/t1.d.ts.map +1 -0
  155. package/dist/test/t1.js +3 -0
  156. package/dist/test/t1.js.map +1 -0
  157. package/dist/utils/deepFreeze.d.ts +2 -0
  158. package/dist/utils/deepFreeze.d.ts.map +1 -0
  159. package/dist/utils/deepFreeze.js +69 -0
  160. package/dist/utils/deepFreeze.js.map +1 -0
  161. package/dist/utils/deepMerge.d.ts +5 -0
  162. package/dist/utils/deepMerge.d.ts.map +1 -0
  163. package/dist/utils/deepMerge.js +68 -0
  164. package/dist/utils/deepMerge.js.map +1 -0
  165. package/dist/utils/normalizeOptions.d.ts +38 -0
  166. package/dist/utils/normalizeOptions.d.ts.map +1 -0
  167. package/dist/utils/normalizeOptions.js +119 -0
  168. package/dist/utils/normalizeOptions.js.map +1 -0
  169. package/package.json +50 -0
  170. package/src/adapters/ArgonAdapter.ts +41 -0
  171. package/src/adapters/BcryptAdapter.ts +49 -0
  172. package/src/adapters/ExpressRLAdapter.ts +84 -0
  173. package/src/adapters/ExpressValidatorAdapter.ts +99 -0
  174. package/src/adapters/GoogleAdapter.ts +206 -0
  175. package/src/adapters/JWTAdapter.ts +346 -0
  176. package/src/adapters/RLFlexibleAdapter.ts +139 -0
  177. package/src/adapters/SanitizeHtmlAdapter.ts +162 -0
  178. package/src/adapters/XSSAdapter.ts +153 -0
  179. package/src/adapters/ZodAdapter.ts +91 -0
  180. package/src/core/HiSecure.ts +955 -0
  181. package/src/core/config.ts +156 -0
  182. package/src/core/constants.ts +73 -0
  183. package/src/core/errors/AdapterError.ts +14 -0
  184. package/src/core/errors/HttpErrror.ts +46 -0
  185. package/src/core/errors/SanitizerError.ts +13 -0
  186. package/src/core/errors/SecurityError.ts +13 -0
  187. package/src/core/errors/ValidationError.ts +13 -0
  188. package/src/core/types/HiSecureConfig.ts +62 -0
  189. package/src/core/types/SecureOptions.ts +61 -0
  190. package/src/core/useSecure.ts +111 -0
  191. package/src/examples/e1.ts +1 -0
  192. package/src/index.ts +17 -0
  193. package/src/logging/index.ts +2 -0
  194. package/src/logging/morganSetup.ts +3 -0
  195. package/src/logging/winstonSetup.ts +17 -0
  196. package/src/managers/AuthManager.ts +237 -0
  197. package/src/managers/CorsManager.ts +58 -0
  198. package/src/managers/HashManager.ts +390 -0
  199. package/src/managers/JsonManager.ts +149 -0
  200. package/src/managers/RateLimitManager.ts +368 -0
  201. package/src/managers/SanitizerManager.ts +359 -0
  202. package/src/managers/ValidatorManager.ts +269 -0
  203. package/src/middlewares/errorHandler.ts +265 -0
  204. package/src/middlewares/index.ts +2 -0
  205. package/src/middlewares/requestLogger.ts +5 -0
  206. package/src/test/t1.ts +1 -0
  207. package/src/utils/deepFreeze.ts +76 -0
  208. package/src/utils/deepMerge.ts +87 -0
  209. package/src/utils/normalizeOptions.ts +265 -0
  210. package/tsconfig.json +30 -0
@@ -0,0 +1,296 @@
1
+ "use strict";
2
+ // // // import { SanitizerError } from "../core/errors/SanitizerError";
3
+ // // // import { logger } from "../logging";
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.SanitizerManager = void 0;
6
+ // // // interface SanitizerAdapter {
7
+ // // // sanitize: (value: string) => string;
8
+ // // // middleware?: () => any;
9
+ // // // }
10
+ // // // export class SanitizerManager {
11
+ // // // private primary: SanitizerAdapter;
12
+ // // // private fallback: SanitizerAdapter | null;
13
+ // // // constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {
14
+ // // // this.primary = primary;
15
+ // // // this.fallback = fallback;
16
+ // // // }
17
+ // // // sanitize(value: string): string {
18
+ // // // try {
19
+ // // // return this.primary.sanitize(value);
20
+ // // // } catch (err: any) {
21
+ // // // logger.warn("⚠ Sanitizer primary adapter failed", { error: err?.message });
22
+ // // // if (!this.fallback) {
23
+ // // // throw new SanitizerError("Primary sanitizer failed, no fallback available.");
24
+ // // // }
25
+ // // // try {
26
+ // // // logger.info("📌 Using fallback sanitizer");
27
+ // // // return this.fallback.sanitize(value);
28
+ // // // } catch (fallbackErr: any) {
29
+ // // // logger.error("❌ Fallback sanitizer failed", {
30
+ // // // error: fallbackErr?.message
31
+ // // // });
32
+ // // // throw new SanitizerError("Both primary and fallback sanitizers failed.");
33
+ // // // }
34
+ // // // }
35
+ // // // }
36
+ // // // middleware() {
37
+ // // // return (req: any, _res: any, next: any) => {
38
+ // // // try {
39
+ // // // if (req.body && typeof req.body === "object") {
40
+ // // // for (const key of Object.keys(req.body)) {
41
+ // // // const value = req.body[key];
42
+ // // // if (typeof value === "string") {
43
+ // // // const clean = this.sanitize(value);
44
+ // // // logger.debug("🧼 Sanitized field", {
45
+ // // // field: key,
46
+ // // // before: value.slice(0, 80),
47
+ // // // after: clean.slice(0, 80),
48
+ // // // });
49
+ // // // req.body[key] = clean;
50
+ // // // }
51
+ // // // }
52
+ // // // }
53
+ // // // next();
54
+ // // // } catch (err: any) {
55
+ // // // logger.error("❌ Sanitizer middleware failed", { error: err?.message });
56
+ // // // next(new SanitizerError("Sanitizer middleware failure"));
57
+ // // // }
58
+ // // // };
59
+ // // // }
60
+ // // // }
61
+ // // // src/managers/SanitizerManager.ts
62
+ // // import { SanitizerError } from "../core/errors/SanitizerError.js";
63
+ // // import { logger } from "../logging";
64
+ // // interface SanitizerAdapter {
65
+ // // sanitize: (value: string, options?: any) => string;
66
+ // // }
67
+ // // export class SanitizerManager {
68
+ // // private primary: SanitizerAdapter;
69
+ // // private fallback: SanitizerAdapter | null;
70
+ // // constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {
71
+ // // this.primary = primary;
72
+ // // this.fallback = fallback;
73
+ // // }
74
+ // // /**
75
+ // // * Sanitize a single value with optional dynamic options.
76
+ // // */
77
+ // // sanitize(value: string, options?: any): string {
78
+ // // try {
79
+ // // return this.primary.sanitize(value, options);
80
+ // // } catch (err: any) {
81
+ // // logger.warn("⚠ Primary sanitizer failed", { error: err?.message });
82
+ // // if (!this.fallback) {
83
+ // // throw new SanitizerError("Primary sanitizer failed and no fallback available.");
84
+ // // }
85
+ // // try {
86
+ // // logger.info("📌 Using fallback sanitizer");
87
+ // // return this.fallback.sanitize(value, options);
88
+ // // } catch (fallbackErr: any) {
89
+ // // logger.error("❌ Fallback sanitizer failed", {
90
+ // // error: fallbackErr?.message
91
+ // // });
92
+ // // throw new SanitizerError("Both primary and fallback sanitizers failed.");
93
+ // // }
94
+ // // }
95
+ // // }
96
+ // // /**
97
+ // // * Dynamic express middleware for sanitizing body.
98
+ // // * Options can override global config on each route.
99
+ // // */
100
+ // // middleware(options?: any) {
101
+ // // return (req: any, _res: any, next: any) => {
102
+ // // try {
103
+ // // if (req.body && typeof req.body === "object") {
104
+ // // for (const key of Object.keys(req.body)) {
105
+ // // const original = req.body[key];
106
+ // // if (typeof original === "string") {
107
+ // // const sanitized = this.sanitize(original, options);
108
+ // // logger.debug("🧼 Sanitized field", {
109
+ // // field: key,
110
+ // // before: original.slice(0, 80),
111
+ // // after: sanitized.slice(0, 80)
112
+ // // });
113
+ // // req.body[key] = sanitized;
114
+ // // }
115
+ // // }
116
+ // // }
117
+ // // next();
118
+ // // } catch (err: any) {
119
+ // // logger.error("❌ Sanitizer middleware failed", {
120
+ // // error: err?.message
121
+ // // });
122
+ // // next(new SanitizerError("Sanitizer middleware failure"));
123
+ // // }
124
+ // // };
125
+ // // }
126
+ // // }
127
+ // // src/managers/SanitizerManager.ts - FIXED
128
+ // import { SanitizerError } from "../core/errors/SanitizerError.js";
129
+ // import { logger } from "../logging";
130
+ // interface SanitizerAdapter {
131
+ // sanitize: (value: string, options?: any) => string;
132
+ // }
133
+ // export class SanitizerManager {
134
+ // private primary: SanitizerAdapter;
135
+ // private fallback: SanitizerAdapter | null;
136
+ // private useFallbackOnly: boolean = false;
137
+ // constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {
138
+ // this.primary = primary;
139
+ // this.fallback = fallback;
140
+ // }
141
+ // /**
142
+ // * Sanitize a single value
143
+ // */
144
+ // sanitize(value: string, options?: any): string {
145
+ // // Don't process non-strings
146
+ // if (typeof value !== 'string') {
147
+ // return value;
148
+ // }
149
+ // // Use only one sanitizer, not both
150
+ // if (this.useFallbackOnly && this.fallback) {
151
+ // return this.fallback.sanitize(value, options);
152
+ // }
153
+ // try {
154
+ // return this.primary.sanitize(value, options);
155
+ // } catch (err: any) {
156
+ // logger.warn("⚠ Primary sanitizer failed", { error: err?.message });
157
+ // if (!this.fallback) {
158
+ // throw new SanitizerError("Primary sanitizer failed and no fallback available.");
159
+ // }
160
+ // logger.info("📌 Using fallback sanitizer");
161
+ // this.useFallbackOnly = true; // Use fallback for subsequent calls
162
+ // return this.fallback.sanitize(value, options);
163
+ // }
164
+ // }
165
+ // /**
166
+ // * Middleware that doesn't mutate original request
167
+ // */
168
+ // middleware(options?: any) {
169
+ // return (req: any, _res: any, next: any) => {
170
+ // try {
171
+ // // Create a sanitized copy of body instead of mutating
172
+ // if (req.body && typeof req.body === "object") {
173
+ // const originalBody = req.body;
174
+ // const sanitizedBody: any = Array.isArray(originalBody) ? [] : {};
175
+ // for (const key of Object.keys(originalBody)) {
176
+ // const value = originalBody[key];
177
+ // if (typeof value === "string") {
178
+ // sanitizedBody[key] = this.sanitize(value, options);
179
+ // } else if (Array.isArray(value)) {
180
+ // sanitizedBody[key] = value.map(item =>
181
+ // typeof item === "string" ? this.sanitize(item, options) : item
182
+ // );
183
+ // } else {
184
+ // sanitizedBody[key] = value;
185
+ // }
186
+ // }
187
+ // // Store sanitized version separately
188
+ // req.sanitizedBody = sanitizedBody;
189
+ // logger.debug("🧼 Request body sanitized", {
190
+ // originalKeys: Object.keys(originalBody),
191
+ // sanitizedKeys: Object.keys(sanitizedBody)
192
+ // });
193
+ // }
194
+ // next();
195
+ // } catch (err: any) {
196
+ // logger.error("❌ Sanitizer middleware failed", {
197
+ // error: err?.message
198
+ // });
199
+ // next(new SanitizerError("Sanitizer middleware failure"));
200
+ // }
201
+ // };
202
+ // }
203
+ // }
204
+ // src/managers/SanitizerManager.ts - COMPLETE FIXED
205
+ const SanitizerError_js_1 = require("../core/errors/SanitizerError.js");
206
+ const logging_1 = require("../logging");
207
+ class SanitizerManager {
208
+ constructor(primary, fallback = null) {
209
+ this.primary = primary;
210
+ this.fallback = fallback;
211
+ }
212
+ /**
213
+ * Sanitize a single value (public API)
214
+ */
215
+ sanitize(value, options) {
216
+ // Don't process non-strings
217
+ if (typeof value !== 'string') {
218
+ return value;
219
+ }
220
+ try {
221
+ return this.primary.sanitize(value, options);
222
+ }
223
+ catch (err) {
224
+ logging_1.logger.warn("⚠ Primary sanitizer failed", { error: err?.message });
225
+ if (!this.fallback) {
226
+ throw new SanitizerError_js_1.SanitizerError("Primary sanitizer failed and no fallback available.");
227
+ }
228
+ logging_1.logger.info("📌 Using fallback sanitizer");
229
+ return this.fallback.sanitize(value, options);
230
+ }
231
+ }
232
+ /**
233
+ * Middleware - Per-request fallback logic
234
+ */
235
+ middleware(options) {
236
+ return (req, _res, next) => {
237
+ let fallbackTriggered = false;
238
+ // Helper function with per-request fallback logic
239
+ const safeSanitize = (value) => {
240
+ if (fallbackTriggered && this.fallback) {
241
+ return this.fallback.sanitize(value, options);
242
+ }
243
+ try {
244
+ return this.primary.sanitize(value, options);
245
+ }
246
+ catch (err) {
247
+ if (!this.fallback) {
248
+ throw err;
249
+ }
250
+ fallbackTriggered = true;
251
+ logging_1.logger.warn("⚠ Switching to fallback sanitizer for this request");
252
+ return this.fallback.sanitize(value, options);
253
+ }
254
+ };
255
+ try {
256
+ // Create a sanitized copy of body instead of mutating
257
+ if (req.body && typeof req.body === "object") {
258
+ const originalBody = req.body;
259
+ const sanitizedBody = Array.isArray(originalBody) ? [] : {};
260
+ for (const key of Object.keys(originalBody)) {
261
+ const value = originalBody[key];
262
+ if (typeof value === "string") {
263
+ sanitizedBody[key] = safeSanitize(value);
264
+ }
265
+ else if (Array.isArray(value)) {
266
+ sanitizedBody[key] = value.map(item => typeof item === "string" ? safeSanitize(item) : item);
267
+ }
268
+ else if (value && typeof value === "object") {
269
+ // Recursive sanitization for nested objects (optional)
270
+ sanitizedBody[key] = value; // Keep as-is for now
271
+ }
272
+ else {
273
+ sanitizedBody[key] = value;
274
+ }
275
+ }
276
+ // Store sanitized version separately
277
+ req.sanitizedBody = sanitizedBody;
278
+ logging_1.logger.debug("🧼 Request body sanitized", {
279
+ originalKeys: Object.keys(originalBody),
280
+ sanitizedKeys: Object.keys(sanitizedBody),
281
+ usedFallback: fallbackTriggered
282
+ });
283
+ }
284
+ next();
285
+ }
286
+ catch (err) {
287
+ logging_1.logger.error("❌ Sanitizer middleware failed", {
288
+ error: err?.message
289
+ });
290
+ next(new SanitizerError_js_1.SanitizerError("Sanitizer middleware failure"));
291
+ }
292
+ };
293
+ }
294
+ }
295
+ exports.SanitizerManager = SanitizerManager;
296
+ //# sourceMappingURL=SanitizerManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SanitizerManager.js","sourceRoot":"","sources":["../../src/managers/SanitizerManager.ts"],"names":[],"mappings":"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","sourcesContent":["// // // import { SanitizerError } from \"../core/errors/SanitizerError\";\r\n// // // import { logger } from \"../logging\";\r\n\r\n// // // interface SanitizerAdapter {\r\n// // // sanitize: (value: string) => string;\r\n// // // middleware?: () => any;\r\n// // // }\r\n\r\n// // // export class SanitizerManager {\r\n// // // private primary: SanitizerAdapter;\r\n// // // private fallback: SanitizerAdapter | null;\r\n\r\n// // // constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {\r\n// // // this.primary = primary;\r\n// // // this.fallback = fallback;\r\n// // // }\r\n\r\n// // // sanitize(value: string): string {\r\n// // // try {\r\n// // // return this.primary.sanitize(value);\r\n// // // } catch (err: any) {\r\n// // // logger.warn(\"⚠ Sanitizer primary adapter failed\", { error: err?.message });\r\n\r\n// // // if (!this.fallback) {\r\n// // // throw new SanitizerError(\"Primary sanitizer failed, no fallback available.\");\r\n// // // }\r\n\r\n// // // try {\r\n// // // logger.info(\"📌 Using fallback sanitizer\");\r\n// // // return this.fallback.sanitize(value);\r\n// // // } catch (fallbackErr: any) {\r\n// // // logger.error(\"❌ Fallback sanitizer failed\", {\r\n// // // error: fallbackErr?.message\r\n// // // });\r\n// // // throw new SanitizerError(\"Both primary and fallback sanitizers failed.\");\r\n// // // }\r\n// // // }\r\n// // // }\r\n\r\n// // // middleware() {\r\n// // // return (req: any, _res: any, next: any) => {\r\n// // // try {\r\n// // // if (req.body && typeof req.body === \"object\") {\r\n// // // for (const key of Object.keys(req.body)) {\r\n// // // const value = req.body[key];\r\n\r\n// // // if (typeof value === \"string\") {\r\n// // // const clean = this.sanitize(value);\r\n\r\n// // // logger.debug(\"🧼 Sanitized field\", {\r\n// // // field: key,\r\n// // // before: value.slice(0, 80),\r\n// // // after: clean.slice(0, 80),\r\n// // // });\r\n\r\n// // // req.body[key] = clean;\r\n// // // }\r\n// // // }\r\n// // // }\r\n\r\n// // // next();\r\n// // // } catch (err: any) {\r\n// // // logger.error(\"❌ Sanitizer middleware failed\", { error: err?.message });\r\n// // // next(new SanitizerError(\"Sanitizer middleware failure\"));\r\n// // // }\r\n// // // };\r\n// // // }\r\n// // // }\r\n\r\n\r\n\r\n// // // src/managers/SanitizerManager.ts\r\n// // import { SanitizerError } from \"../core/errors/SanitizerError.js\";\r\n// // import { logger } from \"../logging\";\r\n\r\n// // interface SanitizerAdapter {\r\n// // sanitize: (value: string, options?: any) => string;\r\n// // }\r\n\r\n// // export class SanitizerManager {\r\n// // private primary: SanitizerAdapter;\r\n// // private fallback: SanitizerAdapter | null;\r\n\r\n// // constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {\r\n// // this.primary = primary;\r\n// // this.fallback = fallback;\r\n// // }\r\n\r\n// // /**\r\n// // * Sanitize a single value with optional dynamic options.\r\n// // */\r\n// // sanitize(value: string, options?: any): string {\r\n// // try {\r\n// // return this.primary.sanitize(value, options);\r\n\r\n// // } catch (err: any) {\r\n// // logger.warn(\"⚠ Primary sanitizer failed\", { error: err?.message });\r\n\r\n// // if (!this.fallback) {\r\n// // throw new SanitizerError(\"Primary sanitizer failed and no fallback available.\");\r\n// // }\r\n\r\n// // try {\r\n// // logger.info(\"📌 Using fallback sanitizer\");\r\n// // return this.fallback.sanitize(value, options);\r\n\r\n// // } catch (fallbackErr: any) {\r\n// // logger.error(\"❌ Fallback sanitizer failed\", {\r\n// // error: fallbackErr?.message\r\n// // });\r\n\r\n// // throw new SanitizerError(\"Both primary and fallback sanitizers failed.\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n// // /**\r\n// // * Dynamic express middleware for sanitizing body.\r\n// // * Options can override global config on each route.\r\n// // */\r\n// // middleware(options?: any) {\r\n// // return (req: any, _res: any, next: any) => {\r\n// // try {\r\n// // if (req.body && typeof req.body === \"object\") {\r\n// // for (const key of Object.keys(req.body)) {\r\n// // const original = req.body[key];\r\n\r\n// // if (typeof original === \"string\") {\r\n// // const sanitized = this.sanitize(original, options);\r\n\r\n// // logger.debug(\"🧼 Sanitized field\", {\r\n// // field: key,\r\n// // before: original.slice(0, 80),\r\n// // after: sanitized.slice(0, 80)\r\n// // });\r\n\r\n// // req.body[key] = sanitized;\r\n// // }\r\n// // }\r\n// // }\r\n\r\n// // next();\r\n\r\n// // } catch (err: any) {\r\n// // logger.error(\"❌ Sanitizer middleware failed\", {\r\n// // error: err?.message\r\n// // });\r\n\r\n// // next(new SanitizerError(\"Sanitizer middleware failure\"));\r\n// // }\r\n// // };\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n// // src/managers/SanitizerManager.ts - FIXED\r\n// import { SanitizerError } from \"../core/errors/SanitizerError.js\";\r\n// import { logger } from \"../logging\";\r\n\r\n// interface SanitizerAdapter {\r\n// sanitize: (value: string, options?: any) => string;\r\n// }\r\n\r\n// export class SanitizerManager {\r\n// private primary: SanitizerAdapter;\r\n// private fallback: SanitizerAdapter | null;\r\n// private useFallbackOnly: boolean = false;\r\n\r\n// constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {\r\n// this.primary = primary;\r\n// this.fallback = fallback;\r\n// }\r\n\r\n// /**\r\n// * Sanitize a single value\r\n// */\r\n// sanitize(value: string, options?: any): string {\r\n// // Don't process non-strings\r\n// if (typeof value !== 'string') {\r\n// return value;\r\n// }\r\n\r\n// // Use only one sanitizer, not both\r\n// if (this.useFallbackOnly && this.fallback) {\r\n// return this.fallback.sanitize(value, options);\r\n// }\r\n\r\n// try {\r\n// return this.primary.sanitize(value, options);\r\n// } catch (err: any) {\r\n// logger.warn(\"⚠ Primary sanitizer failed\", { error: err?.message });\r\n\r\n// if (!this.fallback) {\r\n// throw new SanitizerError(\"Primary sanitizer failed and no fallback available.\");\r\n// }\r\n\r\n// logger.info(\"📌 Using fallback sanitizer\");\r\n// this.useFallbackOnly = true; // Use fallback for subsequent calls\r\n \r\n// return this.fallback.sanitize(value, options);\r\n// }\r\n// }\r\n\r\n// /**\r\n// * Middleware that doesn't mutate original request\r\n// */\r\n// middleware(options?: any) {\r\n// return (req: any, _res: any, next: any) => {\r\n// try {\r\n// // Create a sanitized copy of body instead of mutating\r\n// if (req.body && typeof req.body === \"object\") {\r\n// const originalBody = req.body;\r\n// const sanitizedBody: any = Array.isArray(originalBody) ? [] : {};\r\n \r\n// for (const key of Object.keys(originalBody)) {\r\n// const value = originalBody[key];\r\n \r\n// if (typeof value === \"string\") {\r\n// sanitizedBody[key] = this.sanitize(value, options);\r\n// } else if (Array.isArray(value)) {\r\n// sanitizedBody[key] = value.map(item => \r\n// typeof item === \"string\" ? this.sanitize(item, options) : item\r\n// );\r\n// } else {\r\n// sanitizedBody[key] = value;\r\n// }\r\n// }\r\n \r\n// // Store sanitized version separately\r\n// req.sanitizedBody = sanitizedBody;\r\n// logger.debug(\"🧼 Request body sanitized\", {\r\n// originalKeys: Object.keys(originalBody),\r\n// sanitizedKeys: Object.keys(sanitizedBody)\r\n// });\r\n// }\r\n\r\n// next();\r\n// } catch (err: any) {\r\n// logger.error(\"❌ Sanitizer middleware failed\", {\r\n// error: err?.message\r\n// });\r\n// next(new SanitizerError(\"Sanitizer middleware failure\"));\r\n// }\r\n// };\r\n// }\r\n// }\r\n\r\n\r\n\r\n// src/managers/SanitizerManager.ts - COMPLETE FIXED\r\nimport { SanitizerError } from \"../core/errors/SanitizerError.js\";\r\nimport { logger } from \"../logging\";\r\n\r\ninterface SanitizerAdapter {\r\n sanitize: (value: string, options?: any) => string;\r\n}\r\n\r\nexport class SanitizerManager {\r\n private primary: SanitizerAdapter;\r\n private fallback: SanitizerAdapter | null;\r\n\r\n constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {\r\n this.primary = primary;\r\n this.fallback = fallback;\r\n }\r\n\r\n /**\r\n * Sanitize a single value (public API)\r\n */\r\n sanitize(value: string, options?: any): string {\r\n // Don't process non-strings\r\n if (typeof value !== 'string') {\r\n return value;\r\n }\r\n\r\n try {\r\n return this.primary.sanitize(value, options);\r\n } catch (err: any) {\r\n logger.warn(\"⚠ Primary sanitizer failed\", { error: err?.message });\r\n\r\n if (!this.fallback) {\r\n throw new SanitizerError(\"Primary sanitizer failed and no fallback available.\");\r\n }\r\n\r\n logger.info(\"📌 Using fallback sanitizer\");\r\n return this.fallback.sanitize(value, options);\r\n }\r\n }\r\n\r\n /**\r\n * Middleware - Per-request fallback logic\r\n */\r\n middleware(options?: any) {\r\n return (req: any, _res: any, next: any) => {\r\n let fallbackTriggered = false;\r\n \r\n // Helper function with per-request fallback logic\r\n const safeSanitize = (value: string): string => {\r\n if (fallbackTriggered && this.fallback) {\r\n return this.fallback.sanitize(value, options);\r\n }\r\n \r\n try {\r\n return this.primary.sanitize(value, options);\r\n } catch (err: any) {\r\n if (!this.fallback) {\r\n throw err;\r\n }\r\n \r\n fallbackTriggered = true;\r\n logger.warn(\"⚠ Switching to fallback sanitizer for this request\");\r\n return this.fallback.sanitize(value, options);\r\n }\r\n };\r\n\r\n try {\r\n // Create a sanitized copy of body instead of mutating\r\n if (req.body && typeof req.body === \"object\") {\r\n const originalBody = req.body;\r\n const sanitizedBody: any = Array.isArray(originalBody) ? [] : {};\r\n \r\n for (const key of Object.keys(originalBody)) {\r\n const value = originalBody[key];\r\n \r\n if (typeof value === \"string\") {\r\n sanitizedBody[key] = safeSanitize(value);\r\n } else if (Array.isArray(value)) {\r\n sanitizedBody[key] = value.map(item => \r\n typeof item === \"string\" ? safeSanitize(item) : item\r\n );\r\n } else if (value && typeof value === \"object\") {\r\n // Recursive sanitization for nested objects (optional)\r\n sanitizedBody[key] = value; // Keep as-is for now\r\n } else {\r\n sanitizedBody[key] = value;\r\n }\r\n }\r\n \r\n // Store sanitized version separately\r\n req.sanitizedBody = sanitizedBody;\r\n \r\n logger.debug(\"🧼 Request body sanitized\", {\r\n originalKeys: Object.keys(originalBody),\r\n sanitizedKeys: Object.keys(sanitizedBody),\r\n usedFallback: fallbackTriggered\r\n });\r\n }\r\n\r\n next();\r\n } catch (err: any) {\r\n logger.error(\"❌ Sanitizer middleware failed\", {\r\n error: err?.message\r\n });\r\n next(new SanitizerError(\"Sanitizer middleware failure\"));\r\n }\r\n };\r\n }\r\n}"]}
@@ -0,0 +1,13 @@
1
+ import { HiSecureConfig } from "../core/types/HiSecureConfig.js";
2
+ interface ValidatorAdapter {
3
+ validate: (schema?: any) => any;
4
+ }
5
+ export declare class ValidatorManager {
6
+ private config;
7
+ private primaryAdapter;
8
+ private fallbackAdapter;
9
+ constructor(config: HiSecureConfig["validation"], primaryAdapter: ValidatorAdapter, fallbackAdapter: ValidatorAdapter | null);
10
+ validate(schema?: any): (req: any, res: any, next: any) => void;
11
+ }
12
+ export {};
13
+ //# sourceMappingURL=ValidatorManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidatorManager.d.ts","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"AAyMA,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,UAAU,gBAAgB;IACtB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,eAAe,CAA0B;gBAG7C,MAAM,EAAE,cAAc,CAAC,YAAY,CAAC,EACpC,cAAc,EAAE,gBAAgB,EAChC,eAAe,EAAE,gBAAgB,GAAG,IAAI;IAO5C,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,IACT,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG;CA6C5C"}
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ // // // import { HiSecureConfig } from "../core/config";
3
+ // // // import { logger } from "../logging";
4
+ // // // import { ValidationError } from "../core/errors/ValidationError";
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ValidatorManager = void 0;
7
+ // // // export class ValidatorManager {
8
+ // // // private config: HiSecureConfig["validation"];
9
+ // // // private primaryAdapter: any;
10
+ // // // private fallbackAdapter: any;
11
+ // // // constructor(
12
+ // // // config: HiSecureConfig["validation"],
13
+ // // // primaryAdapter: any,
14
+ // // // fallbackAdapter: any
15
+ // // // ) {
16
+ // // // this.config = config;
17
+ // // // this.primaryAdapter = primaryAdapter;
18
+ // // // this.fallbackAdapter = fallbackAdapter;
19
+ // // // }
20
+ // // // /**
21
+ // // // * Validate request body using primary adapter (Zod/express-validator).
22
+ // // // * Fallback is only used if the adapter implementation itself throws.
23
+ // // // */
24
+ // // // validate(schema: any) {
25
+ // // // return (req: any, res: any, next: any) => {
26
+ // // // try {
27
+ // // // const middleware = this.primaryAdapter.validate(schema);
28
+ // // // return middleware(req, res, next);
29
+ // // // } catch (err: any) {
30
+ // // // logger.warn("⚠ Primary validator failed", {
31
+ // // // error: err?.message,
32
+ // // // path: req.path,
33
+ // // // method: req.method
34
+ // // // });
35
+ // // // if (!this.fallbackAdapter) {
36
+ // // // return next(new ValidationError("Validation failed."));
37
+ // // // }
38
+ // // // try {
39
+ // // // logger.info("📌 Using fallback validator");
40
+ // // // const fallbackMiddleware = this.fallbackAdapter.validate(schema);
41
+ // // // return fallbackMiddleware(req, res, next);
42
+ // // // } catch (fallbackErr: any) {
43
+ // // // logger.error("❌ Fallback validation also failed", {
44
+ // // // error: fallbackErr?.message
45
+ // // // });
46
+ // // // return next(new ValidationError("Both validators failed."));
47
+ // // // }
48
+ // // // }
49
+ // // // };
50
+ // // // }
51
+ // // // }
52
+ // // import { HiSecureConfig } from "../core/config.js";
53
+ // // import { logger } from "../logging";
54
+ // // import { ValidationError } from "../core/errors/ValidationError.js";
55
+ // // interface ValidatorAdapter {
56
+ // // validate: (schema?: any) => any;
57
+ // // }
58
+ // // export class ValidatorManager {
59
+ // // private config: HiSecureConfig["validation"];
60
+ // // private primaryAdapter: ValidatorAdapter;
61
+ // // private fallbackAdapter: ValidatorAdapter | null;
62
+ // // constructor(
63
+ // // config: HiSecureConfig["validation"],
64
+ // // primaryAdapter: ValidatorAdapter,
65
+ // // fallbackAdapter: ValidatorAdapter | null
66
+ // // ) {
67
+ // // this.config = config;
68
+ // // this.primaryAdapter = primaryAdapter;
69
+ // // this.fallbackAdapter = fallbackAdapter;
70
+ // // }
71
+ // // /**
72
+ // // * MAIN DYNAMIC VALIDATOR ENTRY
73
+ // // * schema = per-route schema
74
+ // // * If schema is undefined → use global schema
75
+ // // */
76
+ // // validate(schema?: any) {
77
+ // // return (req: any, res: any, next: any) => {
78
+ // // try {
79
+ // // const middleware = this.primaryAdapter.validate(schema);
80
+ // // return middleware(req, res, next);
81
+ // // } catch (err: any) {
82
+ // // logger.warn("⚠ Primary validator failed", {
83
+ // // error: err?.message,
84
+ // // path: req.path,
85
+ // // method: req.method
86
+ // // });
87
+ // // if (!this.fallbackAdapter) {
88
+ // // return next(new ValidationError("Validation failed"));
89
+ // // }
90
+ // // try {
91
+ // // logger.info("📌 Using fallback validator");
92
+ // // const fallbackMiddleware = this.fallbackAdapter.validate(schema);
93
+ // // return fallbackMiddleware(req, res, next);
94
+ // // } catch (fallbackErr: any) {
95
+ // // logger.error("❌ Fallback validator also failed", {
96
+ // // error: fallbackErr?.message
97
+ // // });
98
+ // // return next(new ValidationError("Both validators failed"));
99
+ // // }
100
+ // // }
101
+ // // };
102
+ // // }
103
+ // // }
104
+ // // src/managers/ValidatorManager.ts - FIXED
105
+ // import { logger } from "../logging";
106
+ // import { ValidationError } from "../core/errors/ValidationError.js";
107
+ // import { HiSecureConfig } from "../core/types/HiSecureConfig";
108
+ // interface ValidatorAdapter {
109
+ // validate: (schema?: any) => any;
110
+ // }
111
+ // export class ValidatorManager {
112
+ // private config: HiSecureConfig["validation"];
113
+ // private primaryAdapter: ValidatorAdapter;
114
+ // private fallbackAdapter: ValidatorAdapter | null;
115
+ // constructor(
116
+ // config: HiSecureConfig["validation"],
117
+ // primaryAdapter: ValidatorAdapter,
118
+ // fallbackAdapter: ValidatorAdapter | null
119
+ // ) {
120
+ // this.config = config;
121
+ // this.primaryAdapter = primaryAdapter;
122
+ // this.fallbackAdapter = fallbackAdapter;
123
+ // }
124
+ // validate(schema?: any) {
125
+ // return (req: any, res: any, next: any) => {
126
+ // // Execute primary adapter middleware
127
+ // const primaryMiddleware = this.primaryAdapter.validate(schema);
128
+ // // Run middleware and handle errors properly
129
+ // primaryMiddleware(req, res, (err?: any) => {
130
+ // if (!err) {
131
+ // return next(); // Validation passed
132
+ // }
133
+ // // If error is a ValidationError, pass it through (don't fallback!)
134
+ // if (err instanceof ValidationError) {
135
+ // logger.warn("⚠ Validation failed", {
136
+ // path: req.path,
137
+ // method: req.method,
138
+ // error: err.message
139
+ // });
140
+ // return next(err);
141
+ // }
142
+ // // Only use fallback for ADAPTER errors, not validation errors
143
+ // logger.warn("⚠ Primary validator adapter failed", {
144
+ // error: err?.message,
145
+ // path: req.path,
146
+ // method: req.method
147
+ // });
148
+ // if (!this.fallbackAdapter) {
149
+ // return next(new ValidationError("Validation system error"));
150
+ // }
151
+ // // Try fallback adapter
152
+ // const fallbackMiddleware = this.fallbackAdapter.validate(schema);
153
+ // fallbackMiddleware(req, res, (fallbackErr?: any) => {
154
+ // if (fallbackErr) {
155
+ // logger.error("❌ Fallback validator also failed", {
156
+ // error: fallbackErr?.message
157
+ // });
158
+ // return next(new ValidationError("Validation system unavailable"));
159
+ // }
160
+ // next(); // Fallback validation passed
161
+ // });
162
+ // });
163
+ // };
164
+ // }
165
+ // }
166
+ // src/managers/ValidatorManager.ts - COMPLETE FIXED
167
+ const logging_1 = require("../logging");
168
+ const ValidationError_js_1 = require("../core/errors/ValidationError.js");
169
+ class ValidatorManager {
170
+ constructor(config, primaryAdapter, fallbackAdapter) {
171
+ this.config = config;
172
+ this.primaryAdapter = primaryAdapter;
173
+ this.fallbackAdapter = fallbackAdapter;
174
+ }
175
+ validate(schema) {
176
+ return (req, res, next) => {
177
+ // Execute primary adapter middleware
178
+ const primaryMiddleware = this.primaryAdapter.validate(schema);
179
+ // Run middleware and handle errors properly
180
+ primaryMiddleware(req, res, (err) => {
181
+ if (!err) {
182
+ return next(); // Validation passed
183
+ }
184
+ // If error is a ValidationError, pass it through (don't fallback!)
185
+ if (err instanceof ValidationError_js_1.ValidationError) {
186
+ logging_1.logger.warn("⚠ Validation failed", {
187
+ path: req.path,
188
+ method: req.method,
189
+ error: err.message
190
+ });
191
+ return next(err);
192
+ }
193
+ // Only use fallback for ADAPTER errors, not validation errors
194
+ logging_1.logger.warn("⚠ Primary validator adapter failed", {
195
+ error: err?.message,
196
+ path: req.path,
197
+ method: req.method
198
+ });
199
+ if (!this.fallbackAdapter) {
200
+ return next(new ValidationError_js_1.ValidationError("Validation system error"));
201
+ }
202
+ // Try fallback adapter
203
+ const fallbackMiddleware = this.fallbackAdapter.validate(schema);
204
+ fallbackMiddleware(req, res, (fallbackErr) => {
205
+ if (fallbackErr) {
206
+ logging_1.logger.error("❌ Fallback validator also failed", {
207
+ error: fallbackErr?.message
208
+ });
209
+ return next(new ValidationError_js_1.ValidationError("Validation system unavailable"));
210
+ }
211
+ next(); // Fallback validation passed
212
+ });
213
+ });
214
+ };
215
+ }
216
+ }
217
+ exports.ValidatorManager = ValidatorManager;
218
+ //# sourceMappingURL=ValidatorManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidatorManager.js","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"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","sourcesContent":["// // // import { HiSecureConfig } from \"../core/config\";\r\n// // // import { logger } from \"../logging\";\r\n// // // import { ValidationError } from \"../core/errors/ValidationError\";\r\n\r\n// // // export class ValidatorManager {\r\n// // // private config: HiSecureConfig[\"validation\"];\r\n// // // private primaryAdapter: any;\r\n// // // private fallbackAdapter: any;\r\n\r\n// // // constructor(\r\n// // // config: HiSecureConfig[\"validation\"],\r\n// // // primaryAdapter: any,\r\n// // // fallbackAdapter: any\r\n// // // ) {\r\n// // // this.config = config;\r\n// // // this.primaryAdapter = primaryAdapter;\r\n// // // this.fallbackAdapter = fallbackAdapter;\r\n// // // }\r\n\r\n// // // /**\r\n// // // * Validate request body using primary adapter (Zod/express-validator).\r\n// // // * Fallback is only used if the adapter implementation itself throws.\r\n// // // */\r\n// // // validate(schema: any) {\r\n// // // return (req: any, res: any, next: any) => {\r\n// // // try {\r\n// // // const middleware = this.primaryAdapter.validate(schema);\r\n// // // return middleware(req, res, next);\r\n\r\n// // // } catch (err: any) {\r\n// // // logger.warn(\"⚠ Primary validator failed\", {\r\n// // // error: err?.message,\r\n// // // path: req.path,\r\n// // // method: req.method\r\n// // // });\r\n\r\n// // // if (!this.fallbackAdapter) {\r\n// // // return next(new ValidationError(\"Validation failed.\"));\r\n// // // }\r\n\r\n// // // try {\r\n// // // logger.info(\"📌 Using fallback validator\");\r\n// // // const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n// // // return fallbackMiddleware(req, res, next);\r\n\r\n// // // } catch (fallbackErr: any) {\r\n// // // logger.error(\"❌ Fallback validation also failed\", {\r\n// // // error: fallbackErr?.message\r\n// // // });\r\n\r\n// // // return next(new ValidationError(\"Both validators failed.\"));\r\n// // // }\r\n// // // }\r\n// // // };\r\n// // // }\r\n// // // }\r\n\r\n\r\n\r\n// // import { HiSecureConfig } from \"../core/config.js\";\r\n// // import { logger } from \"../logging\";\r\n// // import { ValidationError } from \"../core/errors/ValidationError.js\";\r\n\r\n// // interface ValidatorAdapter {\r\n// // validate: (schema?: any) => any;\r\n// // }\r\n\r\n// // export class ValidatorManager {\r\n// // private config: HiSecureConfig[\"validation\"];\r\n// // private primaryAdapter: ValidatorAdapter;\r\n// // private fallbackAdapter: ValidatorAdapter | null;\r\n\r\n// // constructor(\r\n// // config: HiSecureConfig[\"validation\"],\r\n// // primaryAdapter: ValidatorAdapter,\r\n// // fallbackAdapter: ValidatorAdapter | null\r\n// // ) {\r\n// // this.config = config;\r\n// // this.primaryAdapter = primaryAdapter;\r\n// // this.fallbackAdapter = fallbackAdapter;\r\n// // }\r\n\r\n// // /**\r\n// // * MAIN DYNAMIC VALIDATOR ENTRY\r\n// // * schema = per-route schema\r\n// // * If schema is undefined → use global schema\r\n// // */\r\n// // validate(schema?: any) {\r\n// // return (req: any, res: any, next: any) => {\r\n// // try {\r\n// // const middleware = this.primaryAdapter.validate(schema);\r\n// // return middleware(req, res, next);\r\n\r\n// // } catch (err: any) {\r\n// // logger.warn(\"⚠ Primary validator failed\", {\r\n// // error: err?.message,\r\n// // path: req.path,\r\n// // method: req.method\r\n// // });\r\n\r\n// // if (!this.fallbackAdapter) {\r\n// // return next(new ValidationError(\"Validation failed\"));\r\n// // }\r\n\r\n// // try {\r\n// // logger.info(\"📌 Using fallback validator\");\r\n// // const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n// // return fallbackMiddleware(req, res, next);\r\n\r\n// // } catch (fallbackErr: any) {\r\n// // logger.error(\"❌ Fallback validator also failed\", {\r\n// // error: fallbackErr?.message\r\n// // });\r\n\r\n// // return next(new ValidationError(\"Both validators failed\"));\r\n// // }\r\n// // }\r\n// // };\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n\r\n\r\n// // src/managers/ValidatorManager.ts - FIXED\r\n// import { logger } from \"../logging\";\r\n// import { ValidationError } from \"../core/errors/ValidationError.js\";\r\n// import { HiSecureConfig } from \"../core/types/HiSecureConfig\";\r\n\r\n// interface ValidatorAdapter {\r\n// validate: (schema?: any) => any;\r\n// }\r\n\r\n// export class ValidatorManager {\r\n// private config: HiSecureConfig[\"validation\"];\r\n// private primaryAdapter: ValidatorAdapter;\r\n// private fallbackAdapter: ValidatorAdapter | null;\r\n\r\n// constructor(\r\n// config: HiSecureConfig[\"validation\"],\r\n// primaryAdapter: ValidatorAdapter,\r\n// fallbackAdapter: ValidatorAdapter | null\r\n// ) {\r\n// this.config = config;\r\n// this.primaryAdapter = primaryAdapter;\r\n// this.fallbackAdapter = fallbackAdapter;\r\n// }\r\n\r\n// validate(schema?: any) {\r\n// return (req: any, res: any, next: any) => {\r\n// // Execute primary adapter middleware\r\n// const primaryMiddleware = this.primaryAdapter.validate(schema);\r\n \r\n// // Run middleware and handle errors properly\r\n// primaryMiddleware(req, res, (err?: any) => {\r\n// if (!err) {\r\n// return next(); // Validation passed\r\n// }\r\n \r\n// // If error is a ValidationError, pass it through (don't fallback!)\r\n// if (err instanceof ValidationError) {\r\n// logger.warn(\"⚠ Validation failed\", {\r\n// path: req.path,\r\n// method: req.method,\r\n// error: err.message\r\n// });\r\n// return next(err);\r\n// }\r\n \r\n// // Only use fallback for ADAPTER errors, not validation errors\r\n// logger.warn(\"⚠ Primary validator adapter failed\", {\r\n// error: err?.message,\r\n// path: req.path,\r\n// method: req.method\r\n// });\r\n\r\n// if (!this.fallbackAdapter) {\r\n// return next(new ValidationError(\"Validation system error\"));\r\n// }\r\n\r\n// // Try fallback adapter\r\n// const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n// fallbackMiddleware(req, res, (fallbackErr?: any) => {\r\n// if (fallbackErr) {\r\n// logger.error(\"❌ Fallback validator also failed\", {\r\n// error: fallbackErr?.message\r\n// });\r\n// return next(new ValidationError(\"Validation system unavailable\"));\r\n// }\r\n// next(); // Fallback validation passed\r\n// });\r\n// });\r\n// };\r\n// }\r\n// }\r\n\r\n\r\n// src/managers/ValidatorManager.ts - COMPLETE FIXED\r\nimport { logger } from \"../logging\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\";\r\nimport { HiSecureConfig } from \"../core/types/HiSecureConfig.js\"; // ✅ FIXED IMPORT\r\n\r\ninterface ValidatorAdapter {\r\n validate: (schema?: any) => any;\r\n}\r\n\r\nexport class ValidatorManager {\r\n private config: HiSecureConfig[\"validation\"];\r\n private primaryAdapter: ValidatorAdapter;\r\n private fallbackAdapter: ValidatorAdapter | null;\r\n\r\n constructor(\r\n config: HiSecureConfig[\"validation\"],\r\n primaryAdapter: ValidatorAdapter,\r\n fallbackAdapter: ValidatorAdapter | null\r\n ) {\r\n this.config = config;\r\n this.primaryAdapter = primaryAdapter;\r\n this.fallbackAdapter = fallbackAdapter;\r\n }\r\n\r\n validate(schema?: any) {\r\n return (req: any, res: any, next: any) => {\r\n // Execute primary adapter middleware\r\n const primaryMiddleware = this.primaryAdapter.validate(schema);\r\n \r\n // Run middleware and handle errors properly\r\n primaryMiddleware(req, res, (err?: any) => {\r\n if (!err) {\r\n return next(); // Validation passed\r\n }\r\n \r\n // If error is a ValidationError, pass it through (don't fallback!)\r\n if (err instanceof ValidationError) {\r\n logger.warn(\"⚠ Validation failed\", {\r\n path: req.path,\r\n method: req.method,\r\n error: err.message\r\n });\r\n return next(err);\r\n }\r\n \r\n // Only use fallback for ADAPTER errors, not validation errors\r\n logger.warn(\"⚠ Primary validator adapter failed\", {\r\n error: err?.message,\r\n path: req.path,\r\n method: req.method\r\n });\r\n\r\n if (!this.fallbackAdapter) {\r\n return next(new ValidationError(\"Validation system error\"));\r\n }\r\n\r\n // Try fallback adapter\r\n const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n fallbackMiddleware(req, res, (fallbackErr?: any) => {\r\n if (fallbackErr) {\r\n logger.error(\"❌ Fallback validator also failed\", {\r\n error: fallbackErr?.message\r\n });\r\n return next(new ValidationError(\"Validation system unavailable\"));\r\n }\r\n next(); // Fallback validation passed\r\n });\r\n });\r\n };\r\n }\r\n}"]}
@@ -0,0 +1,3 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ export declare function errorHandler(err: any, req: Request, res: Response, _next: NextFunction): Response<any, Record<string, any>>;
3
+ //# sourceMappingURL=errorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/middlewares/errorHandler.ts"],"names":[],"mappings":"AAmKA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAS1D,wBAAgB,YAAY,CACxB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,sCAwFtB"}