hi-secure 1.0.7 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/ArgonAdapter.js +1 -1
- package/dist/adapters/ArgonAdapter.js.map +1 -1
- package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressRLAdapter.js +1 -2
- package/dist/adapters/ExpressRLAdapter.js.map +1 -1
- package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressValidatorAdapter.js +1 -39
- package/dist/adapters/ExpressValidatorAdapter.js.map +1 -1
- package/dist/adapters/GoogleAdapter.d.ts.map +1 -1
- package/dist/adapters/GoogleAdapter.js +0 -101
- package/dist/adapters/GoogleAdapter.js.map +1 -1
- package/dist/adapters/JWTAdapter.d.ts.map +1 -1
- package/dist/adapters/JWTAdapter.js +3 -210
- package/dist/adapters/JWTAdapter.js.map +1 -1
- package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -1
- package/dist/adapters/RLFlexibleAdapter.js +0 -52
- package/dist/adapters/RLFlexibleAdapter.js.map +1 -1
- package/dist/adapters/SanitizeHtmlAdapter.d.ts +0 -3
- package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -1
- package/dist/adapters/SanitizeHtmlAdapter.js +2 -71
- package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -1
- package/dist/adapters/XSSAdapter.d.ts +0 -10
- package/dist/adapters/XSSAdapter.d.ts.map +1 -1
- package/dist/adapters/XSSAdapter.js +2 -19
- package/dist/adapters/XSSAdapter.js.map +1 -1
- package/dist/adapters/ZodAdapter.d.ts.map +1 -1
- package/dist/adapters/ZodAdapter.js +2 -6
- package/dist/adapters/ZodAdapter.js.map +1 -1
- package/dist/core/HiSecure.d.ts +0 -2
- package/dist/core/HiSecure.d.ts.map +1 -1
- package/dist/core/HiSecure.js +8 -20
- package/dist/core/HiSecure.js.map +1 -1
- package/dist/core/useSecure.d.ts +0 -3
- package/dist/core/useSecure.d.ts.map +1 -1
- package/dist/core/useSecure.js +1 -5
- package/dist/core/useSecure.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/managers/AuthManager.d.ts.map +1 -1
- package/dist/managers/AuthManager.js +1 -89
- package/dist/managers/AuthManager.js.map +1 -1
- package/dist/managers/CorsManager.d.ts.map +1 -1
- package/dist/managers/CorsManager.js +1 -19
- package/dist/managers/CorsManager.js.map +1 -1
- package/dist/managers/HashManager.d.ts.map +1 -1
- package/dist/managers/HashManager.js +0 -243
- package/dist/managers/HashManager.js.map +1 -1
- package/dist/managers/JsonManager.d.ts.map +1 -1
- package/dist/managers/JsonManager.js +1 -77
- package/dist/managers/JsonManager.js.map +1 -1
- package/dist/managers/RateLimitManager.d.ts.map +1 -1
- package/dist/managers/RateLimitManager.js +3 -17
- package/dist/managers/RateLimitManager.js.map +1 -1
- package/dist/managers/SanitizerManager.d.ts +0 -6
- package/dist/managers/SanitizerManager.d.ts.map +1 -1
- package/dist/managers/SanitizerManager.js +1 -213
- package/dist/managers/SanitizerManager.js.map +1 -1
- package/dist/managers/ValidatorManager.d.ts.map +1 -1
- package/dist/managers/ValidatorManager.js +1 -109
- package/dist/managers/ValidatorManager.js.map +1 -1
- package/dist/middlewares/errorHandler.d.ts.map +1 -1
- package/dist/middlewares/errorHandler.js +0 -19
- package/dist/middlewares/errorHandler.js.map +1 -1
- package/dist/utils/deepFreeze.d.ts.map +1 -1
- package/dist/utils/deepFreeze.js +0 -25
- package/dist/utils/deepFreeze.js.map +1 -1
- package/dist/utils/deepMerge.d.ts.map +1 -1
- package/dist/utils/deepMerge.js +0 -26
- package/dist/utils/deepMerge.js.map +1 -1
- package/dist/utils/normalizeOptions.d.ts +1 -3
- package/dist/utils/normalizeOptions.d.ts.map +1 -1
- package/dist/utils/normalizeOptions.js +8 -9
- package/dist/utils/normalizeOptions.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/ArgonAdapter.ts +1 -1
- package/src/adapters/ExpressRLAdapter.ts +1 -2
- package/src/adapters/ExpressValidatorAdapter.ts +1 -54
- package/src/adapters/GoogleAdapter.ts +0 -129
- package/src/adapters/JWTAdapter.ts +5 -259
- package/src/adapters/RLFlexibleAdapter.ts +2 -65
- package/src/adapters/SanitizeHtmlAdapter.ts +3 -87
- package/src/adapters/XSSAdapter.ts +11 -19
- package/src/adapters/ZodAdapter.ts +2 -51
- package/src/core/HiSecure.ts +13 -24
- package/src/core/useSecure.ts +5 -7
- package/src/index.ts +4 -5
- package/src/managers/AuthManager.ts +5 -109
- package/src/managers/CorsManager.ts +1 -25
- package/src/managers/HashManager.ts +0 -286
- package/src/managers/JsonManager.ts +1 -91
- package/src/managers/RateLimitManager.ts +3 -262
- package/src/managers/SanitizerManager.ts +4 -263
- package/src/managers/ValidatorManager.ts +1 -135
- package/src/middlewares/errorHandler.ts +1 -176
- package/src/utils/deepFreeze.ts +0 -32
- package/src/utils/deepMerge.ts +0 -35
- package/src/utils/normalizeOptions.ts +16 -133
- package/src/examples/e1.ts +0 -1
- package/src/test/t1.ts +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimitManager.js","sourceRoot":"","sources":["../../src/managers/RateLimitManager.ts"],"names":[],"mappings":"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","sourcesContent":["\r\n\r\n// // // src/managers/RateLimitManager.ts - COMPLETE FIXED\r\n// // import { HiSecureConfig } from \"../core/types/HiSecureConfig.js\";\r\n// // import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// // import { logger } from \"../logging\";\r\n\r\n// // interface RateLimiterAdapter {\r\n// // getMiddleware: (options?: any) => any;\r\n// // }\r\n\r\n// // export class RateLimitManager {\r\n// // private config: HiSecureConfig[\"rateLimiter\"];\r\n// // private primaryAdapter: RateLimiterAdapter;\r\n// // private fallbackAdapter: RateLimiterAdapter | null;\r\n\r\n// // constructor(\r\n// // config: HiSecureConfig[\"rateLimiter\"],\r\n// // primaryAdapter: RateLimiterAdapter,\r\n// // fallbackAdapter: RateLimiterAdapter | null\r\n// // ) {\r\n// // this.config = config;\r\n// // this.primaryAdapter = primaryAdapter;\r\n// // this.fallbackAdapter = fallbackAdapter;\r\n// // }\r\n\r\n// // middleware(opts?: { mode?: \"strict\" | \"relaxed\" | \"api\"; options?: any }) {\r\n// // let finalOptions: any = {};\r\n\r\n// // // Handle presets (user cannot override these)\r\n// // if (opts?.mode === \"strict\") {\r\n// // finalOptions = {\r\n// // windowMs: 10_000,\r\n// // max: 5,\r\n// // points: 5,\r\n// // duration: 10,\r\n// // message: \"Too many requests, please slow down.\"\r\n// // };\r\n// // } else if (opts?.mode === \"relaxed\") {\r\n// // finalOptions = {\r\n// // windowMs: 60_000,\r\n// // max: 100,\r\n// // points: 100,\r\n// // duration: 60,\r\n// // message: \"Rate limit exceeded.\"\r\n// // };\r\n// // } else if (opts?.mode === \"api\") {\r\n// // finalOptions = {\r\n// // windowMs: 15 * 60 * 1000, // 15 minutes\r\n// // max: 100,\r\n// // points: 100,\r\n// // duration: 900,\r\n// // message: \"API rate limit exceeded.\"\r\n// // };\r\n// // } else {\r\n// // // Use defaults\r\n// // finalOptions = {\r\n// // windowMs: this.config.windowMs,\r\n// // max: this.config.maxRequests,\r\n// // duration: this.config.windowMs / 1000,\r\n// // points: this.config.maxRequests,\r\n// // message: this.config.message\r\n// // };\r\n// // }\r\n\r\n// // // Apply custom options WITHOUT overriding preset values\r\n// // if (opts?.options) {\r\n// // // Only allow specific overrides, not preset overrides\r\n// // const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders'];\r\n// // for (const key of allowedOverrides) {\r\n// // if (opts.options[key] !== undefined) {\r\n// // finalOptions[key] = opts.options[key];\r\n// // }\r\n// // }\r\n \r\n// // // Log if user tried to override preset\r\n// // const attemptedOverrides = Object.keys(opts.options).filter(\r\n// // k => !allowedOverrides.includes(k) && k !== 'mode'\r\n// // );\r\n// // if (attemptedOverrides.length > 0) {\r\n// // logger.warn(\"⚠ Rate limit overrides ignored\", { // ✅ FIXED: Better message\r\n// // preset: opts?.mode || 'default', // ✅ FIXED: Handle undefined\r\n// // ignoredOptions: attemptedOverrides\r\n// // });\r\n// // }\r\n// // }\r\n\r\n// // // Try primary adapter\r\n// // try {\r\n// // logger.info(\"📌 Applying rate limiting\", {\r\n// // mode: opts?.mode || 'default',\r\n// // windowMs: finalOptions.windowMs,\r\n// // max: finalOptions.max\r\n// // });\r\n \r\n// // return this.primaryAdapter.getMiddleware(finalOptions);\r\n// // } catch (err: any) {\r\n// // logger.warn(\"⚠ Primary rate limiter failed → fallback\", {\r\n// // error: err?.message\r\n// // });\r\n\r\n// // if (!this.fallbackAdapter) {\r\n// // throw new AdapterError(\"Rate limiters failed; no fallback adapter.\");\r\n// // }\r\n\r\n// // try {\r\n// // logger.info(\"📌 Using fallback rate limiter\");\r\n// // return this.fallbackAdapter.getMiddleware(finalOptions);\r\n// // } catch (fallbackErr: any) {\r\n// // logger.error(\"❌ Fallback limiter also failed\", {\r\n// // error: fallbackErr?.message\r\n// // });\r\n// // throw new AdapterError(\"Both primary and fallback limiters failed.\");\r\n// // }\r\n// // }\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n// // src/managers/RateLimitManager.ts - FIXED\r\n// import { HiSecureConfig } from \"../core/types/HiSecureConfig.js\";\r\n// import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// import { logger } from \"../logging\";\r\n\r\n// interface RateLimiterAdapter {\r\n// getMiddleware: (options?: any) => any;\r\n// }\r\n\r\n// export class RateLimitManager {\r\n// private config: HiSecureConfig[\"rateLimiter\"];\r\n// private primaryAdapter: RateLimiterAdapter;\r\n// private fallbackAdapter: RateLimiterAdapter | null;\r\n\r\n// constructor(\r\n// config: HiSecureConfig[\"rateLimiter\"],\r\n// primaryAdapter: RateLimiterAdapter,\r\n// fallbackAdapter: RateLimiterAdapter | null\r\n// ) {\r\n// this.config = config;\r\n// this.primaryAdapter = primaryAdapter;\r\n// this.fallbackAdapter = fallbackAdapter;\r\n// }\r\n\r\n// middleware(opts?: { mode?: \"strict\" | \"relaxed\" | \"api\"; options?: any }) {\r\n// let finalOptions: any = {};\r\n\r\n// // Handle presets (user cannot override these)\r\n// if (opts?.mode === \"strict\") {\r\n// finalOptions = {\r\n// windowMs: 10_000,\r\n// max: 5,\r\n// points: 5,\r\n// // ❌ REMOVED: duration: 10,\r\n// message: \"Too many requests, please slow down.\"\r\n// };\r\n// } else if (opts?.mode === \"relaxed\") {\r\n// finalOptions = {\r\n// windowMs: 60_000,\r\n// max: 100,\r\n// points: 100,\r\n// // ❌ REMOVED: duration: 60,\r\n// message: \"Rate limit exceeded.\"\r\n// };\r\n// } else if (opts?.mode === \"api\") {\r\n// finalOptions = {\r\n// windowMs: 15 * 60 * 1000, // 15 minutes\r\n// max: 100,\r\n// points: 100,\r\n// // ❌ REMOVED: duration: 900,\r\n// message: \"API rate limit exceeded.\"\r\n// };\r\n// } else {\r\n// // Use defaults\r\n// finalOptions = {\r\n// windowMs: this.config.windowMs,\r\n// max: this.config.maxRequests,\r\n// // ❌ REMOVED: duration: this.config.windowMs / 1000,\r\n// points: this.config.maxRequests,\r\n// message: this.config.message,\r\n// standardHeaders: true, // ✅ ADD\r\n// legacyHeaders: false // ✅ ADD\r\n// };\r\n// }\r\n\r\n// // Apply custom options WITHOUT overriding preset values\r\n// if (opts?.options) {\r\n// // Only allow specific overrides, not preset overrides\r\n// const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders', 'legacyHeaders'];\r\n// for (const key of allowedOverrides) {\r\n// if (opts.options[key] !== undefined) {\r\n// finalOptions[key] = opts.options[key];\r\n// }\r\n// }\r\n \r\n// // Log if user tried to override preset\r\n// const attemptedOverrides = Object.keys(opts.options).filter(\r\n// k => !allowedOverrides.includes(k) && k !== 'mode'\r\n// );\r\n// if (attemptedOverrides.length > 0) {\r\n// logger.warn(\"⚠ Rate limit overrides ignored\", {\r\n// preset: opts?.mode || 'default',\r\n// ignoredOptions: attemptedOverrides\r\n// });\r\n// }\r\n// }\r\n\r\n// // Add v8+ options if not present\r\n// if (finalOptions.standardHeaders === undefined) {\r\n// finalOptions.standardHeaders = true;\r\n// }\r\n// if (finalOptions.legacyHeaders === undefined) {\r\n// finalOptions.legacyHeaders = false;\r\n// }\r\n\r\n// // Try primary adapter\r\n// try {\r\n// logger.info(\"📌 Applying rate limiting\", {\r\n// mode: opts?.mode || 'default',\r\n// windowMs: finalOptions.windowMs,\r\n// max: finalOptions.max\r\n// });\r\n \r\n// return this.primaryAdapter.getMiddleware(finalOptions);\r\n// } catch (err: any) {\r\n// logger.warn(\"⚠ Primary rate limiter failed → fallback\", {\r\n// error: err?.message\r\n// });\r\n\r\n// if (!this.fallbackAdapter) {\r\n// throw new AdapterError(\"Rate limiters failed; no fallback adapter.\");\r\n// }\r\n\r\n// try {\r\n// logger.info(\"📌 Using fallback rate limiter\");\r\n// return this.fallbackAdapter.getMiddleware(finalOptions);\r\n// } catch (fallbackErr: any) {\r\n// logger.error(\"❌ Fallback limiter also failed\", {\r\n// error: fallbackErr?.message\r\n// });\r\n// throw new AdapterError(\"Both primary and fallback limiters failed.\");\r\n// }\r\n// }\r\n// }\r\n// }\r\n\r\n\r\n\r\n// src/managers/RateLimitManager.ts - COMPLETELY FIXED\r\nimport { HiSecureConfig } from \"../core/types/HiSecureConfig.js\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logger } from \"../logging\";\r\n\r\ninterface RateLimiterAdapter {\r\n getMiddleware: (options?: any) => any;\r\n}\r\n\r\nexport class RateLimitManager {\r\n private config: HiSecureConfig[\"rateLimiter\"];\r\n private primaryAdapter: RateLimiterAdapter;\r\n private fallbackAdapter: RateLimiterAdapter | null;\r\n\r\n constructor(\r\n config: HiSecureConfig[\"rateLimiter\"],\r\n primaryAdapter: RateLimiterAdapter,\r\n fallbackAdapter: RateLimiterAdapter | null\r\n ) {\r\n this.config = config;\r\n this.primaryAdapter = primaryAdapter;\r\n this.fallbackAdapter = fallbackAdapter;\r\n }\r\n\r\n middleware(opts?: { mode?: \"strict\" | \"relaxed\" | \"api\"; options?: any }) {\r\n let finalOptions: any = {};\r\n\r\n // Handle presets (user cannot override these)\r\n if (opts?.mode === \"strict\") {\r\n finalOptions = {\r\n windowMs: 10_000,\r\n max: 5,\r\n // ❌ REMOVED: points: 5,\r\n message: \"Too many requests, please slow down.\"\r\n };\r\n } else if (opts?.mode === \"relaxed\") {\r\n finalOptions = {\r\n windowMs: 60_000,\r\n max: 100,\r\n // ❌ REMOVED: points: 100,\r\n message: \"Rate limit exceeded.\"\r\n };\r\n } else if (opts?.mode === \"api\") {\r\n finalOptions = {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n max: 100,\r\n // ❌ REMOVED: points: 100,\r\n message: \"API rate limit exceeded.\"\r\n };\r\n } else {\r\n // Use defaults\r\n finalOptions = {\r\n windowMs: this.config.windowMs,\r\n max: this.config.maxRequests,\r\n message: this.config.message,\r\n standardHeaders: true, // ✅ ADD\r\n legacyHeaders: false // ✅ ADD\r\n };\r\n }\r\n\r\n // Apply custom options WITHOUT overriding preset values\r\n if (opts?.options) {\r\n // Only allow specific overrides, not preset overrides\r\n const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders', 'legacyHeaders'];\r\n for (const key of allowedOverrides) {\r\n if (opts.options[key] !== undefined) {\r\n finalOptions[key] = opts.options[key];\r\n }\r\n }\r\n \r\n // Log if user tried to override preset\r\n const attemptedOverrides = Object.keys(opts.options).filter(\r\n k => !allowedOverrides.includes(k) && k !== 'mode'\r\n );\r\n if (attemptedOverrides.length > 0) {\r\n logger.warn(\"⚠ Rate limit overrides ignored\", {\r\n preset: opts?.mode || 'default',\r\n ignoredOptions: attemptedOverrides\r\n });\r\n }\r\n }\r\n\r\n // Add v8+ options if not present\r\n if (finalOptions.standardHeaders === undefined) {\r\n finalOptions.standardHeaders = true;\r\n }\r\n if (finalOptions.legacyHeaders === undefined) {\r\n finalOptions.legacyHeaders = false;\r\n }\r\n\r\n // Try primary adapter\r\n try {\r\n logger.info(\"📌 Applying rate limiting\", {\r\n mode: opts?.mode || 'default',\r\n windowMs: finalOptions.windowMs,\r\n max: finalOptions.max\r\n });\r\n \r\n return this.primaryAdapter.getMiddleware(finalOptions);\r\n } catch (err: any) {\r\n logger.warn(\"⚠ Primary rate limiter failed → fallback\", {\r\n error: err?.message\r\n });\r\n\r\n if (!this.fallbackAdapter) {\r\n throw new AdapterError(\"Rate limiters failed; no fallback adapter.\");\r\n }\r\n\r\n try {\r\n logger.info(\"📌 Using fallback rate limiter\");\r\n return this.fallbackAdapter.getMiddleware(finalOptions);\r\n } catch (fallbackErr: any) {\r\n logger.error(\"❌ Fallback limiter also failed\", {\r\n error: fallbackErr?.message\r\n });\r\n throw new AdapterError(\"Both primary and fallback limiters failed.\");\r\n }\r\n }\r\n }\r\n}"]}
|
|
1
|
+
{"version":3,"file":"RateLimitManager.js","sourceRoot":"","sources":["../../src/managers/RateLimitManager.ts"],"names":[],"mappings":";;;AACA,oEAA8D;AAC9D,wCAAoC;AAMpC,MAAa,gBAAgB;IAKzB,YACI,MAAqC,EACrC,cAAkC,EAClC,eAA0C;QAE1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IAC3C,CAAC;IAED,UAAU,CAAC,IAA6D;QACpE,IAAI,YAAY,GAAQ,EAAE,CAAC;QAE3B,IAAI,IAAI,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,YAAY,GAAG;gBACX,QAAQ,EAAE,KAAM;gBAChB,GAAG,EAAE,CAAC;gBACN,OAAO,EAAE,sCAAsC;aAClD,CAAC;QACN,CAAC;aAAM,IAAI,IAAI,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;YAClC,YAAY,GAAG;gBACX,QAAQ,EAAE,KAAM;gBAChB,GAAG,EAAE,GAAG;gBACR,OAAO,EAAE,sBAAsB;aAClC,CAAC;QACN,CAAC;aAAM,IAAI,IAAI,EAAE,IAAI,KAAK,KAAK,EAAE,CAAC;YAC9B,YAAY,GAAG;gBACX,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;gBACxB,GAAG,EAAE,GAAG;gBACR,OAAO,EAAE,0BAA0B;aACtC,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,YAAY,GAAG;gBACX,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAC9B,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;gBAC5B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;gBAC5B,eAAe,EAAE,IAAI;gBACrB,aAAa,EAAE,KAAK;aACvB,CAAC;QACN,CAAC;QAED,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC;YAChB,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;YAC/F,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;gBACjC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;oBAClC,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAC1C,CAAC;YACL,CAAC;YAED,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CACvD,CAAC,CAAC,EAAE,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,CACrD,CAAC;YACF,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,gBAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE;oBAC1C,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,SAAS;oBAC/B,cAAc,EAAE,kBAAkB;iBACrC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAED,IAAI,YAAY,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YAC7C,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;QACxC,CAAC;QACD,IAAI,YAAY,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YAC3C,YAAY,CAAC,aAAa,GAAG,KAAK,CAAC;QACvC,CAAC;QAED,IAAI,CAAC;YACD,gBAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;gBACrC,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,SAAS;gBAC7B,QAAQ,EAAE,YAAY,CAAC,QAAQ;gBAC/B,GAAG,EAAE,YAAY,CAAC,GAAG;aACxB,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,gBAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;gBACpD,KAAK,EAAE,GAAG,EAAE,OAAO;aACtB,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;gBACxB,MAAM,IAAI,8BAAY,CAAC,4CAA4C,CAAC,CAAC;YACzE,CAAC;YAED,IAAI,CAAC;gBACD,gBAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;gBAC9C,OAAO,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,WAAgB,EAAE,CAAC;gBACxB,gBAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE;oBAC3C,KAAK,EAAE,WAAW,EAAE,OAAO;iBAC9B,CAAC,CAAC;gBACH,MAAM,IAAI,8BAAY,CAAC,4CAA4C,CAAC,CAAC;YACzE,CAAC;QACL,CAAC;IACL,CAAC;CACJ;AApGD,4CAoGC","sourcesContent":["import { HiSecureConfig } from \"../core/types/HiSecureConfig.js\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logger } from \"../logging\";\r\n\r\ninterface RateLimiterAdapter {\r\n getMiddleware: (options?: any) => any;\r\n}\r\n\r\nexport class RateLimitManager {\r\n private config: HiSecureConfig[\"rateLimiter\"];\r\n private primaryAdapter: RateLimiterAdapter;\r\n private fallbackAdapter: RateLimiterAdapter | null;\r\n\r\n constructor(\r\n config: HiSecureConfig[\"rateLimiter\"],\r\n primaryAdapter: RateLimiterAdapter,\r\n fallbackAdapter: RateLimiterAdapter | null\r\n ) {\r\n this.config = config;\r\n this.primaryAdapter = primaryAdapter;\r\n this.fallbackAdapter = fallbackAdapter;\r\n }\r\n\r\n middleware(opts?: { mode?: \"strict\" | \"relaxed\" | \"api\"; options?: any }) {\r\n let finalOptions: any = {};\r\n\r\n if (opts?.mode === \"strict\") {\r\n finalOptions = {\r\n windowMs: 10_000,\r\n max: 5,\r\n message: \"Too many requests, please slow down.\"\r\n };\r\n } else if (opts?.mode === \"relaxed\") {\r\n finalOptions = {\r\n windowMs: 60_000,\r\n max: 100,\r\n message: \"Rate limit exceeded.\"\r\n };\r\n } else if (opts?.mode === \"api\") {\r\n finalOptions = {\r\n windowMs: 15 * 60 * 1000, \r\n max: 100,\r\n message: \"API rate limit exceeded.\"\r\n };\r\n } else {\r\n finalOptions = {\r\n windowMs: this.config.windowMs,\r\n max: this.config.maxRequests,\r\n message: this.config.message,\r\n standardHeaders: true, \r\n legacyHeaders: false \r\n };\r\n }\r\n\r\n if (opts?.options) {\r\n const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders', 'legacyHeaders'];\r\n for (const key of allowedOverrides) {\r\n if (opts.options[key] !== undefined) {\r\n finalOptions[key] = opts.options[key];\r\n }\r\n }\r\n \r\n const attemptedOverrides = Object.keys(opts.options).filter(\r\n k => !allowedOverrides.includes(k) && k !== 'mode'\r\n );\r\n if (attemptedOverrides.length > 0) {\r\n logger.warn(\"⚠ Rate limit overrides ignored\", {\r\n preset: opts?.mode || 'default',\r\n ignoredOptions: attemptedOverrides\r\n });\r\n }\r\n }\r\n\r\n if (finalOptions.standardHeaders === undefined) {\r\n finalOptions.standardHeaders = true;\r\n }\r\n if (finalOptions.legacyHeaders === undefined) {\r\n finalOptions.legacyHeaders = false;\r\n }\r\n\r\n try {\r\n logger.info(\"📌 Applying rate limiting\", {\r\n mode: opts?.mode || 'default',\r\n windowMs: finalOptions.windowMs,\r\n max: finalOptions.max\r\n });\r\n \r\n return this.primaryAdapter.getMiddleware(finalOptions);\r\n } catch (err: any) {\r\n logger.warn(\"⚠ Primary rate limiter failed → fallback\", {\r\n error: err?.message\r\n });\r\n\r\n if (!this.fallbackAdapter) {\r\n throw new AdapterError(\"Rate limiters failed; no fallback adapter.\");\r\n }\r\n\r\n try {\r\n logger.info(\"📌 Using fallback rate limiter\");\r\n return this.fallbackAdapter.getMiddleware(finalOptions);\r\n } catch (fallbackErr: any) {\r\n logger.error(\"❌ Fallback limiter also failed\", {\r\n error: fallbackErr?.message\r\n });\r\n throw new AdapterError(\"Both primary and fallback limiters failed.\");\r\n }\r\n }\r\n }\r\n}"]}
|
|
@@ -5,13 +5,7 @@ export declare class SanitizerManager {
|
|
|
5
5
|
private primary;
|
|
6
6
|
private fallback;
|
|
7
7
|
constructor(primary: SanitizerAdapter, fallback?: SanitizerAdapter | null);
|
|
8
|
-
/**
|
|
9
|
-
* Sanitize a single value (public API)
|
|
10
|
-
*/
|
|
11
8
|
sanitize(value: string, options?: any): string;
|
|
12
|
-
/**
|
|
13
|
-
* Middleware - Per-request fallback logic
|
|
14
|
-
*/
|
|
15
9
|
middleware(options?: any): (req: any, _res: any, next: any) => void;
|
|
16
10
|
}
|
|
17
11
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SanitizerManager.d.ts","sourceRoot":"","sources":["../../src/managers/SanitizerManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SanitizerManager.d.ts","sourceRoot":"","sources":["../../src/managers/SanitizerManager.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,MAAM,CAAC;CACtD;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,QAAQ,CAA0B;gBAE9B,OAAO,EAAE,gBAAgB,EAAE,QAAQ,GAAE,gBAAgB,GAAG,IAAW;IAK/E,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,MAAM;IAqB9C,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IACZ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;CA6D7C"}
|
|
@@ -1,207 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// // // import { SanitizerError } from "../core/errors/SanitizerError";
|
|
3
|
-
// // // import { logger } from "../logging";
|
|
4
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
3
|
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
4
|
const SanitizerError_js_1 = require("../core/errors/SanitizerError.js");
|
|
206
5
|
const logging_1 = require("../logging");
|
|
207
6
|
class SanitizerManager {
|
|
@@ -209,11 +8,7 @@ class SanitizerManager {
|
|
|
209
8
|
this.primary = primary;
|
|
210
9
|
this.fallback = fallback;
|
|
211
10
|
}
|
|
212
|
-
/**
|
|
213
|
-
* Sanitize a single value (public API)
|
|
214
|
-
*/
|
|
215
11
|
sanitize(value, options) {
|
|
216
|
-
// Don't process non-strings
|
|
217
12
|
if (typeof value !== 'string') {
|
|
218
13
|
return value;
|
|
219
14
|
}
|
|
@@ -229,13 +24,9 @@ class SanitizerManager {
|
|
|
229
24
|
return this.fallback.sanitize(value, options);
|
|
230
25
|
}
|
|
231
26
|
}
|
|
232
|
-
/**
|
|
233
|
-
* Middleware - Per-request fallback logic
|
|
234
|
-
*/
|
|
235
27
|
middleware(options) {
|
|
236
28
|
return (req, _res, next) => {
|
|
237
29
|
let fallbackTriggered = false;
|
|
238
|
-
// Helper function with per-request fallback logic
|
|
239
30
|
const safeSanitize = (value) => {
|
|
240
31
|
if (fallbackTriggered && this.fallback) {
|
|
241
32
|
return this.fallback.sanitize(value, options);
|
|
@@ -253,7 +44,6 @@ class SanitizerManager {
|
|
|
253
44
|
}
|
|
254
45
|
};
|
|
255
46
|
try {
|
|
256
|
-
// Create a sanitized copy of body instead of mutating
|
|
257
47
|
if (req.body && typeof req.body === "object") {
|
|
258
48
|
const originalBody = req.body;
|
|
259
49
|
const sanitizedBody = Array.isArray(originalBody) ? [] : {};
|
|
@@ -266,14 +56,12 @@ class SanitizerManager {
|
|
|
266
56
|
sanitizedBody[key] = value.map(item => typeof item === "string" ? safeSanitize(item) : item);
|
|
267
57
|
}
|
|
268
58
|
else if (value && typeof value === "object") {
|
|
269
|
-
|
|
270
|
-
sanitizedBody[key] = value; // Keep as-is for now
|
|
59
|
+
sanitizedBody[key] = value;
|
|
271
60
|
}
|
|
272
61
|
else {
|
|
273
62
|
sanitizedBody[key] = value;
|
|
274
63
|
}
|
|
275
64
|
}
|
|
276
|
-
// Store sanitized version separately
|
|
277
65
|
req.sanitizedBody = sanitizedBody;
|
|
278
66
|
logging_1.logger.debug("🧼 Request body sanitized", {
|
|
279
67
|
originalKeys: Object.keys(originalBody),
|
|
@@ -1 +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}"]}
|
|
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.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 sanitize(value: string, options?: any): string {\r\n \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(options?: any) {\r\n return (req: any, _res: any, next: any) => {\r\n let fallbackTriggered = false;\r\n \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 \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 sanitizedBody[key] = value; \r\n } else {\r\n sanitizedBody[key] = value;\r\n }\r\n }\r\n \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}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValidatorManager.d.ts","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ValidatorManager.d.ts","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"AAGA,UAAU,gBAAgB;IACtB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,cAAc,CAAmB;gBAE7B,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB;IAK1E,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,IAST,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG;CA8C5C"}
|
|
@@ -1,113 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// // src/managers/ValidatorManager.ts - COMPLETE FIXED
|
|
3
|
-
// import { logger } from "../logging";
|
|
4
|
-
// import { ValidationError } from "../core/errors/ValidationError.js";
|
|
5
|
-
// import { HiSecureConfig } from "../core/types/HiSecureConfig.js"; // ✅ FIXED IMPORT
|
|
6
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
3
|
exports.ValidatorManager = void 0;
|
|
8
|
-
// interface ValidatorAdapter {
|
|
9
|
-
// validate: (schema?: any) => any;
|
|
10
|
-
// }
|
|
11
|
-
// export class ValidatorManager {
|
|
12
|
-
// private config: HiSecureConfig["validation"];
|
|
13
|
-
// private primaryAdapter: ValidatorAdapter;
|
|
14
|
-
// private fallbackAdapter: ValidatorAdapter | null;
|
|
15
|
-
// constructor(
|
|
16
|
-
// config: HiSecureConfig["validation"],
|
|
17
|
-
// primaryAdapter: ValidatorAdapter,
|
|
18
|
-
// fallbackAdapter: ValidatorAdapter | null
|
|
19
|
-
// ) {
|
|
20
|
-
// this.config = config;
|
|
21
|
-
// this.primaryAdapter = primaryAdapter;
|
|
22
|
-
// this.fallbackAdapter = fallbackAdapter;
|
|
23
|
-
// }
|
|
24
|
-
// validate(schema?: any) {
|
|
25
|
-
// return (req: any, res: any, next: any) => {
|
|
26
|
-
// // Execute primary adapter middleware
|
|
27
|
-
// const primaryMiddleware = this.primaryAdapter.validate(schema);
|
|
28
|
-
// // Run middleware and handle errors properly
|
|
29
|
-
// primaryMiddleware(req, res, (err?: any) => {
|
|
30
|
-
// if (!err) {
|
|
31
|
-
// return next(); // Validation passed
|
|
32
|
-
// }
|
|
33
|
-
// // If error is a ValidationError, pass it through (don't fallback!)
|
|
34
|
-
// if (err instanceof ValidationError) {
|
|
35
|
-
// logger.warn("⚠ Validation failed", {
|
|
36
|
-
// path: req.path,
|
|
37
|
-
// method: req.method,
|
|
38
|
-
// error: err.message
|
|
39
|
-
// });
|
|
40
|
-
// return next(err);
|
|
41
|
-
// }
|
|
42
|
-
// // Only use fallback for ADAPTER errors, not validation errors
|
|
43
|
-
// logger.warn("⚠ Primary validator adapter failed", {
|
|
44
|
-
// error: err?.message,
|
|
45
|
-
// path: req.path,
|
|
46
|
-
// method: req.method
|
|
47
|
-
// });
|
|
48
|
-
// if (!this.fallbackAdapter) {
|
|
49
|
-
// return next(new ValidationError("Validation system error"));
|
|
50
|
-
// }
|
|
51
|
-
// // Try fallback adapter
|
|
52
|
-
// const fallbackMiddleware = this.fallbackAdapter.validate(schema);
|
|
53
|
-
// fallbackMiddleware(req, res, (fallbackErr?: any) => {
|
|
54
|
-
// if (fallbackErr) {
|
|
55
|
-
// logger.error("❌ Fallback validator also failed", {
|
|
56
|
-
// error: fallbackErr?.message
|
|
57
|
-
// });
|
|
58
|
-
// return next(new ValidationError("Validation system unavailable"));
|
|
59
|
-
// }
|
|
60
|
-
// next(); // Fallback validation passed
|
|
61
|
-
// });
|
|
62
|
-
// });
|
|
63
|
-
// };
|
|
64
|
-
// }
|
|
65
|
-
// }
|
|
66
|
-
// // src/managers/ValidatorManager.ts
|
|
67
|
-
// import { logger } from "../logging";
|
|
68
|
-
// import { ValidationError } from "../core/errors/ValidationError.js";
|
|
69
|
-
// interface ValidatorAdapter {
|
|
70
|
-
// validate: (schema?: any) => any;
|
|
71
|
-
// }
|
|
72
|
-
// export class ValidatorManager {
|
|
73
|
-
// private primaryAdapter: ValidatorAdapter;
|
|
74
|
-
// private fallbackAdapter: ValidatorAdapter | null;
|
|
75
|
-
// constructor(primaryAdapter: ValidatorAdapter, fallbackAdapter: ValidatorAdapter | null) {
|
|
76
|
-
// this.primaryAdapter = primaryAdapter;
|
|
77
|
-
// this.fallbackAdapter = fallbackAdapter;
|
|
78
|
-
// }
|
|
79
|
-
// validate(schema?: any) {
|
|
80
|
-
// return (req: any, res: any, next: any) => {
|
|
81
|
-
// const isZod = schema && typeof schema === "object" && typeof schema.safeParse === "function";
|
|
82
|
-
// const isExpressValidator = Array.isArray(schema);
|
|
83
|
-
// let adapter: ValidatorAdapter;
|
|
84
|
-
// if (isZod) {
|
|
85
|
-
// adapter = this.primaryAdapter; // ZodAdapter
|
|
86
|
-
// logger.debug("📌 Using Zod adapter for validation");
|
|
87
|
-
// }
|
|
88
|
-
// else if (isExpressValidator) {
|
|
89
|
-
// adapter = this.fallbackAdapter!; // ExpressValidatorAdapter
|
|
90
|
-
// logger.debug("📌 Using express-validator adapter for validation");
|
|
91
|
-
// }
|
|
92
|
-
// else {
|
|
93
|
-
// return next(); // nothing to validate
|
|
94
|
-
// }
|
|
95
|
-
// const middleware = adapter.validate(schema);
|
|
96
|
-
// // Execute validation chain
|
|
97
|
-
// middleware(req, res, (err?: any) => {
|
|
98
|
-
// if (err instanceof ValidationError) {
|
|
99
|
-
// return next(err);
|
|
100
|
-
// }
|
|
101
|
-
// if (err) {
|
|
102
|
-
// logger.error("❌ Validator internal error", { error: err.message });
|
|
103
|
-
// return next(new ValidationError("Validation failed internally."));
|
|
104
|
-
// }
|
|
105
|
-
// next();
|
|
106
|
-
// });
|
|
107
|
-
// };
|
|
108
|
-
// }
|
|
109
|
-
// }
|
|
110
|
-
// src/managers/ValidatorManager.ts
|
|
111
4
|
const logging_1 = require("../logging");
|
|
112
5
|
const ValidationError_js_1 = require("../core/errors/ValidationError.js");
|
|
113
6
|
class ValidatorManager {
|
|
@@ -116,7 +9,6 @@ class ValidatorManager {
|
|
|
116
9
|
this.expressAdapter = expressAdapter;
|
|
117
10
|
}
|
|
118
11
|
validate(schema) {
|
|
119
|
-
// const isZod = schema && typeof schema.safeParse === "function";
|
|
120
12
|
const isZod = schema &&
|
|
121
13
|
typeof schema === "object" &&
|
|
122
14
|
typeof schema._def === "object" &&
|
|
@@ -133,7 +25,7 @@ class ValidatorManager {
|
|
|
133
25
|
middleware = this.expressAdapter.validate(schema);
|
|
134
26
|
}
|
|
135
27
|
else {
|
|
136
|
-
return next();
|
|
28
|
+
return next();
|
|
137
29
|
}
|
|
138
30
|
// CASE 1 — express-validator returns ARRAY
|
|
139
31
|
if (Array.isArray(middleware)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValidatorManager.js","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"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","sourcesContent":["// // src/managers/ValidatorManager.ts - COMPLETE FIXED\r\n// import { logger } from \"../logging\";\r\n// import { ValidationError } from \"../core/errors/ValidationError.js\";\r\n// import { HiSecureConfig } from \"../core/types/HiSecureConfig.js\"; // ✅ FIXED IMPORT\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\r\n\r\n// // src/managers/ValidatorManager.ts\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 primaryAdapter: ValidatorAdapter;\r\n// private fallbackAdapter: ValidatorAdapter | null;\r\n\r\n// constructor(primaryAdapter: ValidatorAdapter, fallbackAdapter: ValidatorAdapter | null) {\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// const isZod = schema && typeof schema === \"object\" && typeof schema.safeParse === \"function\";\r\n// const isExpressValidator = Array.isArray(schema);\r\n\r\n// let adapter: ValidatorAdapter;\r\n\r\n// if (isZod) {\r\n// adapter = this.primaryAdapter; // ZodAdapter\r\n// logger.debug(\"📌 Using Zod adapter for validation\");\r\n// } \r\n// else if (isExpressValidator) {\r\n// adapter = this.fallbackAdapter!; // ExpressValidatorAdapter\r\n// logger.debug(\"📌 Using express-validator adapter for validation\");\r\n// } \r\n// else {\r\n// return next(); // nothing to validate\r\n// }\r\n\r\n// const middleware = adapter.validate(schema);\r\n\r\n// // Execute validation chain\r\n// middleware(req, res, (err?: any) => {\r\n// if (err instanceof ValidationError) {\r\n// return next(err);\r\n// }\r\n// if (err) {\r\n// logger.error(\"❌ Validator internal error\", { error: err.message });\r\n// return next(new ValidationError(\"Validation failed internally.\"));\r\n// }\r\n// next();\r\n// });\r\n// };\r\n// }\r\n// }\r\n\r\n\r\n\r\n\r\n\r\n// src/managers/ValidatorManager.ts\r\nimport { logger } from \"../logging\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\";\r\n\r\ninterface ValidatorAdapter {\r\n validate: (schema?: any) => any;\r\n}\r\n\r\nexport class ValidatorManager {\r\n private zodAdapter: ValidatorAdapter;\r\n private expressAdapter: ValidatorAdapter;\r\n\r\n constructor(zodAdapter: ValidatorAdapter, expressAdapter: ValidatorAdapter) {\r\n this.zodAdapter = zodAdapter;\r\n this.expressAdapter = expressAdapter;\r\n }\r\n\r\n validate(schema?: any) {\r\n // const isZod = schema && typeof schema.safeParse === \"function\";\r\n const isZod =\r\n schema &&\r\n typeof schema === \"object\" &&\r\n typeof schema._def === \"object\" && \r\n typeof schema.safeParse === \"function\";\r\n\r\n const isExpressValidator = Array.isArray(schema);\r\n\r\n return (req: any, res: any, next: any) => {\r\n let middleware;\r\n\r\n if (isZod) {\r\n logger.debug(\"📌 Using Zod adapter\");\r\n middleware = this.zodAdapter.validate(schema);\r\n } \r\n else if (isExpressValidator) {\r\n logger.debug(\"📌 Using express-validator adapter\");\r\n middleware = this.expressAdapter.validate(schema);\r\n } \r\n else {\r\n return next(); // no schema found\r\n }\r\n\r\n // CASE 1 — express-validator returns ARRAY\r\n if (Array.isArray(middleware)) {\r\n let idx = 0;\r\n\r\n const run = (err?: any) => {\r\n if (err) return next(err);\r\n\r\n const fn = middleware[idx++];\r\n if (!fn) return next(); // done\r\n\r\n try {\r\n fn(req, res, run);\r\n } catch (error: any) {\r\n next(new ValidationError(error.message));\r\n }\r\n };\r\n\r\n return run();\r\n }\r\n\r\n // CASE 2 — Zod returns SINGLE MIDDLEWARE\r\n try {\r\n middleware(req, res, (err?: any) => {\r\n if (err) return next(err);\r\n next();\r\n });\r\n } catch (err: any) {\r\n next(new ValidationError(err.message));\r\n }\r\n };\r\n }\r\n}\r\n\r\n"]}
|
|
1
|
+
{"version":3,"file":"ValidatorManager.js","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":";;;AAAA,wCAAoC;AACpC,0EAAoE;AAMpE,MAAa,gBAAgB;IAIzB,YAAY,UAA4B,EAAE,cAAgC;QACtE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACzC,CAAC;IAED,QAAQ,CAAC,MAAY;QACjB,MAAM,KAAK,GACf,MAAM;YACN,OAAO,MAAM,KAAK,QAAQ;YAC1B,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;YAC/B,OAAO,MAAM,CAAC,SAAS,KAAK,UAAU,CAAC;QAEnC,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjD,OAAO,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;YACrC,IAAI,UAAU,CAAC;YAEf,IAAI,KAAK,EAAE,CAAC;gBACR,gBAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;gBACrC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAClD,CAAC;iBACI,IAAI,kBAAkB,EAAE,CAAC;gBAC1B,gBAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBACnD,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACtD,CAAC;iBACI,CAAC;gBACF,OAAO,IAAI,EAAE,CAAC;YAClB,CAAC;YAED,2CAA2C;YAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC5B,IAAI,GAAG,GAAG,CAAC,CAAC;gBAEZ,MAAM,GAAG,GAAG,CAAC,GAAS,EAAE,EAAE;oBACtB,IAAI,GAAG;wBAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;oBAE1B,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;oBAC7B,IAAI,CAAC,EAAE;wBAAE,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO;oBAE/B,IAAI,CAAC;wBACD,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;oBACtB,CAAC;oBAAC,OAAO,KAAU,EAAE,CAAC;wBAClB,IAAI,CAAC,IAAI,oCAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC7C,CAAC;gBACL,CAAC,CAAC;gBAEF,OAAO,GAAG,EAAE,CAAC;YACjB,CAAC;YAED,yCAAyC;YACzC,IAAI,CAAC;gBACD,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAS,EAAE,EAAE;oBAC/B,IAAI,GAAG;wBAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC1B,IAAI,EAAE,CAAC;gBACX,CAAC,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,IAAI,CAAC,IAAI,oCAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3C,CAAC;QACL,CAAC,CAAC;IACN,CAAC;CACJ;AAhED,4CAgEC","sourcesContent":["import { logger } from \"../logging\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\";\r\n\r\ninterface ValidatorAdapter {\r\n validate: (schema?: any) => any;\r\n}\r\n\r\nexport class ValidatorManager {\r\n private zodAdapter: ValidatorAdapter;\r\n private expressAdapter: ValidatorAdapter;\r\n\r\n constructor(zodAdapter: ValidatorAdapter, expressAdapter: ValidatorAdapter) {\r\n this.zodAdapter = zodAdapter;\r\n this.expressAdapter = expressAdapter;\r\n }\r\n\r\n validate(schema?: any) {\r\n const isZod =\r\n schema &&\r\n typeof schema === \"object\" &&\r\n typeof schema._def === \"object\" && \r\n typeof schema.safeParse === \"function\";\r\n\r\n const isExpressValidator = Array.isArray(schema);\r\n\r\n return (req: any, res: any, next: any) => {\r\n let middleware;\r\n\r\n if (isZod) {\r\n logger.debug(\"📌 Using Zod adapter\");\r\n middleware = this.zodAdapter.validate(schema);\r\n } \r\n else if (isExpressValidator) {\r\n logger.debug(\"📌 Using express-validator adapter\");\r\n middleware = this.expressAdapter.validate(schema);\r\n } \r\n else {\r\n return next(); \r\n }\r\n\r\n // CASE 1 — express-validator returns ARRAY\r\n if (Array.isArray(middleware)) {\r\n let idx = 0;\r\n\r\n const run = (err?: any) => {\r\n if (err) return next(err);\r\n\r\n const fn = middleware[idx++];\r\n if (!fn) return next(); // done\r\n\r\n try {\r\n fn(req, res, run);\r\n } catch (error: any) {\r\n next(new ValidationError(error.message));\r\n }\r\n };\r\n\r\n return run();\r\n }\r\n\r\n // CASE 2 — Zod returns SINGLE MIDDLEWARE\r\n try {\r\n middleware(req, res, (err?: any) => {\r\n if (err) return next(err);\r\n next();\r\n });\r\n } catch (err: any) {\r\n next(new ValidationError(err.message));\r\n }\r\n };\r\n }\r\n}\r\n\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/middlewares/errorHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/middlewares/errorHandler.ts"],"names":[],"mappings":"AAAA,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,sCA4EtB"}
|