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,11 +1,10 @@
1
- import { JWTAdapter } from "../adapters/JWTAdapter.js";
2
- import { GoogleAdapter } from "../adapters/GoogleAdapter.js";
3
- import { AdapterError } from "../core/errors/AdapterError.js";
4
- import { HttpError } from "../core/errors/HttpError.js";
1
+ import { JWTAdapter } from "../adapters/JWTAdapter";
2
+ import { GoogleAdapter } from "../adapters/GoogleAdapter";
3
+ import { AdapterError } from "../core/errors/AdapterError";
4
+ import { HttpError } from "../core/errors/HttpError";
5
5
  import { Request, Response, NextFunction } from "express";
6
6
  import { logger } from "../logging";
7
7
 
8
-
9
8
  export interface AuthOptions {
10
9
  jwtSecret: string;
11
10
  jwtExpiresIn?: string | number;
@@ -27,29 +26,47 @@ export class AuthManager {
27
26
  }
28
27
 
29
28
  if (opts.jwtSecret.length < 32) {
30
- logger.warn(" JWT secret is less than 32 characters - consider using a stronger secret");
29
+ logger.warn("Weak JWT secret detected", {
30
+ layer: "auth-manager",
31
+ operation: "init",
32
+ secretLength: opts.jwtSecret.length
33
+ });
31
34
  }
32
35
 
33
- logger.info("AuthManager initialized");
36
+ logger.info("AuthManager initialized", {
37
+ layer: "auth-manager",
38
+ jwtExpiresIn: opts.jwtExpiresIn ?? "1d",
39
+ googleEnabled: !!opts.googleClientId
40
+ });
34
41
 
35
42
  this.jwtAdapter = new JWTAdapter({
36
43
  secret: opts.jwtSecret,
37
- expiresIn: opts.jwtExpiresIn ?? "1d",
44
+ expiresIn: opts.jwtExpiresIn ?? "1d"
38
45
  });
39
46
 
40
47
  if (opts.googleClientId) {
41
48
  this.googleAdapter = new GoogleAdapter(opts.googleClientId);
42
- logger.info("GoogleAdapter enabled");
49
+ logger.info("Google authentication enabled", {
50
+ layer: "auth-manager"
51
+ });
43
52
  }
44
53
  }
45
54
 
46
- sign(payload: object, options?: { expiresIn?: string | number, jti?: string }) {
47
- logger.info("JWT Sign called");
55
+ sign(payload: object, options?: { expiresIn?: string | number; jti?: string }) {
56
+ logger.info("JWT sign requested", {
57
+ layer: "auth-manager",
58
+ operation: "sign"
59
+ });
60
+
48
61
  return this.jwtAdapter.sign(payload, options);
49
62
  }
50
63
 
51
64
  verify(token: string) {
52
- logger.info("JWT Verify called");
65
+ logger.info("JWT verify requested", {
66
+ layer: "auth-manager",
67
+ operation: "verify"
68
+ });
69
+
53
70
  return this.jwtAdapter.verify(token);
54
71
  }
55
72
 
@@ -58,12 +75,20 @@ export class AuthManager {
58
75
  throw new AdapterError("GoogleAdapter not configured.");
59
76
  }
60
77
 
61
- logger.info("Google ID Token verify called");
78
+ logger.info("Google ID token verification requested", {
79
+ layer: "auth-manager",
80
+ operation: "google-verify"
81
+ });
62
82
 
63
83
  try {
64
84
  return await this.googleAdapter.verifyIdToken(idToken);
65
85
  } catch (err: any) {
66
- logger.error("Google ID Token verification failed", { error: err?.message });
86
+ logger.error("Google ID token verification failed", {
87
+ layer: "auth-manager",
88
+ operation: "google-verify",
89
+ reason: err?.message
90
+ });
91
+
67
92
  throw HttpError.Unauthorized("Invalid Google ID token");
68
93
  }
69
94
  }
@@ -72,27 +97,28 @@ export class AuthManager {
72
97
  const required = options?.required ?? true;
73
98
  const roles = options?.roles;
74
99
 
75
- return (req: Request, res: Response, next: NextFunction) => {
100
+ return (req: Request, _res: Response, next: NextFunction) => {
76
101
  const header = req.headers["authorization"];
77
102
 
78
-
79
103
  if (!required && !header) {
80
104
  return next();
81
105
  }
82
106
 
83
-
84
107
  if (!header) {
85
- logger.warn("Missing Authorization header", {
108
+ logger.warn("Authorization header missing", {
109
+ layer: "auth-manager",
110
+ operation: "protect",
86
111
  path: req.path,
87
112
  method: req.method
88
113
  });
89
114
  return next(HttpError.Unauthorized("Missing Authorization header"));
90
115
  }
91
116
 
92
-
93
117
  const [type, token] = String(header).split(" ");
94
118
  if (type !== "Bearer" || !token) {
95
- logger.warn("Invalid Authorization header", {
119
+ logger.warn("Invalid Authorization header format", {
120
+ layer: "auth-manager",
121
+ operation: "protect",
96
122
  path: req.path,
97
123
  method: req.method
98
124
  });
@@ -100,36 +126,40 @@ export class AuthManager {
100
126
  }
101
127
 
102
128
  try {
103
-
104
- // Verify JWT
105
129
  const decoded = this.verify(token);
106
-
107
- // Attach to request
130
+
108
131
  (req as any).auth = decoded;
109
- (req as any).user = decoded;
110
-
111
- // Role-based authorization - role added Middleware
132
+ (req as any).user = decoded;
133
+
112
134
  if (roles && roles.length > 0) {
113
- const userRole = (decoded as any).role || (decoded as any).roles?.[0];
135
+ const userRole =
136
+ (decoded as any).role || (decoded as any).roles?.[0];
137
+
114
138
  if (!userRole || !roles.includes(userRole)) {
115
- logger.warn("Insufficient permissions", {
139
+ logger.warn("Access denied: insufficient role", {
140
+ layer: "auth-manager",
141
+ operation: "authorize",
116
142
  path: req.path,
117
143
  requiredRoles: roles,
118
144
  userRole
119
145
  });
146
+
120
147
  return next(HttpError.Forbidden("Insufficient permissions"));
121
148
  }
122
149
  }
123
-
150
+
124
151
  return next();
125
152
  } catch (err: any) {
126
- logger.error("JWT verify failed", {
127
- error: err?.message,
153
+ logger.error("JWT authentication failed", {
154
+ layer: "auth-manager",
155
+ operation: "protect",
128
156
  path: req.path,
129
- method: req.method
157
+ method: req.method,
158
+ reason: err?.message
130
159
  });
160
+
131
161
  return next(HttpError.Unauthorized("Invalid or expired token"));
132
162
  }
133
163
  };
134
164
  }
135
- }
165
+ }
@@ -1,34 +1,41 @@
1
1
  import cors from "cors";
2
2
  import { logger } from "../logging";
3
- import { AdapterError } from "../core/errors/AdapterError.js";
3
+ import { AdapterError } from "../core/errors/AdapterError";
4
4
 
5
5
  export class CorsManager {
6
-
7
6
  middleware(options?: any) {
8
7
  try {
9
8
  const defaultOptions = {
10
- origin: '*',
11
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
12
- allowedHeaders: ['Content-Type', 'Authorization'],
9
+ origin: "*",
10
+ methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
11
+ allowedHeaders: ["Content-Type", "Authorization"],
13
12
  credentials: false,
14
13
  maxAge: 86400
15
14
  };
16
-
17
- const finalOptions = options ? { ...defaultOptions, ...options } : defaultOptions;
18
-
19
- logger.debug("CORS configured", {
15
+
16
+ const finalOptions = options
17
+ ? { ...defaultOptions, ...options }
18
+ : defaultOptions;
19
+
20
+ // ✅ visible + clean log
21
+ logger.info("CORS middleware configured", {
22
+ layer: "cors-manager",
23
+ operation: "init",
20
24
  origin: finalOptions.origin,
21
- methods: finalOptions.methods
25
+ methods: finalOptions.methods,
26
+ credentials: finalOptions.credentials
22
27
  });
23
-
28
+
24
29
  return cors(finalOptions);
25
-
30
+
26
31
  } catch (err: any) {
27
- logger.error(" CORS Manager: failed to create CORS middleware", {
28
- error: err?.message || err,
29
- options
32
+ logger.error("CORS middleware initialization failed", {
33
+ layer: "cors-manager",
34
+ operation: "init",
35
+ reason: err?.message
30
36
  });
37
+
31
38
  throw new AdapterError("CORS middleware initialization failed.");
32
39
  }
33
40
  }
34
- }
41
+ }
@@ -1,5 +1,5 @@
1
- import { AdapterError } from "../core/errors/AdapterError.js";
2
- import { HiSecureConfig } from "../core/types/HiSecureConfig.js";
1
+ import { AdapterError } from "../core/errors/AdapterError";
2
+ import { HiSecureConfig } from "../core/types/HiSecureConfig";
3
3
  import { logger } from "../logging";
4
4
 
5
5
  interface HashAdapter {
@@ -26,20 +26,33 @@ export class HashManager {
26
26
  this.config = config;
27
27
  this.primaryAdapter = primaryAdapter;
28
28
  this.fallbackAdapter = fallbackAdapter;
29
+
30
+ logger.info("HashManager initialized", {
31
+ layer: "hash-manager",
32
+ primary: config.primary,
33
+ fallbackEnabled: !!fallbackAdapter
34
+ });
29
35
  }
30
36
 
31
- async hash(value: string, options?: { allowFallback?: boolean }): Promise<HashResult> {
37
+ async hash(
38
+ value: string,
39
+ options?: { allowFallback?: boolean }
40
+ ): Promise<HashResult> {
32
41
  try {
33
42
  const hash = await this.primaryAdapter.hash(value);
43
+
34
44
  return {
35
45
  hash,
36
46
  algorithm: this.config.primary,
37
47
  usedFallback: false
38
48
  };
49
+
39
50
  } catch (err: any) {
40
51
  logger.warn("Primary hashing failed", {
41
- error: err.message,
42
- algorithm: this.config.primary
52
+ layer: "hash-manager",
53
+ operation: "hash",
54
+ algorithm: this.config.primary,
55
+ reason: err?.message
43
56
  });
44
57
 
45
58
  if (!options?.allowFallback || !this.fallbackAdapter) {
@@ -50,22 +63,30 @@ export class HashManager {
50
63
 
51
64
  try {
52
65
  const hash = await this.fallbackAdapter.hash(value);
53
-
54
- // Log security downgrade warning
55
- logger.warn("SECURITY DOWNGRADE: Using fallback hashing", {
66
+
67
+ // ⚠️ security downgrade log (VERY GOOD PRACTICE)
68
+ logger.warn("Hashing fallback used (security downgrade)", {
69
+ layer: "hash-manager",
70
+ operation: "hash",
56
71
  from: this.config.primary,
57
72
  to: this.config.fallback
58
73
  });
59
-
74
+
60
75
  return {
61
76
  hash,
62
- algorithm: this.config.fallback || 'bcrypt',
77
+ algorithm: this.config.fallback || "bcrypt",
63
78
  usedFallback: true
64
79
  };
80
+
65
81
  } catch (fallbackErr: any) {
66
82
  logger.error("Fallback hashing failed", {
67
- error: fallbackErr?.message,
83
+ layer: "hash-manager",
84
+ operation: "hash",
85
+ from: this.config.primary,
86
+ to: this.config.fallback,
87
+ reason: fallbackErr?.message
68
88
  });
89
+
69
90
  throw new AdapterError(
70
91
  "Both primary and fallback hashing failed."
71
92
  );
@@ -74,31 +95,39 @@ export class HashManager {
74
95
  }
75
96
 
76
97
  async verify(value: string, hashed: string): Promise<boolean> {
77
- // primary adapter - first
78
98
  try {
79
99
  return await this.primaryAdapter.verify(value, hashed);
100
+
80
101
  } catch (primaryErr: any) {
81
- logger.warn("Primary verify failed", {
82
- error: primaryErr?.message,
102
+ logger.warn("Primary hash verification failed", {
103
+ layer: "hash-manager",
104
+ operation: "verify",
105
+ algorithm: this.config.primary,
106
+ reason: primaryErr?.message
83
107
  });
84
108
 
85
- // fallback exists - try it
86
109
  if (this.fallbackAdapter) {
87
110
  try {
88
111
  return await this.fallbackAdapter.verify(value, hashed);
112
+
89
113
  } catch (fallbackErr: any) {
90
- logger.error(" Fallback verify failed", {
91
- error: fallbackErr?.message,
114
+ logger.error("Fallback hash verification failed", {
115
+ layer: "hash-manager",
116
+ operation: "verify",
117
+ from: this.config.primary,
118
+ to: this.config.fallback,
119
+ reason: fallbackErr?.message
92
120
  });
121
+
93
122
  throw new AdapterError(
94
123
  "Both primary and fallback verify failed."
95
124
  );
96
125
  }
97
126
  }
98
-
127
+
99
128
  throw new AdapterError(
100
129
  "Primary verify failed and no fallback adapter configured."
101
130
  );
102
131
  }
103
132
  }
104
- }
133
+ }
@@ -1,19 +1,35 @@
1
1
  import express from "express";
2
2
  import qs from "qs";
3
3
  import { logger } from "../logging";
4
- import { AdapterError } from "../core/errors/AdapterError.js";
4
+ import { AdapterError } from "../core/errors/AdapterError";
5
5
 
6
6
  export class JsonManager {
7
7
  middleware(options?: any) {
8
8
  try {
9
9
  const defaultOptions = {
10
- limit: '1mb',
10
+ limit: "1mb",
11
11
  inflate: true,
12
12
  strict: true
13
13
  };
14
- return express.json({ ...defaultOptions, ...(options || {}) });
14
+
15
+ const finalOptions = { ...defaultOptions, ...(options || {}) };
16
+
17
+ logger.info("JSON body parser configured", {
18
+ layer: "json-manager",
19
+ operation: "json",
20
+ limit: finalOptions.limit,
21
+ strict: finalOptions.strict
22
+ });
23
+
24
+ return express.json(finalOptions);
25
+
15
26
  } catch (err: any) {
16
- logger.error("JSON Manager: failed to create JSON parser");
27
+ logger.error("JSON body parser initialization failed", {
28
+ layer: "json-manager",
29
+ operation: "json",
30
+ reason: err?.message
31
+ });
32
+
17
33
  throw new AdapterError("JSON parser initialization failed.");
18
34
  }
19
35
  }
@@ -22,38 +38,64 @@ export class JsonManager {
22
38
  try {
23
39
  const defaultOptions = {
24
40
  extended: true,
25
- limit: '1mb',
41
+ limit: "1mb",
26
42
  parameterLimit: 1000
27
43
  };
28
- const opts = { ...defaultOptions, ...(options || {}) };
29
- return express.urlencoded(opts);
44
+
45
+ const finalOptions = { ...defaultOptions, ...(options || {}) };
46
+
47
+ logger.info("URL-encoded parser configured", {
48
+ layer: "json-manager",
49
+ operation: "urlencoded",
50
+ limit: finalOptions.limit,
51
+ parameterLimit: finalOptions.parameterLimit
52
+ });
53
+
54
+ return express.urlencoded(finalOptions);
55
+
30
56
  } catch (err: any) {
31
- logger.error("URL-encoded parser failed");
57
+ logger.error("URL-encoded parser initialization failed", {
58
+ layer: "json-manager",
59
+ operation: "urlencoded",
60
+ reason: err?.message
61
+ });
62
+
32
63
  throw new AdapterError("URL-encoded parser initialization failed.");
33
64
  }
34
65
  }
35
66
 
36
67
  queryParser(options?: any) {
37
- return (req: any, res: any, next: any) => {
68
+ return (req: any, _res: any, next: any) => {
38
69
  try {
39
- if (!req.parsedQuery && req.url.includes('?')) {
70
+ if (!req.parsedQuery && req.url.includes("?")) {
40
71
  const queryString = req.url.split("?")[1] || "";
72
+
41
73
  const parsed = qs.parse(queryString, {
42
74
  depth: 5,
43
75
  parameterLimit: 100,
44
76
  ...options
45
77
  });
46
-
78
+
47
79
  req.parsedQuery = parsed;
48
- logger.debug(" Query parsed", {
49
- keys: Object.keys(parsed)
80
+
81
+ // ✅ visible + safe info
82
+ logger.info("Query parameters parsed", {
83
+ layer: "json-manager",
84
+ operation: "query-parse",
85
+ keyCount: Object.keys(parsed).length
50
86
  });
51
87
  }
88
+
52
89
  next();
53
90
  } catch (err: any) {
54
- logger.error("Failed to parse query", { error: err?.message });
91
+ logger.error("Query parsing failed", {
92
+ layer: "json-manager",
93
+ operation: "query-parse",
94
+ reason: err?.message
95
+ });
96
+
55
97
  next(new AdapterError("Query parsing failed."));
56
98
  }
57
99
  };
58
100
  }
59
- }
101
+ }
@@ -1,5 +1,5 @@
1
- import { HiSecureConfig } from "../core/types/HiSecureConfig.js";
2
- import { AdapterError } from "../core/errors/AdapterError.js";
1
+ import { HiSecureConfig } from "../core/types/HiSecureConfig";
2
+ import { AdapterError } from "../core/errors/AdapterError";
3
3
  import { logger } from "../logging";
4
4
 
5
5
  interface RateLimiterAdapter {
@@ -19,26 +19,33 @@ export class RateLimitManager {
19
19
  this.config = config;
20
20
  this.primaryAdapter = primaryAdapter;
21
21
  this.fallbackAdapter = fallbackAdapter;
22
+
23
+ logger.info("RateLimitManager initialized", {
24
+ layer: "rate-limit-manager",
25
+ primaryConfigured: true,
26
+ fallbackConfigured: !!fallbackAdapter
27
+ });
22
28
  }
23
29
 
24
30
  middleware(opts?: { mode?: "strict" | "relaxed" | "api"; options?: any }) {
25
31
  let finalOptions: any = {};
32
+ const mode = opts?.mode || "default";
26
33
 
27
- if (opts?.mode === "strict") {
34
+ if (mode === "strict") {
28
35
  finalOptions = {
29
36
  windowMs: 10_000,
30
37
  max: 5,
31
38
  message: "Too many requests, please slow down."
32
39
  };
33
- } else if (opts?.mode === "relaxed") {
40
+ } else if (mode === "relaxed") {
34
41
  finalOptions = {
35
42
  windowMs: 60_000,
36
43
  max: 100,
37
44
  message: "Rate limit exceeded."
38
45
  };
39
- } else if (opts?.mode === "api") {
46
+ } else if (mode === "api") {
40
47
  finalOptions = {
41
- windowMs: 15 * 60 * 1000,
48
+ windowMs: 15 * 60 * 1000,
42
49
  max: 100,
43
50
  message: "API rate limit exceeded."
44
51
  };
@@ -47,63 +54,88 @@ export class RateLimitManager {
47
54
  windowMs: this.config.windowMs,
48
55
  max: this.config.maxRequests,
49
56
  message: this.config.message,
50
- standardHeaders: true,
51
- legacyHeaders: false
57
+ standardHeaders: true,
58
+ legacyHeaders: false
52
59
  };
53
60
  }
54
61
 
55
62
  if (opts?.options) {
56
- const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders', 'legacyHeaders'];
63
+ const allowedOverrides = [
64
+ "message",
65
+ "skipFailedRequests",
66
+ "standardHeaders",
67
+ "legacyHeaders"
68
+ ];
69
+
57
70
  for (const key of allowedOverrides) {
58
71
  if (opts.options[key] !== undefined) {
59
72
  finalOptions[key] = opts.options[key];
60
73
  }
61
74
  }
62
-
75
+
63
76
  const attemptedOverrides = Object.keys(opts.options).filter(
64
- k => !allowedOverrides.includes(k) && k !== 'mode'
77
+ k => !allowedOverrides.includes(k) && k !== "mode"
65
78
  );
79
+
66
80
  if (attemptedOverrides.length > 0) {
67
81
  logger.warn("Rate limit overrides ignored", {
68
- preset: opts?.mode || 'default',
82
+ layer: "rate-limit-manager",
83
+ operation: "configure",
84
+ mode,
69
85
  ignoredOptions: attemptedOverrides
70
86
  });
71
87
  }
72
88
  }
73
89
 
74
- if (finalOptions.standardHeaders === undefined) {
75
- finalOptions.standardHeaders = true;
76
- }
77
- if (finalOptions.legacyHeaders === undefined) {
78
- finalOptions.legacyHeaders = false;
79
- }
90
+ finalOptions.standardHeaders ??= true;
91
+ finalOptions.legacyHeaders ??= false;
80
92
 
81
93
  try {
82
- logger.info("Applying rate limiting", {
83
- mode: opts?.mode || 'default',
94
+ logger.info("Rate limiting applied", {
95
+ layer: "rate-limit-manager",
96
+ operation: "apply",
97
+ mode,
84
98
  windowMs: finalOptions.windowMs,
85
99
  max: finalOptions.max
86
100
  });
87
-
101
+
88
102
  return this.primaryAdapter.getMiddleware(finalOptions);
103
+
89
104
  } catch (err: any) {
90
- logger.warn("Primary rate limiter failed → fallback", {
91
- error: err?.message
105
+ logger.warn("Primary rate limiter failed", {
106
+ layer: "rate-limit-manager",
107
+ operation: "apply",
108
+ mode,
109
+ reason: err?.message
92
110
  });
93
111
 
94
112
  if (!this.fallbackAdapter) {
95
- throw new AdapterError("Rate limiters failed; no fallback adapter.");
113
+ throw new AdapterError(
114
+ "Rate limiters failed; no fallback adapter configured."
115
+ );
96
116
  }
97
117
 
98
118
  try {
99
- logger.info("Using fallback rate limiter");
119
+ logger.warn("Using fallback rate limiter", {
120
+ layer: "rate-limit-manager",
121
+ operation: "fallback",
122
+ mode
123
+ });
124
+
100
125
  return this.fallbackAdapter.getMiddleware(finalOptions);
126
+
101
127
  } catch (fallbackErr: any) {
102
- logger.error("Fallback limiter also failed", {
103
- error: fallbackErr?.message
128
+ logger.error("Fallback rate limiter failed", {
129
+ layer: "rate-limit-manager",
130
+ operation: "fallback",
131
+ mode,
132
+ reason: fallbackErr?.message
104
133
  });
105
- throw new AdapterError("Both primary and fallback limiters failed.");
134
+
135
+ throw new AdapterError(
136
+ "Both primary and fallback rate limiters failed."
137
+ );
106
138
  }
107
139
  }
108
140
  }
109
- }
141
+ }