hi-secure 1.0.15 → 1.0.17

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 (95) hide show
  1. package/dist/adapters/ArgonAdapter.d.ts +1 -1
  2. package/dist/adapters/ArgonAdapter.d.ts.map +1 -1
  3. package/dist/adapters/ArgonAdapter.js +7 -5
  4. package/dist/adapters/ArgonAdapter.js.map +1 -1
  5. package/dist/adapters/BcryptAdapter.d.ts.map +1 -1
  6. package/dist/adapters/BcryptAdapter.js +7 -3
  7. package/dist/adapters/BcryptAdapter.js.map +1 -1
  8. package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -1
  9. package/dist/adapters/ExpressRLAdapter.js +10 -6
  10. package/dist/adapters/ExpressRLAdapter.js.map +1 -1
  11. package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -1
  12. package/dist/adapters/ExpressValidatorAdapter.js +14 -10
  13. package/dist/adapters/ExpressValidatorAdapter.js.map +1 -1
  14. package/dist/adapters/GoogleAdapter.d.ts.map +1 -1
  15. package/dist/adapters/GoogleAdapter.js +19 -16
  16. package/dist/adapters/GoogleAdapter.js.map +1 -1
  17. package/dist/adapters/JWTAdapter.d.ts.map +1 -1
  18. package/dist/adapters/JWTAdapter.js +25 -15
  19. package/dist/adapters/JWTAdapter.js.map +1 -1
  20. package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -1
  21. package/dist/adapters/RLFlexibleAdapter.js +23 -12
  22. package/dist/adapters/RLFlexibleAdapter.js.map +1 -1
  23. package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -1
  24. package/dist/adapters/SanitizeHtmlAdapter.js +17 -13
  25. package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -1
  26. package/dist/adapters/XSSAdapter.d.ts +1 -1
  27. package/dist/adapters/XSSAdapter.d.ts.map +1 -1
  28. package/dist/adapters/XSSAdapter.js +21 -20
  29. package/dist/adapters/XSSAdapter.js.map +1 -1
  30. package/dist/adapters/ZodAdapter.d.ts +1 -1
  31. package/dist/adapters/ZodAdapter.d.ts.map +1 -1
  32. package/dist/adapters/ZodAdapter.js +10 -8
  33. package/dist/adapters/ZodAdapter.js.map +1 -1
  34. package/dist/core/HiSecure.d.ts +3 -4
  35. package/dist/core/HiSecure.d.ts.map +1 -1
  36. package/dist/core/HiSecure.js +91 -120
  37. package/dist/core/HiSecure.js.map +1 -1
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +8 -1
  41. package/dist/index.js.map +1 -1
  42. package/dist/logging/morganSetup.d.ts.map +1 -1
  43. package/dist/logging/morganSetup.js +8 -1
  44. package/dist/logging/morganSetup.js.map +1 -1
  45. package/dist/logging/winstonSetup.d.ts.map +1 -1
  46. package/dist/logging/winstonSetup.js +17 -3
  47. package/dist/logging/winstonSetup.js.map +1 -1
  48. package/dist/managers/AuthManager.d.ts +2 -2
  49. package/dist/managers/AuthManager.d.ts.map +1 -1
  50. package/dist/managers/AuthManager.js +59 -31
  51. package/dist/managers/AuthManager.js.map +1 -1
  52. package/dist/managers/CorsManager.d.ts.map +1 -1
  53. package/dist/managers/CorsManager.js +18 -11
  54. package/dist/managers/CorsManager.js.map +1 -1
  55. package/dist/managers/HashManager.d.ts +1 -1
  56. package/dist/managers/HashManager.d.ts.map +1 -1
  57. package/dist/managers/HashManager.js +35 -17
  58. package/dist/managers/HashManager.js.map +1 -1
  59. package/dist/managers/JsonManager.d.ts +1 -1
  60. package/dist/managers/JsonManager.d.ts.map +1 -1
  61. package/dist/managers/JsonManager.js +44 -16
  62. package/dist/managers/JsonManager.js.map +1 -1
  63. package/dist/managers/RateLimitManager.d.ts +1 -1
  64. package/dist/managers/RateLimitManager.d.ts.map +1 -1
  65. package/dist/managers/RateLimitManager.js +43 -22
  66. package/dist/managers/RateLimitManager.js.map +1 -1
  67. package/dist/managers/SanitizerManager.d.ts.map +1 -1
  68. package/dist/managers/SanitizerManager.js +32 -15
  69. package/dist/managers/SanitizerManager.js.map +1 -1
  70. package/dist/managers/ValidatorManager.d.ts.map +1 -1
  71. package/dist/managers/ValidatorManager.js +31 -7
  72. package/dist/managers/ValidatorManager.js.map +1 -1
  73. package/package.json +2 -6
  74. package/readme.md +3 -6
  75. package/src/adapters/ArgonAdapter.ts +10 -6
  76. package/src/adapters/BcryptAdapter.ts +7 -8
  77. package/src/adapters/ExpressRLAdapter.ts +14 -9
  78. package/src/adapters/ExpressValidatorAdapter.ts +17 -11
  79. package/src/adapters/GoogleAdapter.ts +24 -21
  80. package/src/adapters/JWTAdapter.ts +33 -21
  81. package/src/adapters/RLFlexibleAdapter.ts +31 -16
  82. package/src/adapters/SanitizeHtmlAdapter.ts +28 -18
  83. package/src/adapters/XSSAdapter.ts +33 -38
  84. package/src/adapters/ZodAdapter.ts +10 -10
  85. package/src/core/HiSecure.ts +127 -161
  86. package/src/index.ts +4 -0
  87. package/src/logging/morganSetup.ts +11 -1
  88. package/src/logging/winstonSetup.ts +35 -8
  89. package/src/managers/AuthManager.ts +64 -34
  90. package/src/managers/CorsManager.ts +23 -16
  91. package/src/managers/HashManager.ts +48 -19
  92. package/src/managers/JsonManager.ts +57 -15
  93. package/src/managers/RateLimitManager.ts +61 -29
  94. package/src/managers/SanitizerManager.ts +47 -25
  95. package/src/managers/ValidatorManager.ts +40 -15
@@ -1,31 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RateLimitManager = void 0;
4
- const AdapterError_js_1 = require("../core/errors/AdapterError.js");
4
+ const AdapterError_1 = require("../core/errors/AdapterError");
5
5
  const logging_1 = require("../logging");
6
6
  class RateLimitManager {
7
7
  constructor(config, primaryAdapter, fallbackAdapter) {
8
8
  this.config = config;
9
9
  this.primaryAdapter = primaryAdapter;
10
10
  this.fallbackAdapter = fallbackAdapter;
11
+ logging_1.logger.info("RateLimitManager initialized", {
12
+ layer: "rate-limit-manager",
13
+ primaryConfigured: true,
14
+ fallbackConfigured: !!fallbackAdapter
15
+ });
11
16
  }
12
17
  middleware(opts) {
13
18
  let finalOptions = {};
14
- if (opts?.mode === "strict") {
19
+ const mode = opts?.mode || "default";
20
+ if (mode === "strict") {
15
21
  finalOptions = {
16
22
  windowMs: 10000,
17
23
  max: 5,
18
24
  message: "Too many requests, please slow down."
19
25
  };
20
26
  }
21
- else if (opts?.mode === "relaxed") {
27
+ else if (mode === "relaxed") {
22
28
  finalOptions = {
23
29
  windowMs: 60000,
24
30
  max: 100,
25
31
  message: "Rate limit exceeded."
26
32
  };
27
33
  }
28
- else if (opts?.mode === "api") {
34
+ else if (mode === "api") {
29
35
  finalOptions = {
30
36
  windowMs: 15 * 60 * 1000,
31
37
  max: 100,
@@ -42,50 +48,65 @@ class RateLimitManager {
42
48
  };
43
49
  }
44
50
  if (opts?.options) {
45
- const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders', 'legacyHeaders'];
51
+ const allowedOverrides = [
52
+ "message",
53
+ "skipFailedRequests",
54
+ "standardHeaders",
55
+ "legacyHeaders"
56
+ ];
46
57
  for (const key of allowedOverrides) {
47
58
  if (opts.options[key] !== undefined) {
48
59
  finalOptions[key] = opts.options[key];
49
60
  }
50
61
  }
51
- const attemptedOverrides = Object.keys(opts.options).filter(k => !allowedOverrides.includes(k) && k !== 'mode');
62
+ const attemptedOverrides = Object.keys(opts.options).filter(k => !allowedOverrides.includes(k) && k !== "mode");
52
63
  if (attemptedOverrides.length > 0) {
53
64
  logging_1.logger.warn("Rate limit overrides ignored", {
54
- preset: opts?.mode || 'default',
65
+ layer: "rate-limit-manager",
66
+ operation: "configure",
67
+ mode,
55
68
  ignoredOptions: attemptedOverrides
56
69
  });
57
70
  }
58
71
  }
59
- if (finalOptions.standardHeaders === undefined) {
60
- finalOptions.standardHeaders = true;
61
- }
62
- if (finalOptions.legacyHeaders === undefined) {
63
- finalOptions.legacyHeaders = false;
64
- }
72
+ finalOptions.standardHeaders ?? (finalOptions.standardHeaders = true);
73
+ finalOptions.legacyHeaders ?? (finalOptions.legacyHeaders = false);
65
74
  try {
66
- logging_1.logger.info("Applying rate limiting", {
67
- mode: opts?.mode || 'default',
75
+ logging_1.logger.info("Rate limiting applied", {
76
+ layer: "rate-limit-manager",
77
+ operation: "apply",
78
+ mode,
68
79
  windowMs: finalOptions.windowMs,
69
80
  max: finalOptions.max
70
81
  });
71
82
  return this.primaryAdapter.getMiddleware(finalOptions);
72
83
  }
73
84
  catch (err) {
74
- logging_1.logger.warn("Primary rate limiter failed → fallback", {
75
- error: err?.message
85
+ logging_1.logger.warn("Primary rate limiter failed", {
86
+ layer: "rate-limit-manager",
87
+ operation: "apply",
88
+ mode,
89
+ reason: err?.message
76
90
  });
77
91
  if (!this.fallbackAdapter) {
78
- throw new AdapterError_js_1.AdapterError("Rate limiters failed; no fallback adapter.");
92
+ throw new AdapterError_1.AdapterError("Rate limiters failed; no fallback adapter configured.");
79
93
  }
80
94
  try {
81
- logging_1.logger.info("Using fallback rate limiter");
95
+ logging_1.logger.warn("Using fallback rate limiter", {
96
+ layer: "rate-limit-manager",
97
+ operation: "fallback",
98
+ mode
99
+ });
82
100
  return this.fallbackAdapter.getMiddleware(finalOptions);
83
101
  }
84
102
  catch (fallbackErr) {
85
- logging_1.logger.error("Fallback limiter also failed", {
86
- error: fallbackErr?.message
103
+ logging_1.logger.error("Fallback rate limiter failed", {
104
+ layer: "rate-limit-manager",
105
+ operation: "fallback",
106
+ mode,
107
+ reason: fallbackErr?.message
87
108
  });
88
- throw new AdapterError_js_1.AdapterError("Both primary and fallback limiters failed.");
109
+ throw new AdapterError_1.AdapterError("Both primary and fallback rate limiters failed.");
89
110
  }
90
111
  }
91
112
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RateLimitManager.js","sourceRoot":"","sources":["../../src/managers/RateLimitManager.ts"],"names":[],"mappings":"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","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}"]}
1
+ {"version":3,"file":"RateLimitManager.js","sourceRoot":"","sources":["../../src/managers/RateLimitManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { HiSecureConfig } from \"../core/types/HiSecureConfig\";\r\nimport { AdapterError } from \"../core/errors/AdapterError\";\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 logger.info(\"RateLimitManager initialized\", {\r\n layer: \"rate-limit-manager\",\r\n primaryConfigured: true,\r\n fallbackConfigured: !!fallbackAdapter\r\n });\r\n }\r\n\r\n middleware(opts?: { mode?: \"strict\" | \"relaxed\" | \"api\"; options?: any }) {\r\n let finalOptions: any = {};\r\n const mode = opts?.mode || \"default\";\r\n\r\n if (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 (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 (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 = [\r\n \"message\",\r\n \"skipFailedRequests\",\r\n \"standardHeaders\",\r\n \"legacyHeaders\"\r\n ];\r\n\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\r\n if (attemptedOverrides.length > 0) {\r\n logger.warn(\"Rate limit overrides ignored\", {\r\n layer: \"rate-limit-manager\",\r\n operation: \"configure\",\r\n mode,\r\n ignoredOptions: attemptedOverrides\r\n });\r\n }\r\n }\r\n\r\n finalOptions.standardHeaders ??= true;\r\n finalOptions.legacyHeaders ??= false;\r\n\r\n try {\r\n logger.info(\"Rate limiting applied\", {\r\n layer: \"rate-limit-manager\",\r\n operation: \"apply\",\r\n mode,\r\n windowMs: finalOptions.windowMs,\r\n max: finalOptions.max\r\n });\r\n\r\n return this.primaryAdapter.getMiddleware(finalOptions);\r\n\r\n } catch (err: any) {\r\n logger.warn(\"Primary rate limiter failed\", {\r\n layer: \"rate-limit-manager\",\r\n operation: \"apply\",\r\n mode,\r\n reason: err?.message\r\n });\r\n\r\n if (!this.fallbackAdapter) {\r\n throw new AdapterError(\r\n \"Rate limiters failed; no fallback adapter configured.\"\r\n );\r\n }\r\n\r\n try {\r\n logger.warn(\"Using fallback rate limiter\", {\r\n layer: \"rate-limit-manager\",\r\n operation: \"fallback\",\r\n mode\r\n });\r\n\r\n return this.fallbackAdapter.getMiddleware(finalOptions);\r\n\r\n } catch (fallbackErr: any) {\r\n logger.error(\"Fallback rate limiter failed\", {\r\n layer: \"rate-limit-manager\",\r\n operation: \"fallback\",\r\n mode,\r\n reason: fallbackErr?.message\r\n });\r\n\r\n throw new AdapterError(\r\n \"Both primary and fallback rate limiters failed.\"\r\n );\r\n }\r\n }\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
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
+ {"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;IAU/E,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,MAAM;IA6B9C,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IACZ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;CAsE7C"}
@@ -1,26 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SanitizerManager = void 0;
4
- const SanitizerError_js_1 = require("../core/errors/SanitizerError.js");
4
+ const SanitizerError_1 = require("../core/errors/SanitizerError");
5
5
  const logging_1 = require("../logging");
6
6
  class SanitizerManager {
7
7
  constructor(primary, fallback = null) {
8
8
  this.primary = primary;
9
9
  this.fallback = fallback;
10
+ logging_1.logger.info("SanitizerManager initialized", {
11
+ layer: "sanitizer-manager",
12
+ fallbackEnabled: !!fallback
13
+ });
10
14
  }
11
15
  sanitize(value, options) {
12
- if (typeof value !== 'string') {
16
+ if (typeof value !== "string") {
13
17
  return value;
14
18
  }
15
19
  try {
16
20
  return this.primary.sanitize(value, options);
17
21
  }
18
22
  catch (err) {
19
- logging_1.logger.warn("Primary sanitizer failed", { error: err?.message });
23
+ logging_1.logger.warn("Primary sanitizer failed", {
24
+ layer: "sanitizer-manager",
25
+ operation: "sanitize",
26
+ reason: err?.message
27
+ });
20
28
  if (!this.fallback) {
21
- throw new SanitizerError_js_1.SanitizerError("Primary sanitizer failed and no fallback available.");
29
+ throw new SanitizerError_1.SanitizerError("Primary sanitizer failed and no fallback available.");
22
30
  }
23
- logging_1.logger.info("Using fallback sanitizer");
31
+ logging_1.logger.warn("Sanitizer fallback used", {
32
+ layer: "sanitizer-manager",
33
+ operation: "sanitize"
34
+ });
24
35
  return this.fallback.sanitize(value, options);
25
36
  }
26
37
  }
@@ -39,7 +50,10 @@ class SanitizerManager {
39
50
  throw err;
40
51
  }
41
52
  fallbackTriggered = true;
42
- logging_1.logger.warn("Switching to fallback sanitizer for this request");
53
+ logging_1.logger.warn("Switching to fallback sanitizer for request", {
54
+ layer: "sanitizer-manager",
55
+ operation: "middleware"
56
+ });
43
57
  return this.fallback.sanitize(value, options);
44
58
  }
45
59
  };
@@ -53,19 +67,20 @@ class SanitizerManager {
53
67
  sanitizedBody[key] = safeSanitize(value);
54
68
  }
55
69
  else if (Array.isArray(value)) {
56
- sanitizedBody[key] = value.map(item => typeof item === "string" ? safeSanitize(item) : item);
57
- }
58
- else if (value && typeof value === "object") {
59
- sanitizedBody[key] = value;
70
+ sanitizedBody[key] = value.map(item => typeof item === "string"
71
+ ? safeSanitize(item)
72
+ : item);
60
73
  }
61
74
  else {
62
75
  sanitizedBody[key] = value;
63
76
  }
64
77
  }
65
78
  req.sanitizedBody = sanitizedBody;
66
- logging_1.logger.debug("Request body sanitized", {
67
- originalKeys: Object.keys(originalBody),
68
- sanitizedKeys: Object.keys(sanitizedBody),
79
+ // visible + safe info
80
+ logging_1.logger.info("Request body sanitized", {
81
+ layer: "sanitizer-manager",
82
+ operation: "middleware",
83
+ fieldCount: Object.keys(sanitizedBody).length,
69
84
  usedFallback: fallbackTriggered
70
85
  });
71
86
  }
@@ -73,9 +88,11 @@ class SanitizerManager {
73
88
  }
74
89
  catch (err) {
75
90
  logging_1.logger.error("Sanitizer middleware failed", {
76
- error: err?.message
91
+ layer: "sanitizer-manager",
92
+ operation: "middleware",
93
+ reason: err?.message
77
94
  });
78
- next(new SanitizerError_js_1.SanitizerError("Sanitizer middleware failure"));
95
+ next(new SanitizerError_1.SanitizerError("Sanitizer middleware failure"));
79
96
  }
80
97
  };
81
98
  }
@@ -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.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
+ {"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\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 logger.info(\"SanitizerManager initialized\", {\r\n layer: \"sanitizer-manager\",\r\n fallbackEnabled: !!fallback\r\n });\r\n }\r\n\r\n sanitize(value: string, options?: any): string {\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\", {\r\n layer: \"sanitizer-manager\",\r\n operation: \"sanitize\",\r\n reason: err?.message\r\n });\r\n\r\n if (!this.fallback) {\r\n throw new SanitizerError(\r\n \"Primary sanitizer failed and no fallback available.\"\r\n );\r\n }\r\n\r\n logger.warn(\"Sanitizer fallback used\", {\r\n layer: \"sanitizer-manager\",\r\n operation: \"sanitize\"\r\n });\r\n\r\n return this.fallback.sanitize(value, options);\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\r\n logger.warn(\"Switching to fallback sanitizer for request\", {\r\n layer: \"sanitizer-manager\",\r\n operation: \"middleware\"\r\n });\r\n\r\n return this.fallback.sanitize(value, options);\r\n }\r\n };\r\n\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 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\"\r\n ? safeSanitize(item)\r\n : item\r\n );\r\n } else {\r\n sanitizedBody[key] = value;\r\n }\r\n }\r\n\r\n req.sanitizedBody = sanitizedBody;\r\n\r\n // ✅ visible + safe info\r\n logger.info(\"Request body sanitized\", {\r\n layer: \"sanitizer-manager\",\r\n operation: \"middleware\",\r\n fieldCount: Object.keys(sanitizedBody).length,\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 layer: \"sanitizer-manager\",\r\n operation: \"middleware\",\r\n reason: err?.message\r\n });\r\n\r\n next(new SanitizerError(\"Sanitizer middleware failure\"));\r\n }\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":"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
+ {"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;IAU1E,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,IAST,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG;CAmE5C"}
@@ -2,11 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ValidatorManager = void 0;
4
4
  const logging_1 = require("../logging");
5
- const ValidationError_js_1 = require("../core/errors/ValidationError.js");
5
+ const ValidationError_1 = require("../core/errors/ValidationError");
6
6
  class ValidatorManager {
7
7
  constructor(zodAdapter, expressAdapter) {
8
8
  this.zodAdapter = zodAdapter;
9
9
  this.expressAdapter = expressAdapter;
10
+ logging_1.logger.info("ValidatorManager initialized", {
11
+ layer: "validator-manager",
12
+ adapters: ["zod", "express-validator"]
13
+ });
10
14
  }
11
15
  validate(schema) {
12
16
  const isZod = schema &&
@@ -16,17 +20,25 @@ class ValidatorManager {
16
20
  const isExpressValidator = Array.isArray(schema);
17
21
  return (req, res, next) => {
18
22
  let middleware;
23
+ let adapterUsed = "none";
19
24
  if (isZod) {
20
- logging_1.logger.debug("Using Zod adapter");
25
+ adapterUsed = "zod";
21
26
  middleware = this.zodAdapter.validate(schema);
22
27
  }
23
28
  else if (isExpressValidator) {
24
- logging_1.logger.debug(" Using express-validator adapter");
29
+ adapterUsed = "express-validator";
25
30
  middleware = this.expressAdapter.validate(schema);
26
31
  }
27
32
  else {
28
33
  return next();
29
34
  }
35
+ logging_1.logger.info("Validation adapter selected", {
36
+ layer: "validator-manager",
37
+ operation: "select",
38
+ adapter: adapterUsed,
39
+ path: req.path,
40
+ method: req.method
41
+ });
30
42
  // CASE 1 — express-validator returns ARRAY
31
43
  if (Array.isArray(middleware)) {
32
44
  let idx = 0;
@@ -35,17 +47,23 @@ class ValidatorManager {
35
47
  return next(err);
36
48
  const fn = middleware[idx++];
37
49
  if (!fn)
38
- return next(); // done
50
+ return next();
39
51
  try {
40
52
  fn(req, res, run);
41
53
  }
42
54
  catch (error) {
43
- next(new ValidationError_js_1.ValidationError(error.message));
55
+ logging_1.logger.error("Validation middleware execution failed", {
56
+ layer: "validator-manager",
57
+ operation: "execute",
58
+ adapter: adapterUsed,
59
+ reason: error?.message
60
+ });
61
+ next(new ValidationError_1.ValidationError(error.message));
44
62
  }
45
63
  };
46
64
  return run();
47
65
  }
48
- // CASE 2 — Zod returns SINGLE MIDDLEWARE
66
+ // CASE 2 — Zod returns SINGLE middleware
49
67
  try {
50
68
  middleware(req, res, (err) => {
51
69
  if (err)
@@ -54,7 +72,13 @@ class ValidatorManager {
54
72
  });
55
73
  }
56
74
  catch (err) {
57
- next(new ValidationError_js_1.ValidationError(err.message));
75
+ logging_1.logger.error("Validation middleware execution failed", {
76
+ layer: "validator-manager",
77
+ operation: "execute",
78
+ adapter: adapterUsed,
79
+ reason: err?.message
80
+ });
81
+ next(new ValidationError_1.ValidationError(err.message));
58
82
  }
59
83
  };
60
84
  }
@@ -1 +1 @@
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,mBAAmB,CAAC,CAAC;gBAClC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAClD,CAAC;iBACI,IAAI,kBAAkB,EAAE,CAAC;gBAC1B,gBAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBACjD,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
+ {"version":3,"file":"ValidatorManager.js","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { logger } from \"../logging\";\r\nimport { ValidationError } from \"../core/errors/ValidationError\";\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 logger.info(\"ValidatorManager initialized\", {\r\n layer: \"validator-manager\",\r\n adapters: [\"zod\", \"express-validator\"]\r\n });\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 let adapterUsed: \"zod\" | \"express-validator\" | \"none\" = \"none\";\r\n\r\n if (isZod) {\r\n adapterUsed = \"zod\";\r\n middleware = this.zodAdapter.validate(schema);\r\n } else if (isExpressValidator) {\r\n adapterUsed = \"express-validator\";\r\n middleware = this.expressAdapter.validate(schema);\r\n } else {\r\n return next();\r\n }\r\n\r\n logger.info(\"Validation adapter selected\", {\r\n layer: \"validator-manager\",\r\n operation: \"select\",\r\n adapter: adapterUsed,\r\n path: req.path,\r\n method: req.method\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();\r\n\r\n try {\r\n fn(req, res, run);\r\n } catch (error: any) {\r\n logger.error(\"Validation middleware execution failed\", {\r\n layer: \"validator-manager\",\r\n operation: \"execute\",\r\n adapter: adapterUsed,\r\n reason: error?.message\r\n });\r\n\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 logger.error(\"Validation middleware execution failed\", {\r\n layer: \"validator-manager\",\r\n operation: \"execute\",\r\n adapter: adapterUsed,\r\n reason: err?.message\r\n });\r\n\r\n next(new ValidationError(err.message));\r\n }\r\n };\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,14 +1,10 @@
1
1
  {
2
2
  "name": "hi-secure",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Unified security layer for Express.js: authentication, validation, sanitization, rate limiting and CORS",
5
+ "license": "MIT",
5
6
  "main": "dist/index.js",
6
7
  "types": "dist/index.d.ts",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/100NikhilBro/hi-secure.git"
10
- },
11
- "homepage": "https://github.com/100NikhilBro/hi-secure#readme",
12
8
  "keywords": [
13
9
  "express",
14
10
  "security",
package/readme.md CHANGED
@@ -97,7 +97,7 @@ Managing these separately leads to duplicated logic, configuration drift and sub
97
97
 
98
98
  <tr>
99
99
  <td>Logging</td>
100
- <td>Beta</td>
100
+ <td>Better</td>
101
101
  <td>Structured internal logs</td>
102
102
  </tr>
103
103
  </table>
@@ -324,7 +324,7 @@ Choose the style based on complexity and ownership.
324
324
 
325
325
  <h4>express-validator (Rule-Based, Inline)</h4>
326
326
 
327
- <pre><code>import { body } from "express-validator";
327
+ <pre><code>import { HiSecure , body } from "hi-secure";
328
328
 
329
329
  router.post(
330
330
  "/register",
@@ -346,7 +346,7 @@ router.post(
346
346
 
347
347
  <h4>Zod (Schema-Based, Reusable)</h4>
348
348
 
349
- <pre><code>import { z } from "zod";
349
+ <pre><code>import { HiSecure , z } from "hi-secure";
350
350
 
351
351
  const registerSchema = z.object({
352
352
  email: z.string().email(),
@@ -455,9 +455,6 @@ HiSecure.getInstance({
455
455
 
456
456
  <hr/>
457
457
 
458
- <h2>Final Authentication Setup</h2>
459
-
460
- <hr/>
461
458
 
462
459
  <h2>🔐 Final Authentication Setup</h2>
463
460
 
@@ -3,12 +3,10 @@ import { AdapterError } from "../core/errors/AdapterError";
3
3
  import { logger } from "../logging";
4
4
 
5
5
  export class ArgonAdapter {
6
- private options: argon2.Options | undefined;
6
+ private options?: argon2.Options;
7
7
 
8
8
  constructor(options?: argon2.Options) {
9
- if (options) {
10
- this.options = options;
11
- }
9
+ this.options = options;
12
10
  }
13
11
 
14
12
  async hash(value: string): Promise<string> {
@@ -18,8 +16,11 @@ export class ArgonAdapter {
18
16
  : await argon2.hash(value);
19
17
  } catch (err: any) {
20
18
  logger.error("Argon2 hashing failed", {
21
- error: err?.message || err
19
+ adapter: "argon2",
20
+ operation: "hash",
21
+ reason: err?.message
22
22
  });
23
+
23
24
  throw new AdapterError("Argon2 hashing failed.");
24
25
  }
25
26
  }
@@ -33,8 +34,11 @@ export class ArgonAdapter {
33
34
  return await argon2.verify(hashed, value);
34
35
  } catch (err: any) {
35
36
  logger.error("Argon2 verify failed", {
36
- error: err?.message || err
37
+ adapter: "argon2",
38
+ operation: "verify",
39
+ reason: err?.message
37
40
  });
41
+
38
42
  throw new AdapterError("Argon2 verify failed.");
39
43
  }
40
44
  }
@@ -14,8 +14,10 @@ export class BcryptAdapter {
14
14
  return await bcrypt.hash(value, this.saltRounds);
15
15
  } catch (err: any) {
16
16
  logger.error("Bcrypt hashing failed", {
17
- error: err?.message || err,
18
- saltRounds: this.saltRounds
17
+ adapter: "bcrypt",
18
+ operation: "hash",
19
+ saltRounds: this.saltRounds,
20
+ reason: err?.message
19
21
  });
20
22
 
21
23
  throw new AdapterError("Bcrypt hashing failed.");
@@ -35,15 +37,12 @@ export class BcryptAdapter {
35
37
  return await bcrypt.compare(value, hashed);
36
38
  } catch (err: any) {
37
39
  logger.error("Bcrypt verify failed", {
38
- error: err?.message || err
40
+ adapter: "bcrypt",
41
+ operation: "verify",
42
+ reason: err?.message
39
43
  });
40
44
 
41
45
  throw new AdapterError("Bcrypt verify failed.");
42
46
  }
43
47
  }
44
48
  }
45
-
46
-
47
-
48
-
49
-
@@ -1,6 +1,6 @@
1
1
  import rateLimit from "express-rate-limit";
2
- import { logger } from "../logging/index.js";
3
- import { AdapterError } from "../core/errors/AdapterError.js";
2
+ import { logger } from "../logging";
3
+ import { AdapterError } from "../core/errors/AdapterError";
4
4
 
5
5
  export interface RateLimitOptions {
6
6
  windowMs?: number;
@@ -16,7 +16,7 @@ export class ExpressRLAdapter {
16
16
  getMiddleware(options: RateLimitOptions = {}) {
17
17
  try {
18
18
  const defaultOptions = {
19
- windowMs: 15 * 60 * 1000,
19
+ windowMs: 15 * 60 * 1000,
20
20
  max: 100,
21
21
  message: { error: "Too many requests" },
22
22
  standardHeaders: true,
@@ -25,21 +25,26 @@ export class ExpressRLAdapter {
25
25
  };
26
26
 
27
27
  const finalOptions = { ...defaultOptions, ...options };
28
-
28
+
29
29
  const limiter = rateLimit(finalOptions);
30
+
30
31
 
31
- logger.debug("Express rate limiter configured", {
32
+ logger.info("Express rate limiter configured", {
33
+ adapter: "express-rate-limit",
34
+ operation: "configure",
32
35
  windowMs: finalOptions.windowMs,
33
36
  max: finalOptions.max
34
37
  });
35
38
 
36
39
  return limiter;
37
-
38
40
  } catch (err: any) {
39
- logger.error("ExpressRLAdapter: failed to create limiter", {
40
- error: err?.message || err
41
+ logger.error("Express rate limiter setup failed", {
42
+ adapter: "express-rate-limit",
43
+ operation: "configure",
44
+ reason: err?.message
41
45
  });
46
+
42
47
  throw new AdapterError("Express rate limiter creation failed.");
43
48
  }
44
49
  }
45
- }
50
+ }