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,56 +1,6 @@
1
1
  "use strict";
2
- // import { RateLimiterMemory, RateLimiterRes } from "rate-limiter-flexible";
3
- // import { logger } from "../logging";
4
- // import { AdapterError } from "../core/errors/AdapterError";
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.RLFlexibleAdapter = void 0;
7
- // export class RLFlexibleAdapter {
8
- // /**
9
- // * Create middleware dynamically using options.
10
- // */
11
- // getMiddleware(options: {
12
- // points?: number;
13
- // duration?: number; // seconds
14
- // message?: any;
15
- // } = {}) {
16
- // try {
17
- // const limiter = new RateLimiterMemory({
18
- // points: options.points ?? 100,
19
- // duration: options.duration ?? 60,
20
- // });
21
- // return async (req: any, res: any, next: any) => {
22
- // const ip = req.ip ||
23
- // req.headers["x-forwarded-for"] ||
24
- // req.connection?.remoteAddress ||
25
- // "unknown";
26
- // try {
27
- // await limiter.consume(ip);
28
- // next();
29
- // } catch (err: any) {
30
- // const rlErr = err as RateLimiterRes;
31
- // logger.warn("⚠ RLFlexibleAdapter: rate limit exceeded", {
32
- // ip,
33
- // path: req.path,
34
- // method: req.method,
35
- // retryAfter: rlErr.msBeforeNext
36
- // });
37
- // return res.status(429).json({
38
- // success: false,
39
- // error: "RATE_LIMIT_EXCEEDED",
40
- // retryAfter: Math.ceil(rlErr.msBeforeNext / 1000),
41
- // message: options.message ?? "Too many requests, slow down."
42
- // });
43
- // }
44
- // };
45
- // } catch (err: any) {
46
- // logger.error("❌ RLFlexibleAdapter: failed to initialize limiter", {
47
- // error: err?.message || err
48
- // });
49
- // throw new AdapterError("RateLimiterFlexible creation failed.");
50
- // }
51
- // }
52
- // }
53
- // src/adapters/RLFlexibleAdapter.ts - IMPROVED
54
4
  const rate_limiter_flexible_1 = require("rate-limiter-flexible");
55
5
  const index_js_1 = require("../logging/index.js");
56
6
  const AdapterError_js_1 = require("../core/errors/AdapterError.js");
@@ -70,7 +20,6 @@ class RLFlexibleAdapter {
70
20
  blockDuration: finalOptions.blockDuration
71
21
  });
72
22
  return async (req, res, next) => {
73
- // Better IP extraction
74
23
  const ip = this.extractIP(req);
75
24
  try {
76
25
  await limiter.consume(ip);
@@ -102,7 +51,6 @@ class RLFlexibleAdapter {
102
51
  }
103
52
  }
104
53
  extractIP(req) {
105
- // Order of priority for IP extraction
106
54
  return (req.headers['x-real-ip'] ||
107
55
  req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||
108
56
  req.ip ||
@@ -1 +1 @@
1
- {"version":3,"file":"RLFlexibleAdapter.js","sourceRoot":"","sources":["../../src/adapters/RLFlexibleAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["\r\n// import { RateLimiterMemory, RateLimiterRes } from \"rate-limiter-flexible\";\r\n// import { logger } from \"../logging\";\r\n// import { AdapterError } from \"../core/errors/AdapterError\";\r\n\r\n// export class RLFlexibleAdapter {\r\n\r\n// /**\r\n// * Create middleware dynamically using options.\r\n// */\r\n// getMiddleware(options: {\r\n// points?: number;\r\n// duration?: number; // seconds\r\n// message?: any;\r\n// } = {}) {\r\n\r\n// try {\r\n// const limiter = new RateLimiterMemory({\r\n// points: options.points ?? 100,\r\n// duration: options.duration ?? 60,\r\n// });\r\n\r\n// return async (req: any, res: any, next: any) => {\r\n// const ip = req.ip ||\r\n// req.headers[\"x-forwarded-for\"] ||\r\n// req.connection?.remoteAddress ||\r\n// \"unknown\";\r\n\r\n// try {\r\n// await limiter.consume(ip);\r\n// next();\r\n// } catch (err: any) {\r\n// const rlErr = err as RateLimiterRes;\r\n\r\n// logger.warn(\"⚠ RLFlexibleAdapter: rate limit exceeded\", {\r\n// ip,\r\n// path: req.path,\r\n// method: req.method,\r\n// retryAfter: rlErr.msBeforeNext\r\n// });\r\n\r\n// return res.status(429).json({\r\n// success: false,\r\n// error: \"RATE_LIMIT_EXCEEDED\",\r\n// retryAfter: Math.ceil(rlErr.msBeforeNext / 1000),\r\n// message: options.message ?? \"Too many requests, slow down.\"\r\n// });\r\n// }\r\n// };\r\n\r\n// } catch (err: any) {\r\n// logger.error(\"❌ RLFlexibleAdapter: failed to initialize limiter\", {\r\n// error: err?.message || err\r\n// });\r\n// throw new AdapterError(\"RateLimiterFlexible creation failed.\");\r\n// }\r\n// }\r\n// }\r\n\r\n\r\n\r\n// src/adapters/RLFlexibleAdapter.ts - IMPROVED\r\nimport { RateLimiterMemory, RateLimiterRes } from \"rate-limiter-flexible\";\r\nimport { logger } from \"../logging/index.js\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\n\r\nexport interface RLOptions {\r\n points?: number;\r\n duration?: number; // seconds\r\n message?: any;\r\n blockDuration?: number;\r\n}\r\n\r\nexport class RLFlexibleAdapter {\r\n getMiddleware(options: RLOptions = {}) {\r\n try {\r\n const defaultOptions = {\r\n points: 100,\r\n duration: 60,\r\n message: \"Too many requests, slow down.\",\r\n blockDuration: 0\r\n };\r\n\r\n const finalOptions = { ...defaultOptions, ...options };\r\n\r\n const limiter = new RateLimiterMemory({\r\n points: finalOptions.points,\r\n duration: finalOptions.duration,\r\n blockDuration: finalOptions.blockDuration\r\n });\r\n\r\n return async (req: any, res: any, next: any) => {\r\n // Better IP extraction\r\n const ip = this.extractIP(req);\r\n\r\n try {\r\n await limiter.consume(ip);\r\n next();\r\n } catch (err: any) {\r\n const rlErr = err as RateLimiterRes;\r\n\r\n logger.warn(\"⚠ RLFlexibleAdapter: rate limit exceeded\", {\r\n ip,\r\n path: req.path,\r\n method: req.method,\r\n retryAfter: rlErr.msBeforeNext\r\n });\r\n\r\n res.setHeader('Retry-After', Math.ceil(rlErr.msBeforeNext / 1000));\r\n \r\n return res.status(429).json({\r\n success: false,\r\n error: \"RATE_LIMIT_EXCEEDED\",\r\n retryAfter: Math.ceil(rlErr.msBeforeNext / 1000),\r\n message: finalOptions.message\r\n });\r\n }\r\n };\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ RLFlexibleAdapter: failed to initialize limiter\", {\r\n error: err?.message || err\r\n });\r\n throw new AdapterError(\"RateLimiterFlexible creation failed.\");\r\n }\r\n }\r\n\r\n private extractIP(req: any): string {\r\n // Order of priority for IP extraction\r\n return (\r\n req.headers['x-real-ip'] ||\r\n req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||\r\n req.ip ||\r\n req.connection?.remoteAddress ||\r\n req.socket?.remoteAddress ||\r\n 'unknown'\r\n );\r\n }\r\n}"]}
1
+ {"version":3,"file":"RLFlexibleAdapter.js","sourceRoot":"","sources":["../../src/adapters/RLFlexibleAdapter.ts"],"names":[],"mappings":";;;AAAA,iEAA0E;AAC1E,kDAA6C;AAC7C,oEAA8D;AAS9D,MAAa,iBAAiB;IAC1B,aAAa,CAAC,UAAqB,EAAE;QACjC,IAAI,CAAC;YACD,MAAM,cAAc,GAAG;gBACnB,MAAM,EAAE,GAAG;gBACX,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,+BAA+B;gBACxC,aAAa,EAAE,CAAC;aACnB,CAAC;YAEF,MAAM,YAAY,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC;YAEvD,MAAM,OAAO,GAAG,IAAI,yCAAiB,CAAC;gBAClC,MAAM,EAAE,YAAY,CAAC,MAAM;gBAC3B,QAAQ,EAAE,YAAY,CAAC,QAAQ;gBAC/B,aAAa,EAAE,YAAY,CAAC,aAAa;aAC5C,CAAC,CAAC;YAEH,OAAO,KAAK,EAAE,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;gBAE3C,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBAE/B,IAAI,CAAC;oBACD,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBAC1B,IAAI,EAAE,CAAC;gBACX,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,MAAM,KAAK,GAAG,GAAqB,CAAC;oBAEpC,iBAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;wBACpD,EAAE;wBACF,IAAI,EAAE,GAAG,CAAC,IAAI;wBACd,MAAM,EAAE,GAAG,CAAC,MAAM;wBAClB,UAAU,EAAE,KAAK,CAAC,YAAY;qBACjC,CAAC,CAAC;oBAEH,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;oBAEnE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBACxB,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,qBAAqB;wBAC5B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;wBAChD,OAAO,EAAE,YAAY,CAAC,OAAO;qBAChC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC,CAAC;QAEN,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,iBAAM,CAAC,KAAK,CAAC,mDAAmD,EAAE;gBAC9D,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG;aAC7B,CAAC,CAAC;YACH,MAAM,IAAI,8BAAY,CAAC,sCAAsC,CAAC,CAAC;QACnE,CAAC;IACL,CAAC;IAEO,SAAS,CAAC,GAAQ;QACtB,OAAO,CACH,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC;YACxB,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE;YACrD,GAAG,CAAC,EAAE;YACN,GAAG,CAAC,UAAU,EAAE,aAAa;YAC7B,GAAG,CAAC,MAAM,EAAE,aAAa;YACzB,SAAS,CACZ,CAAC;IACN,CAAC;CACJ;AAhED,8CAgEC","sourcesContent":["import { RateLimiterMemory, RateLimiterRes } from \"rate-limiter-flexible\";\r\nimport { logger } from \"../logging/index.js\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\n\r\nexport interface RLOptions {\r\n points?: number;\r\n duration?: number; \r\n message?: any;\r\n blockDuration?: number;\r\n}\r\n\r\nexport class RLFlexibleAdapter {\r\n getMiddleware(options: RLOptions = {}) {\r\n try {\r\n const defaultOptions = {\r\n points: 100,\r\n duration: 60,\r\n message: \"Too many requests, slow down.\",\r\n blockDuration: 0\r\n };\r\n\r\n const finalOptions = { ...defaultOptions, ...options };\r\n\r\n const limiter = new RateLimiterMemory({\r\n points: finalOptions.points,\r\n duration: finalOptions.duration,\r\n blockDuration: finalOptions.blockDuration\r\n });\r\n\r\n return async (req: any, res: any, next: any) => {\r\n \r\n const ip = this.extractIP(req);\r\n\r\n try {\r\n await limiter.consume(ip);\r\n next();\r\n } catch (err: any) {\r\n const rlErr = err as RateLimiterRes;\r\n\r\n logger.warn(\"⚠ RLFlexibleAdapter: rate limit exceeded\", {\r\n ip,\r\n path: req.path,\r\n method: req.method,\r\n retryAfter: rlErr.msBeforeNext\r\n });\r\n\r\n res.setHeader('Retry-After', Math.ceil(rlErr.msBeforeNext / 1000));\r\n \r\n return res.status(429).json({\r\n success: false,\r\n error: \"RATE_LIMIT_EXCEEDED\",\r\n retryAfter: Math.ceil(rlErr.msBeforeNext / 1000),\r\n message: finalOptions.message\r\n });\r\n }\r\n };\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ RLFlexibleAdapter: failed to initialize limiter\", {\r\n error: err?.message || err\r\n });\r\n throw new AdapterError(\"RateLimiterFlexible creation failed.\");\r\n }\r\n }\r\n\r\n private extractIP(req: any): string {\r\n return (\r\n req.headers['x-real-ip'] ||\r\n req.headers['x-forwarded-for']?.split(',')[0]?.trim() ||\r\n req.ip ||\r\n req.connection?.remoteAddress ||\r\n req.socket?.remoteAddress ||\r\n 'unknown'\r\n );\r\n }\r\n}"]}
@@ -3,9 +3,6 @@ export declare class SanitizeHtmlAdapter {
3
3
  private globalOptions;
4
4
  constructor(options?: sanitizeHtml.IOptions);
5
5
  sanitize(input: string, dynamicOptions?: any): string;
6
- /**
7
- * Deep sanitize with recursion protection
8
- */
9
6
  private deepSanitize;
10
7
  middleware(dynamicOptions?: any): (req: any, _res: any, next: any) => void;
11
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SanitizeHtmlAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/SanitizeHtmlAdapter.ts"],"names":[],"mappings":"AAkFA,OAAO,YAAY,MAAM,eAAe,CAAC;AAIzC,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,aAAa,CAAwB;gBAEjC,OAAO,GAAE,YAAY,CAAC,QAAa;IAI/C,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,GAAG,GAAG,MAAM;IAiBrD;;OAEG;IACH,OAAO,CAAC,YAAY;IA4BpB,UAAU,CAAC,cAAc,CAAC,EAAE,GAAG,IACnB,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;CAmB7C"}
1
+ {"version":3,"file":"SanitizeHtmlAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/SanitizeHtmlAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAC;AAIzC,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,aAAa,CAAwB;gBAEjC,OAAO,GAAE,YAAY,CAAC,QAAa;IAI/C,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,GAAG,GAAG,MAAM;IAkBrD,OAAO,CAAC,YAAY;IA4BpB,UAAU,CAAC,cAAc,CAAC,EAAE,GAAG,IACnB,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;CAmB7C"}
@@ -1,75 +1,9 @@
1
1
  "use strict";
2
- // import sanitizeHtml from "sanitize-html";
3
- // import { AdapterError } from "../core/errors/AdapterError";
4
- // import { logger } from "../logging";
5
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
6
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
7
4
  };
8
5
  Object.defineProperty(exports, "__esModule", { value: true });
9
6
  exports.SanitizeHtmlAdapter = void 0;
10
- // export class SanitizeHtmlAdapter {
11
- // private globalOptions: sanitizeHtml.IOptions;
12
- // constructor(options: sanitizeHtml.IOptions = {}) {
13
- // this.globalOptions = options;
14
- // }
15
- // /**
16
- // * Sanitize a string with merged global + dynamic options
17
- // */
18
- // sanitize(input: string, dynamicOptions?: any): string {
19
- // try {
20
- // const opts = { ...this.globalOptions, ...(dynamicOptions || {}) };
21
- // const clean = sanitizeHtml(input, opts);
22
- // return typeof clean === "string" ? clean : String(clean);
23
- // } catch (err: any) {
24
- // logger.error("❌ sanitize-html failed", {
25
- // error: err?.message || err,
26
- // preview: typeof input === "string" ? input.slice(0, 100) : undefined
27
- // });
28
- // throw new AdapterError("sanitize-html adapter failed.");
29
- // }
30
- // }
31
- // /**
32
- // * Deep sanitize nested objects, arrays, strings
33
- // */
34
- // private deepSanitize(obj: any, dynamicOptions?: any): any {
35
- // if (typeof obj === "string") {
36
- // return this.sanitize(obj, dynamicOptions);
37
- // }
38
- // if (Array.isArray(obj)) {
39
- // return obj.map((item) => this.deepSanitize(item, dynamicOptions));
40
- // }
41
- // if (obj && typeof obj === "object") {
42
- // const result: any = {};
43
- // for (const key of Object.keys(obj)) {
44
- // result[key] = this.deepSanitize(obj[key], dynamicOptions);
45
- // }
46
- // return result;
47
- // }
48
- // return obj;
49
- // }
50
- // /**
51
- // * Middleware wrapper with dynamic per-route options
52
- // */
53
- // middleware(dynamicOptions?: any) {
54
- // return (req: any, _res: any, next: any) => {
55
- // try {
56
- // if (req.body) {
57
- // req.body = this.deepSanitize(req.body, dynamicOptions);
58
- // logger.debug("🧼 sanitize-html applied", {
59
- // keys: Object.keys(req.body)
60
- // });
61
- // }
62
- // next();
63
- // } catch (err: any) {
64
- // logger.error("❌ sanitize-html middleware failed", {
65
- // error: err?.message || err
66
- // });
67
- // next(err);
68
- // }
69
- // };
70
- // }
71
- // }
72
- // src/adapters/SanitizeHtmlAdapter.ts - FIXED
73
7
  const sanitize_html_1 = __importDefault(require("sanitize-html"));
74
8
  const AdapterError_js_1 = require("../core/errors/AdapterError.js");
75
9
  const index_js_1 = require("../logging/index.js");
@@ -91,14 +25,11 @@ class SanitizeHtmlAdapter {
91
25
  throw new AdapterError_js_1.AdapterError("sanitize-html adapter failed.");
92
26
  }
93
27
  }
94
- /**
95
- * Deep sanitize with recursion protection
96
- */
28
+ // Deep Sanitization - Recursively
97
29
  deepSanitize(obj, dynamicOptions, visited = new WeakSet()) {
98
- // Handle circular references
99
30
  if (obj && typeof obj === "object") {
100
31
  if (visited.has(obj)) {
101
- return obj; // Circular reference detected
32
+ return obj;
102
33
  }
103
34
  visited.add(obj);
104
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SanitizeHtmlAdapter.js","sourceRoot":"","sources":["../../src/adapters/SanitizeHtmlAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["// import sanitizeHtml from \"sanitize-html\";\r\n// import { AdapterError } from \"../core/errors/AdapterError\";\r\n// import { logger } from \"../logging\";\r\n\r\n// export class SanitizeHtmlAdapter {\r\n// private globalOptions: sanitizeHtml.IOptions;\r\n\r\n// constructor(options: sanitizeHtml.IOptions = {}) {\r\n// this.globalOptions = options;\r\n// }\r\n\r\n// /**\r\n// * Sanitize a string with merged global + dynamic options\r\n// */\r\n// sanitize(input: string, dynamicOptions?: any): string {\r\n// try {\r\n// const opts = { ...this.globalOptions, ...(dynamicOptions || {}) };\r\n\r\n// const clean = sanitizeHtml(input, opts);\r\n\r\n// return typeof clean === \"string\" ? clean : String(clean);\r\n\r\n// } catch (err: any) {\r\n// logger.error(\"❌ sanitize-html failed\", {\r\n// error: err?.message || err,\r\n// preview: typeof input === \"string\" ? input.slice(0, 100) : undefined\r\n// });\r\n\r\n// throw new AdapterError(\"sanitize-html adapter failed.\");\r\n// }\r\n// }\r\n\r\n// /**\r\n// * Deep sanitize nested objects, arrays, strings\r\n// */\r\n// private deepSanitize(obj: any, dynamicOptions?: any): any {\r\n// if (typeof obj === \"string\") {\r\n// return this.sanitize(obj, dynamicOptions);\r\n// }\r\n\r\n// if (Array.isArray(obj)) {\r\n// return obj.map((item) => this.deepSanitize(item, dynamicOptions));\r\n// }\r\n\r\n// if (obj && typeof obj === \"object\") {\r\n// const result: any = {};\r\n// for (const key of Object.keys(obj)) {\r\n// result[key] = this.deepSanitize(obj[key], dynamicOptions);\r\n// }\r\n// return result;\r\n// }\r\n\r\n// return obj;\r\n// }\r\n\r\n// /**\r\n// * Middleware wrapper with dynamic per-route options\r\n// */\r\n// middleware(dynamicOptions?: any) {\r\n// return (req: any, _res: any, next: any) => {\r\n// try {\r\n// if (req.body) {\r\n// req.body = this.deepSanitize(req.body, dynamicOptions);\r\n\r\n// logger.debug(\"🧼 sanitize-html applied\", {\r\n// keys: Object.keys(req.body)\r\n// });\r\n// }\r\n// next();\r\n\r\n// } catch (err: any) {\r\n// logger.error(\"❌ sanitize-html middleware failed\", {\r\n// error: err?.message || err\r\n// });\r\n// next(err);\r\n// }\r\n// };\r\n// }\r\n// }\r\n\r\n\r\n// src/adapters/SanitizeHtmlAdapter.ts - FIXED\r\nimport sanitizeHtml from \"sanitize-html\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logger } from \"../logging/index.js\";\r\n\r\nexport class SanitizeHtmlAdapter {\r\n private globalOptions: sanitizeHtml.IOptions;\r\n\r\n constructor(options: sanitizeHtml.IOptions = {}) {\r\n this.globalOptions = options;\r\n }\r\n\r\n sanitize(input: string, dynamicOptions?: any): string {\r\n try {\r\n const opts = { ...this.globalOptions, ...(dynamicOptions || {}) };\r\n\r\n const clean = sanitizeHtml(input, opts);\r\n return typeof clean === \"string\" ? clean : String(clean);\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ sanitize-html failed\", {\r\n error: err?.message || err,\r\n preview: typeof input === \"string\" ? input.slice(0, 100) : undefined\r\n });\r\n\r\n throw new AdapterError(\"sanitize-html adapter failed.\");\r\n }\r\n }\r\n\r\n /**\r\n * Deep sanitize with recursion protection\r\n */\r\n private deepSanitize(obj: any, dynamicOptions?: any, visited = new WeakSet()): any {\r\n // Handle circular references\r\n if (obj && typeof obj === \"object\") {\r\n if (visited.has(obj)) {\r\n return obj; // Circular reference detected\r\n }\r\n visited.add(obj);\r\n }\r\n\r\n if (typeof obj === \"string\") {\r\n return this.sanitize(obj, dynamicOptions);\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map((item) => this.deepSanitize(item, dynamicOptions, visited));\r\n }\r\n\r\n if (obj && typeof obj === \"object\") {\r\n const result: any = {};\r\n for (const key of Object.keys(obj)) {\r\n result[key] = this.deepSanitize(obj[key], dynamicOptions, visited);\r\n }\r\n return result;\r\n }\r\n\r\n return obj;\r\n }\r\n\r\n middleware(dynamicOptions?: any) {\r\n return (req: any, _res: any, next: any) => {\r\n try {\r\n if (req.body) {\r\n req.body = this.deepSanitize(req.body, dynamicOptions);\r\n\r\n logger.debug(\"🧼 sanitize-html applied\", {\r\n keys: Object.keys(req.body)\r\n });\r\n }\r\n next();\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ sanitize-html middleware failed\", {\r\n error: err?.message || err\r\n });\r\n next(err);\r\n }\r\n };\r\n }\r\n}"]}
1
+ {"version":3,"file":"SanitizeHtmlAdapter.js","sourceRoot":"","sources":["../../src/adapters/SanitizeHtmlAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import sanitizeHtml from \"sanitize-html\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logger } from \"../logging/index.js\";\r\n\r\nexport class SanitizeHtmlAdapter {\r\n private globalOptions: sanitizeHtml.IOptions;\r\n\r\n constructor(options: sanitizeHtml.IOptions = {}) {\r\n this.globalOptions = options;\r\n }\r\n\r\n sanitize(input: string, dynamicOptions?: any): string {\r\n try {\r\n const opts = { ...this.globalOptions, ...(dynamicOptions || {}) };\r\n\r\n const clean = sanitizeHtml(input, opts);\r\n return typeof clean === \"string\" ? clean : String(clean);\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ sanitize-html failed\", {\r\n error: err?.message || err,\r\n preview: typeof input === \"string\" ? input.slice(0, 100) : undefined\r\n });\r\n\r\n throw new AdapterError(\"sanitize-html adapter failed.\");\r\n }\r\n }\r\n\r\n // Deep Sanitization - Recursively \r\n private deepSanitize(obj: any, dynamicOptions?: any, visited = new WeakSet()): any {\r\n \r\n if (obj && typeof obj === \"object\") {\r\n if (visited.has(obj)) {\r\n return obj; \r\n }\r\n visited.add(obj);\r\n }\r\n\r\n if (typeof obj === \"string\") {\r\n return this.sanitize(obj, dynamicOptions);\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map((item) => this.deepSanitize(item, dynamicOptions, visited));\r\n }\r\n\r\n if (obj && typeof obj === \"object\") {\r\n const result: any = {};\r\n for (const key of Object.keys(obj)) {\r\n result[key] = this.deepSanitize(obj[key], dynamicOptions, visited);\r\n }\r\n return result;\r\n }\r\n\r\n return obj;\r\n }\r\n\r\n middleware(dynamicOptions?: any) {\r\n return (req: any, _res: any, next: any) => {\r\n try {\r\n if (req.body) {\r\n req.body = this.deepSanitize(req.body, dynamicOptions);\r\n\r\n logger.debug(\"🧼 sanitize-html applied\", {\r\n keys: Object.keys(req.body)\r\n });\r\n }\r\n next();\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ sanitize-html middleware failed\", {\r\n error: err?.message || err\r\n });\r\n next(err);\r\n }\r\n };\r\n }\r\n}"]}
@@ -16,18 +16,8 @@ export declare class XSSAdapter {
16
16
  private globalOptions;
17
17
  private defaultFilter;
18
18
  constructor(options?: XSSOptions);
19
- /**
20
- * Sanitize a string with global + dynamic merged options
21
- */
22
19
  sanitize(input: string, dynamicOptions?: XSSOptions): string;
23
- /**
24
- * Middleware wrapper WITH dynamic options
25
- * Doesn't mutate original request - creates sanitized copy
26
- */
27
20
  middleware(dynamicOptions?: XSSOptions): (req: any, _res: any, next: any) => void;
28
- /**
29
- * Deep sanitize nested objects/arrays
30
- */
31
21
  private deepSanitize;
32
22
  }
33
23
  //# sourceMappingURL=XSSAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"XSSAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/XSSAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAkC,SAAS,EAAE,MAAM,KAAK,CAAC;AAIhE,MAAM,WAAW,UAAU;IACvB,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC3C,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,MAAM,CAAC;IAC5D,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,KAAK,MAAM,CAAC;IACvF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,MAAM,CAAC;IAClE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,qBAAa,UAAU;IACnB,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,aAAa,CAAY;gBAErB,OAAO,GAAE,UAAe;IAuBpC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,UAAU,GAAG,MAAM;IA0B5D;;;OAGG;IACH,UAAU,CAAC,cAAc,CAAC,EAAE,UAAU,IAC1B,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;IA4C1C;;OAEG;IACH,OAAO,CAAC,YAAY;CA2BvB"}
1
+ {"version":3,"file":"XSSAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/XSSAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,SAAS,EAAE,MAAM,KAAK,CAAC;AAIhE,MAAM,WAAW,UAAU;IACvB,SAAS,CAAC,EAAE,OAAO,SAAS,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC3C,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,MAAM,CAAC;IAC5D,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,KAAK,MAAM,CAAC;IACvF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,MAAM,CAAC;IAClE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,qBAAa,UAAU;IACnB,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,aAAa,CAAY;gBAErB,OAAO,GAAE,UAAe;IAwBpC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,UAAU,GAAG,MAAM;IA2B5D,UAAU,CAAC,cAAc,CAAC,EAAE,UAAU,IAC1B,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;IA6C1C,OAAO,CAAC,YAAY;CA2BvB"}
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.XSSAdapter = void 0;
4
- // src/adapters/XSSAdapter.ts - NEW FILE
5
4
  const xss_1 = require("xss");
6
5
  const AdapterError_js_1 = require("../core/errors/AdapterError.js");
7
6
  const index_js_1 = require("../logging/index.js");
@@ -11,12 +10,11 @@ class XSSAdapter {
11
10
  // Default safe configuration
12
11
  const defaultOptions = {
13
12
  whiteList: (0, xss_1.getDefaultWhiteList)(),
14
- stripIgnoreTag: true, // Remove non-whitelisted tags completely
13
+ stripIgnoreTag: true,
15
14
  stripIgnoreTagBody: ['script', 'style', 'iframe', 'object', 'embed'],
16
15
  allowCommentTag: false,
17
- css: false, // Disable CSS by default
16
+ css: false,
18
17
  onTag: (tag, html, options) => {
19
- // Add noopener/noreferrer to links for security
20
18
  if (tag === 'a') {
21
19
  return html.replace(/<a /i, '<a target="_blank" rel="noopener noreferrer" ');
22
20
  }
@@ -26,19 +24,14 @@ class XSSAdapter {
26
24
  const finalOptions = { ...defaultOptions, ...options };
27
25
  this.defaultFilter = new xss_1.FilterXSS(finalOptions);
28
26
  }
29
- /**
30
- * Sanitize a string with global + dynamic merged options
31
- */
32
27
  sanitize(input, dynamicOptions) {
33
28
  try {
34
29
  if (typeof input !== "string") {
35
30
  return input;
36
31
  }
37
- // If no dynamic options, use default filter
38
32
  if (!dynamicOptions || Object.keys(dynamicOptions).length === 0) {
39
33
  return this.defaultFilter.process(input);
40
34
  }
41
- // Merge options for this specific call
42
35
  const mergedOptions = { ...this.globalOptions, ...dynamicOptions };
43
36
  const customFilter = new xss_1.FilterXSS(mergedOptions);
44
37
  return customFilter.process(input);
@@ -51,10 +44,6 @@ class XSSAdapter {
51
44
  throw new AdapterError_js_1.AdapterError("XSS sanitizer failed.");
52
45
  }
53
46
  }
54
- /**
55
- * Middleware wrapper WITH dynamic options
56
- * Doesn't mutate original request - creates sanitized copy
57
- */
58
47
  middleware(dynamicOptions) {
59
48
  return (req, _res, next) => {
60
49
  try {
@@ -72,14 +61,12 @@ class XSSAdapter {
72
61
  : v);
73
62
  }
74
63
  else if (val && typeof val === "object") {
75
- // Handle nested objects (simple recursion)
76
64
  sanitizedBody[key] = this.deepSanitize(val, dynamicOptions);
77
65
  }
78
66
  else {
79
67
  sanitizedBody[key] = val;
80
68
  }
81
69
  }
82
- // Store sanitized version separately
83
70
  req.sanitizedBody = sanitizedBody;
84
71
  index_js_1.logger.debug("🛡️ XSS sanitizer applied", {
85
72
  originalKeys: Object.keys(originalBody),
@@ -96,11 +83,7 @@ class XSSAdapter {
96
83
  }
97
84
  };
98
85
  }
99
- /**
100
- * Deep sanitize nested objects/arrays
101
- */
102
86
  deepSanitize(obj, options, visited = new WeakSet()) {
103
- // Handle circular references
104
87
  if (obj && typeof obj === "object") {
105
88
  if (visited.has(obj)) {
106
89
  return obj;
@@ -1 +1 @@
1
- {"version":3,"file":"XSSAdapter.js","sourceRoot":"","sources":["../../src/adapters/XSSAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["// src/adapters/XSSAdapter.ts - NEW FILE\r\nimport { FilterXSS, getDefaultWhiteList, whiteList } from 'xss';\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logger } from \"../logging/index.js\";\r\n\r\nexport interface XSSOptions {\r\n whiteList?: typeof whiteList;\r\n stripIgnoreTag?: boolean;\r\n stripIgnoreTagBody?: string[];\r\n allowCommentTag?: boolean;\r\n css?: boolean | { [key: string]: boolean };\r\n onTag?: (tag: string, html: string, options: any) => string;\r\n onTagAttr?: (tag: string, name: string, value: string, isWhiteAttr: boolean) => string;\r\n onIgnoreTag?: (tag: string, html: string, options: any) => string;\r\n [key: string]: any;\r\n}\r\n\r\nexport class XSSAdapter {\r\n private globalOptions: XSSOptions;\r\n private defaultFilter: FilterXSS;\r\n\r\n constructor(options: XSSOptions = {}) {\r\n this.globalOptions = options;\r\n \r\n // Default safe configuration\r\n const defaultOptions: XSSOptions = {\r\n whiteList: getDefaultWhiteList(),\r\n stripIgnoreTag: true, // Remove non-whitelisted tags completely\r\n stripIgnoreTagBody: ['script', 'style', 'iframe', 'object', 'embed'],\r\n allowCommentTag: false,\r\n css: false, // Disable CSS by default\r\n onTag: (tag, html, options) => {\r\n // Add noopener/noreferrer to links for security\r\n if (tag === 'a') {\r\n return html.replace(/<a /i, '<a target=\"_blank\" rel=\"noopener noreferrer\" ');\r\n }\r\n return html;\r\n }\r\n };\r\n\r\n const finalOptions = { ...defaultOptions, ...options };\r\n this.defaultFilter = new FilterXSS(finalOptions);\r\n }\r\n\r\n /**\r\n * Sanitize a string with global + dynamic merged options\r\n */\r\n sanitize(input: string, dynamicOptions?: XSSOptions): string {\r\n try {\r\n if (typeof input !== \"string\") {\r\n return input as any;\r\n }\r\n\r\n // If no dynamic options, use default filter\r\n if (!dynamicOptions || Object.keys(dynamicOptions).length === 0) {\r\n return this.defaultFilter.process(input);\r\n }\r\n\r\n // Merge options for this specific call\r\n const mergedOptions = { ...this.globalOptions, ...dynamicOptions };\r\n const customFilter = new FilterXSS(mergedOptions);\r\n \r\n return customFilter.process(input);\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ XSS sanitizer failed\", {\r\n error: err?.message,\r\n preview: input?.slice?.(0, 80)\r\n });\r\n throw new AdapterError(\"XSS sanitizer failed.\");\r\n }\r\n }\r\n\r\n /**\r\n * Middleware wrapper WITH dynamic options\r\n * Doesn't mutate original request - creates sanitized copy\r\n */\r\n middleware(dynamicOptions?: XSSOptions) {\r\n return (req: any, _res: any, next: any) => {\r\n try {\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 val = originalBody[key];\r\n\r\n if (typeof val === \"string\") {\r\n sanitizedBody[key] = this.sanitize(val, dynamicOptions);\r\n } else if (Array.isArray(val)) {\r\n sanitizedBody[key] = val.map((v) =>\r\n typeof v === \"string\"\r\n ? this.sanitize(v, dynamicOptions)\r\n : v\r\n );\r\n } else if (val && typeof val === \"object\") {\r\n // Handle nested objects (simple recursion)\r\n sanitizedBody[key] = this.deepSanitize(val, dynamicOptions);\r\n } else {\r\n sanitizedBody[key] = val;\r\n }\r\n }\r\n \r\n // Store sanitized version separately\r\n req.sanitizedBody = sanitizedBody;\r\n \r\n logger.debug(\"🛡️ XSS sanitizer applied\", {\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(\"❌ XSS middleware failed\", {\r\n error: err?.message || err\r\n });\r\n next(err);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Deep sanitize nested objects/arrays\r\n */\r\n private deepSanitize(obj: any, options?: XSSOptions, visited = new WeakSet()): any {\r\n // Handle circular references\r\n if (obj && typeof obj === \"object\") {\r\n if (visited.has(obj)) {\r\n return obj;\r\n }\r\n visited.add(obj);\r\n }\r\n\r\n if (typeof obj === \"string\") {\r\n return this.sanitize(obj, options);\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map(item => this.deepSanitize(item, options, visited));\r\n }\r\n\r\n if (obj && typeof obj === \"object\") {\r\n const result: any = {};\r\n for (const key of Object.keys(obj)) {\r\n result[key] = this.deepSanitize(obj[key], options, visited);\r\n }\r\n return result;\r\n }\r\n\r\n return obj;\r\n }\r\n}"]}
1
+ {"version":3,"file":"XSSAdapter.js","sourceRoot":"","sources":["../../src/adapters/XSSAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { FilterXSS, getDefaultWhiteList, whiteList } from 'xss';\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logger } from \"../logging/index.js\";\r\n\r\nexport interface XSSOptions {\r\n whiteList?: typeof whiteList;\r\n stripIgnoreTag?: boolean;\r\n stripIgnoreTagBody?: string[];\r\n allowCommentTag?: boolean;\r\n css?: boolean | { [key: string]: boolean };\r\n onTag?: (tag: string, html: string, options: any) => string;\r\n onTagAttr?: (tag: string, name: string, value: string, isWhiteAttr: boolean) => string;\r\n onIgnoreTag?: (tag: string, html: string, options: any) => string;\r\n [key: string]: any;\r\n}\r\n\r\nexport class XSSAdapter {\r\n private globalOptions: XSSOptions;\r\n private defaultFilter: FilterXSS;\r\n\r\n constructor(options: XSSOptions = {}) {\r\n this.globalOptions = options;\r\n \r\n // Default safe configuration\r\n const defaultOptions: XSSOptions = {\r\n whiteList: getDefaultWhiteList(),\r\n stripIgnoreTag: true, \r\n stripIgnoreTagBody: ['script', 'style', 'iframe', 'object', 'embed'],\r\n allowCommentTag: false,\r\n css: false, \r\n onTag: (tag, html, options) => {\r\n \r\n if (tag === 'a') {\r\n return html.replace(/<a /i, '<a target=\"_blank\" rel=\"noopener noreferrer\" ');\r\n }\r\n return html;\r\n }\r\n };\r\n\r\n const finalOptions = { ...defaultOptions, ...options };\r\n this.defaultFilter = new FilterXSS(finalOptions);\r\n }\r\n\r\n \r\n sanitize(input: string, dynamicOptions?: XSSOptions): string {\r\n try {\r\n if (typeof input !== \"string\") {\r\n return input as any;\r\n }\r\n\r\n \r\n if (!dynamicOptions || Object.keys(dynamicOptions).length === 0) {\r\n return this.defaultFilter.process(input);\r\n }\r\n\r\n \r\n const mergedOptions = { ...this.globalOptions, ...dynamicOptions };\r\n const customFilter = new FilterXSS(mergedOptions);\r\n \r\n return customFilter.process(input);\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ XSS sanitizer failed\", {\r\n error: err?.message,\r\n preview: input?.slice?.(0, 80)\r\n });\r\n throw new AdapterError(\"XSS sanitizer failed.\");\r\n }\r\n }\r\n\r\n \r\n middleware(dynamicOptions?: XSSOptions) {\r\n return (req: any, _res: any, next: any) => {\r\n try {\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 val = originalBody[key];\r\n\r\n if (typeof val === \"string\") {\r\n sanitizedBody[key] = this.sanitize(val, dynamicOptions);\r\n } else if (Array.isArray(val)) {\r\n sanitizedBody[key] = val.map((v) =>\r\n typeof v === \"string\"\r\n ? this.sanitize(v, dynamicOptions)\r\n : v\r\n );\r\n } else if (val && typeof val === \"object\") {\r\n \r\n sanitizedBody[key] = this.deepSanitize(val, dynamicOptions);\r\n } else {\r\n sanitizedBody[key] = val;\r\n }\r\n }\r\n \r\n \r\n req.sanitizedBody = sanitizedBody;\r\n \r\n logger.debug(\"🛡️ XSS sanitizer applied\", {\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(\"❌ XSS middleware failed\", {\r\n error: err?.message || err\r\n });\r\n next(err);\r\n }\r\n };\r\n }\r\n\r\n \r\n private deepSanitize(obj: any, options?: XSSOptions, visited = new WeakSet()): any {\r\n \r\n if (obj && typeof obj === \"object\") {\r\n if (visited.has(obj)) {\r\n return obj;\r\n }\r\n visited.add(obj);\r\n }\r\n\r\n if (typeof obj === \"string\") {\r\n return this.sanitize(obj, options);\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map(item => this.deepSanitize(item, options, visited));\r\n }\r\n\r\n if (obj && typeof obj === \"object\") {\r\n const result: any = {};\r\n for (const key of Object.keys(obj)) {\r\n result[key] = this.deepSanitize(obj[key], options, visited);\r\n }\r\n return result;\r\n }\r\n\r\n return obj;\r\n }\r\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ZodAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ZodAdapter.ts"],"names":[],"mappings":"AAiDA,OAAO,EAAE,SAAS,EAAY,MAAM,KAAK,CAAC;AAI1C,qBAAa,UAAU;IACnB,OAAO,CAAC,YAAY,CAAC,CAAY;gBAErB,YAAY,CAAC,EAAE,SAAS;IAIpC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,IACtB,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG;CA6B5C"}
1
+ {"version":3,"file":"ZodAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ZodAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,KAAK,CAAC;AAI1C,qBAAa,UAAU;IACnB,OAAO,CAAC,YAAY,CAAC,CAAY;gBAErB,YAAY,CAAC,EAAE,SAAS;IAIpC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,IACtB,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG;CA6B5C"}
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- // import { ZodSchema, ZodError } from "zod";
3
- // import { ValidationError } from "../core/errors/ValidationError";
4
- // import { logger } from "../logging";
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.ZodAdapter = void 0;
7
- const ValidationError_js_1 = require("../core/errors/ValidationError.js"); // ✅ Add .js
4
+ const ValidationError_js_1 = require("../core/errors/ValidationError.js");
8
5
  const index_js_1 = require("../logging/index.js");
9
6
  class ZodAdapter {
10
7
  constructor(globalSchema) {
@@ -30,8 +27,7 @@ class ZodAdapter {
30
27
  issues,
31
28
  preview: JSON.stringify(req.body).slice(0, 200)
32
29
  });
33
- return next(new ValidationError_js_1.ValidationError("Validation failed.", issues) // ✅ Pass issues
34
- );
30
+ return next(new ValidationError_js_1.ValidationError("Validation failed.", issues));
35
31
  };
36
32
  }
37
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ZodAdapter.js","sourceRoot":"","sources":["../../src/adapters/ZodAdapter.ts"],"names":[],"mappings":";AAAA,6CAA6C;AAC7C,oEAAoE;AACpE,uCAAuC;;;AAgDvC,0EAAoE,CAAC,YAAY;AACjF,kDAA6C;AAE7C,MAAa,UAAU;IAGnB,YAAY,YAAwB;QAChC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAED,QAAQ,CAAC,aAAyB;QAC9B,OAAO,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,aAAa,IAAI,IAAI,CAAC,YAAY,CAAC;YAElD,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,EAAE,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE1C,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,IAAI,EAAE,CAAC;YAElC,MAAM,MAAM,GAAa,MAAM,CAAC,KAAK,CAAC;YAEtC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvC,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;aACnB,CAAC,CAAC,CAAC;YAEJ,iBAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;gBACnC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM;gBACN,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;aAClD,CAAC,CAAC;YAEH,OAAO,IAAI,CACP,IAAI,oCAAe,CAAC,oBAAoB,EAAE,MAAa,CAAC,CAAC,gBAAgB;aAC5E,CAAC;QACN,CAAC,CAAC;IACN,CAAC;CACJ;AArCD,gCAqCC","sourcesContent":["// import { ZodSchema, ZodError } from \"zod\";\r\n// import { ValidationError } from \"../core/errors/ValidationError\";\r\n// import { logger } from \"../logging\";\r\n\r\n// export class ZodAdapter {\r\n// private globalSchema?: ZodSchema;\r\n\r\n// constructor(globalSchema?: ZodSchema) {\r\n// this.globalSchema = globalSchema as any;\r\n// }\r\n\r\n// /**\r\n// * Validate with global + dynamic schema (dynamic overrides global)\r\n// */\r\n// validate(dynamicSchema?: ZodSchema) {\r\n// return (req: any, res: any, next: any) => {\r\n// const schema = dynamicSchema || this.globalSchema;\r\n\r\n// if (!schema) return next(); // no validation for this route\r\n\r\n// const result = schema.safeParse(req.body);\r\n\r\n// if (result.success) return next();\r\n\r\n// const zodErr: ZodError = result.error;\r\n\r\n// const issues = zodErr.issues.map(issue => ({\r\n// message: issue.message,\r\n// path: issue.path.join(\".\"),\r\n// code: issue.code\r\n// }));\r\n\r\n// logger.warn(\"⚠ Zod validation failed\", {\r\n// path: req.path,\r\n// method: req.method,\r\n// issues,\r\n// preview: JSON.stringify(req.body).slice(0, 200)\r\n// });\r\n\r\n// return next(\r\n// new ValidationError(issues[0]?.message || \"Validation failed.\")\r\n// );\r\n// };\r\n// }\r\n// }\r\n\r\n\r\n\r\n// src/adapters/ZodAdapter.ts - FIXED\r\nimport { ZodSchema, ZodError } from \"zod\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\"; // ✅ Add .js\r\nimport { logger } from \"../logging/index.js\";\r\n\r\nexport class ZodAdapter {\r\n private globalSchema?: ZodSchema;\r\n\r\n constructor(globalSchema?: ZodSchema) {\r\n this.globalSchema = globalSchema;\r\n }\r\n\r\n validate(dynamicSchema?: ZodSchema) {\r\n return (req: any, res: any, next: any) => {\r\n const schema = dynamicSchema || this.globalSchema;\r\n\r\n if (!schema) return next();\r\n\r\n const result = schema.safeParse(req.body);\r\n\r\n if (result.success) return next();\r\n\r\n const zodErr: ZodError = result.error;\r\n\r\n const issues = zodErr.issues.map(issue => ({\r\n message: issue.message,\r\n path: issue.path.join(\".\"),\r\n code: issue.code\r\n }));\r\n\r\n logger.warn(\"⚠ Zod validation failed\", {\r\n path: req.path,\r\n method: req.method,\r\n issues,\r\n preview: JSON.stringify(req.body).slice(0, 200)\r\n });\r\n\r\n return next(\r\n new ValidationError(\"Validation failed.\", issues as any) // ✅ Pass issues\r\n );\r\n };\r\n }\r\n}"]}
1
+ {"version":3,"file":"ZodAdapter.js","sourceRoot":"","sources":["../../src/adapters/ZodAdapter.ts"],"names":[],"mappings":";;;AACA,0EAAoE;AACpE,kDAA6C;AAE7C,MAAa,UAAU;IAGnB,YAAY,YAAwB;QAChC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAED,QAAQ,CAAC,aAAyB;QAC9B,OAAO,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,aAAa,IAAI,IAAI,CAAC,YAAY,CAAC;YAElD,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,EAAE,CAAC;YAE3B,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE1C,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,IAAI,EAAE,CAAC;YAElC,MAAM,MAAM,GAAa,MAAM,CAAC,KAAK,CAAC;YAEtC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvC,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;aACnB,CAAC,CAAC,CAAC;YAEJ,iBAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;gBACnC,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,MAAM;gBACN,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;aAClD,CAAC,CAAC;YAEH,OAAO,IAAI,CACP,IAAI,oCAAe,CAAC,oBAAoB,EAAE,MAAa,CAAC,CAC3D,CAAC;QACN,CAAC,CAAC;IACN,CAAC;CACJ;AArCD,gCAqCC","sourcesContent":["import { ZodSchema, ZodError } from \"zod\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\"; \r\nimport { logger } from \"../logging/index.js\";\r\n\r\nexport class ZodAdapter {\r\n private globalSchema?: ZodSchema;\r\n\r\n constructor(globalSchema?: ZodSchema) {\r\n this.globalSchema = globalSchema;\r\n }\r\n\r\n validate(dynamicSchema?: ZodSchema) {\r\n return (req: any, res: any, next: any) => {\r\n const schema = dynamicSchema || this.globalSchema;\r\n\r\n if (!schema) return next();\r\n\r\n const result = schema.safeParse(req.body);\r\n\r\n if (result.success) return next();\r\n\r\n const zodErr: ZodError = result.error;\r\n\r\n const issues = zodErr.issues.map(issue => ({\r\n message: issue.message,\r\n path: issue.path.join(\".\"),\r\n code: issue.code\r\n }));\r\n\r\n logger.warn(\"⚠ Zod validation failed\", {\r\n path: req.path,\r\n method: req.method,\r\n issues,\r\n preview: JSON.stringify(req.body).slice(0, 200)\r\n });\r\n\r\n return next(\r\n new ValidationError(\"Validation failed.\", issues as any) \r\n );\r\n };\r\n }\r\n}"]}
@@ -22,8 +22,6 @@ export declare class HiSecure {
22
22
  private hashingFallback;
23
23
  private rateLimiterPrimary;
24
24
  private rateLimiterFallback;
25
- private validatorPrimary;
26
- private validatorFallback;
27
25
  private sanitizerPrimary;
28
26
  private sanitizerFallback;
29
27
  private constructor();
@@ -1 +1 @@
1
- {"version":3,"file":"HiSecure.d.ts","sourceRoot":"","sources":["../../src/core/HiSecure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAkB3D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AASzD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAoB,MAAM,0BAA0B,CAAC;AAE7F,qBAAa,QAAQ;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAyB;IAChD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,WAAW,CAAS;IAGrB,WAAW,EAAG,WAAW,CAAC;IAC1B,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAGjC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,mBAAmB,CAAM;IACjC,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAM;IAG/B,OAAO;IAQP,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,QAAQ;IAQ9D,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B,IAAI,IAAI,IAAI;IA0BZ,aAAa,IAAI,OAAO;IAQxB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;IAQ9D,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB;IAIxC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG;IAI7B,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM;IAe9D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;kBArHxB,CAAC;;;iBAEmD,CAAC;IAuHtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;WAYZ,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAMvC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrE,MAAM,CAAC,GAAG;wBACU,MAAM,YAAY,GAAG;wBAQrB,MAAM;;qCASO,MAAM;;MAQrC;IAMF,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ;IAwBvE,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,qBAAqB;CAmDhC"}
1
+ {"version":3,"file":"HiSecure.d.ts","sourceRoot":"","sources":["../../src/core/HiSecure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAkB3D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AASzD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAE1E,qBAAa,QAAQ;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAyB;IAChD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,WAAW,CAAS;IAGrB,WAAW,EAAG,WAAW,CAAC;IAC1B,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAGjC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,mBAAmB,CAAM;IACjC,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAM;IAG/B,OAAO;IAMP,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,QAAQ;IAQ9D,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B,IAAI,IAAI,IAAI;IAyBZ,aAAa,IAAI,OAAO;IAMxB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;IAQ9D,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB;IAIxC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG;IAI7B,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM;IAe9D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;kBA7GJ,CAAC;;;iBAID,CAAC;IA6GtB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;WAUZ,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAMvC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrE,MAAM,CAAC,GAAG;wBACU,MAAM,YAAY,GAAG;wBAQrB,MAAM;;qCASO,MAAM;;MAQrC;IAIF,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ;IAuBvE,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,qBAAqB;CAmDhC"}
@@ -37,9 +37,7 @@ class HiSecure {
37
37
  this.initialized = false;
38
38
  this.config = (0, deepMerge_js_1.deepMerge)(config_js_1.defaultConfig, userConfig);
39
39
  }
40
- // =====================================================
41
40
  // SINGLETON & INITIALIZATION
42
- // =====================================================
43
41
  static getInstance(config) {
44
42
  if (!HiSecure.instance) {
45
43
  HiSecure.instance = new HiSecure(config);
@@ -59,7 +57,6 @@ class HiSecure {
59
57
  this.setupAdapters();
60
58
  this.setupManagers();
61
59
  this.setupDynamicManagers();
62
- // Make everything immutable
63
60
  (0, deepFreeze_js_1.deepFreeze)(this.config);
64
61
  // deepFreeze(this.hashManager);
65
62
  // deepFreeze(this.rateLimitManager);
@@ -74,9 +71,7 @@ class HiSecure {
74
71
  isInitialized() {
75
72
  return this.initialized;
76
73
  }
77
- // =====================================================
78
74
  // FLUENT API METHODS (Route-level security)
79
- // =====================================================
80
75
  static auth(options) {
81
76
  const instance = this.getInstance();
82
77
  if (!instance.authManager) {
@@ -112,9 +107,7 @@ class HiSecure {
112
107
  chain.push(instance.jsonManager.urlencoded());
113
108
  return chain;
114
109
  }
115
- // =====================================================
116
110
  // UTILITY METHODS (Direct usage)
117
- // =====================================================
118
111
  static async hash(password) {
119
112
  const instance = this.getInstance();
120
113
  const result = await instance.hashManager.hash(password, { allowFallback: true });
@@ -123,9 +116,7 @@ class HiSecure {
123
116
  static async verify(password, hash) {
124
117
  return this.getInstance().hashManager.verify(password, hash);
125
118
  }
126
- // =====================================================
127
119
  // GLOBAL MIDDLEWARE (app.use())
128
- // =====================================================
129
120
  static middleware(options) {
130
121
  const instance = this.getInstance();
131
122
  // Handle preset strings
@@ -143,9 +134,7 @@ class HiSecure {
143
134
  }
144
135
  return instance.createMiddlewareChain(options || {});
145
136
  }
146
- // =====================================================
147
- // INTERNAL METHODS
148
- // =====================================================
137
+ // Internal Methods
149
138
  setupAdapters() {
150
139
  index_js_1.logger.info("🧩 Setting up adapters...");
151
140
  // Hashing
@@ -160,13 +149,13 @@ class HiSecure {
160
149
  ? new RLFlexibleAdapter_js_1.RLFlexibleAdapter()
161
150
  : new ExpressRLAdapter_js_1.ExpressRLAdapter();
162
151
  this.rateLimiterFallback = new ExpressRLAdapter_js_1.ExpressRLAdapter();
163
- // Validation
164
- this.validatorPrimary = this.config.validation.mode === "zod"
165
- ? new ZodAdapter_js_1.ZodAdapter()
166
- : new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter();
167
- this.validatorFallback = this.config.validation.fallback === "express-validator"
168
- ? new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter()
169
- : null;
152
+ // // Validation
153
+ // this.validatorPrimary = this.config.validation.mode === "zod"
154
+ // ? new ZodAdapter()
155
+ // : new ExpressValidatorAdapter();
156
+ // this.validatorFallback = this.config.validation.fallback === "express-validator"
157
+ // ? new ExpressValidatorAdapter()
158
+ // : null;
170
159
  // Sanitization
171
160
  this.sanitizerPrimary = new SanitizeHtmlAdapter_js_1.SanitizeHtmlAdapter(this.config.sanitizer);
172
161
  this.sanitizerFallback = new XSSAdapter_js_1.XSSAdapter(this.config.sanitizer);
@@ -195,7 +184,6 @@ class HiSecure {
195
184
  jwtSecret,
196
185
  jwtExpiresIn: this.config.auth.jwtExpiresIn,
197
186
  googleClientId: process.env.GOOGLE_CLIENT_ID || this.config.auth.googleClientId
198
- // Removed algorithm - handled in AuthManager
199
187
  });
200
188
  }
201
189
  }