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.
Files changed (101) hide show
  1. package/dist/adapters/ArgonAdapter.js +1 -1
  2. package/dist/adapters/ArgonAdapter.js.map +1 -1
  3. package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -1
  4. package/dist/adapters/ExpressRLAdapter.js +1 -2
  5. package/dist/adapters/ExpressRLAdapter.js.map +1 -1
  6. package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -1
  7. package/dist/adapters/ExpressValidatorAdapter.js +1 -39
  8. package/dist/adapters/ExpressValidatorAdapter.js.map +1 -1
  9. package/dist/adapters/GoogleAdapter.d.ts.map +1 -1
  10. package/dist/adapters/GoogleAdapter.js +0 -101
  11. package/dist/adapters/GoogleAdapter.js.map +1 -1
  12. package/dist/adapters/JWTAdapter.d.ts.map +1 -1
  13. package/dist/adapters/JWTAdapter.js +3 -210
  14. package/dist/adapters/JWTAdapter.js.map +1 -1
  15. package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -1
  16. package/dist/adapters/RLFlexibleAdapter.js +0 -52
  17. package/dist/adapters/RLFlexibleAdapter.js.map +1 -1
  18. package/dist/adapters/SanitizeHtmlAdapter.d.ts +0 -3
  19. package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -1
  20. package/dist/adapters/SanitizeHtmlAdapter.js +2 -71
  21. package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -1
  22. package/dist/adapters/XSSAdapter.d.ts +0 -10
  23. package/dist/adapters/XSSAdapter.d.ts.map +1 -1
  24. package/dist/adapters/XSSAdapter.js +2 -19
  25. package/dist/adapters/XSSAdapter.js.map +1 -1
  26. package/dist/adapters/ZodAdapter.d.ts.map +1 -1
  27. package/dist/adapters/ZodAdapter.js +2 -6
  28. package/dist/adapters/ZodAdapter.js.map +1 -1
  29. package/dist/core/HiSecure.d.ts +0 -2
  30. package/dist/core/HiSecure.d.ts.map +1 -1
  31. package/dist/core/HiSecure.js +8 -20
  32. package/dist/core/HiSecure.js.map +1 -1
  33. package/dist/core/useSecure.d.ts +0 -3
  34. package/dist/core/useSecure.d.ts.map +1 -1
  35. package/dist/core/useSecure.js +1 -5
  36. package/dist/core/useSecure.js.map +1 -1
  37. package/dist/index.d.ts +1 -4
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +0 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/managers/AuthManager.d.ts.map +1 -1
  42. package/dist/managers/AuthManager.js +1 -89
  43. package/dist/managers/AuthManager.js.map +1 -1
  44. package/dist/managers/CorsManager.d.ts.map +1 -1
  45. package/dist/managers/CorsManager.js +1 -19
  46. package/dist/managers/CorsManager.js.map +1 -1
  47. package/dist/managers/HashManager.d.ts.map +1 -1
  48. package/dist/managers/HashManager.js +0 -243
  49. package/dist/managers/HashManager.js.map +1 -1
  50. package/dist/managers/JsonManager.d.ts.map +1 -1
  51. package/dist/managers/JsonManager.js +1 -77
  52. package/dist/managers/JsonManager.js.map +1 -1
  53. package/dist/managers/RateLimitManager.d.ts.map +1 -1
  54. package/dist/managers/RateLimitManager.js +3 -17
  55. package/dist/managers/RateLimitManager.js.map +1 -1
  56. package/dist/managers/SanitizerManager.d.ts +0 -6
  57. package/dist/managers/SanitizerManager.d.ts.map +1 -1
  58. package/dist/managers/SanitizerManager.js +1 -213
  59. package/dist/managers/SanitizerManager.js.map +1 -1
  60. package/dist/managers/ValidatorManager.d.ts.map +1 -1
  61. package/dist/managers/ValidatorManager.js +1 -109
  62. package/dist/managers/ValidatorManager.js.map +1 -1
  63. package/dist/middlewares/errorHandler.d.ts.map +1 -1
  64. package/dist/middlewares/errorHandler.js +0 -19
  65. package/dist/middlewares/errorHandler.js.map +1 -1
  66. package/dist/utils/deepFreeze.d.ts.map +1 -1
  67. package/dist/utils/deepFreeze.js +0 -25
  68. package/dist/utils/deepFreeze.js.map +1 -1
  69. package/dist/utils/deepMerge.d.ts.map +1 -1
  70. package/dist/utils/deepMerge.js +0 -26
  71. package/dist/utils/deepMerge.js.map +1 -1
  72. package/dist/utils/normalizeOptions.d.ts +1 -3
  73. package/dist/utils/normalizeOptions.d.ts.map +1 -1
  74. package/dist/utils/normalizeOptions.js +8 -9
  75. package/dist/utils/normalizeOptions.js.map +1 -1
  76. package/package.json +1 -1
  77. package/src/adapters/ArgonAdapter.ts +1 -1
  78. package/src/adapters/ExpressRLAdapter.ts +1 -2
  79. package/src/adapters/ExpressValidatorAdapter.ts +1 -54
  80. package/src/adapters/GoogleAdapter.ts +0 -129
  81. package/src/adapters/JWTAdapter.ts +5 -259
  82. package/src/adapters/RLFlexibleAdapter.ts +2 -65
  83. package/src/adapters/SanitizeHtmlAdapter.ts +3 -87
  84. package/src/adapters/XSSAdapter.ts +11 -19
  85. package/src/adapters/ZodAdapter.ts +2 -51
  86. package/src/core/HiSecure.ts +13 -24
  87. package/src/core/useSecure.ts +5 -7
  88. package/src/index.ts +4 -5
  89. package/src/managers/AuthManager.ts +5 -109
  90. package/src/managers/CorsManager.ts +1 -25
  91. package/src/managers/HashManager.ts +0 -286
  92. package/src/managers/JsonManager.ts +1 -91
  93. package/src/managers/RateLimitManager.ts +3 -262
  94. package/src/managers/SanitizerManager.ts +4 -263
  95. package/src/managers/ValidatorManager.ts +1 -135
  96. package/src/middlewares/errorHandler.ts +1 -176
  97. package/src/utils/deepFreeze.ts +0 -32
  98. package/src/utils/deepMerge.ts +0 -35
  99. package/src/utils/normalizeOptions.ts +16 -133
  100. package/src/examples/e1.ts +0 -1
  101. 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":"AA8PA,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;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,MAAM;IAoB9C;;OAEG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IACZ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;CAgE7C"}
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
- // Recursive sanitization for nested objects (optional)
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":"AAwIA,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,IAUT,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG;CA8C5C"}
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(); // no schema found
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":"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"}
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"}