hi-secure 1.0.7 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/ArgonAdapter.js +1 -1
- package/dist/adapters/ArgonAdapter.js.map +1 -1
- package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressRLAdapter.js +1 -2
- package/dist/adapters/ExpressRLAdapter.js.map +1 -1
- package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressValidatorAdapter.js +1 -39
- package/dist/adapters/ExpressValidatorAdapter.js.map +1 -1
- package/dist/adapters/GoogleAdapter.d.ts.map +1 -1
- package/dist/adapters/GoogleAdapter.js +0 -101
- package/dist/adapters/GoogleAdapter.js.map +1 -1
- package/dist/adapters/JWTAdapter.d.ts.map +1 -1
- package/dist/adapters/JWTAdapter.js +3 -210
- package/dist/adapters/JWTAdapter.js.map +1 -1
- package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -1
- package/dist/adapters/RLFlexibleAdapter.js +0 -52
- package/dist/adapters/RLFlexibleAdapter.js.map +1 -1
- package/dist/adapters/SanitizeHtmlAdapter.d.ts +0 -3
- package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -1
- package/dist/adapters/SanitizeHtmlAdapter.js +2 -71
- package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -1
- package/dist/adapters/XSSAdapter.d.ts +0 -10
- package/dist/adapters/XSSAdapter.d.ts.map +1 -1
- package/dist/adapters/XSSAdapter.js +2 -19
- package/dist/adapters/XSSAdapter.js.map +1 -1
- package/dist/adapters/ZodAdapter.d.ts.map +1 -1
- package/dist/adapters/ZodAdapter.js +2 -6
- package/dist/adapters/ZodAdapter.js.map +1 -1
- package/dist/core/HiSecure.d.ts +0 -2
- package/dist/core/HiSecure.d.ts.map +1 -1
- package/dist/core/HiSecure.js +8 -20
- package/dist/core/HiSecure.js.map +1 -1
- package/dist/core/useSecure.d.ts +0 -3
- package/dist/core/useSecure.d.ts.map +1 -1
- package/dist/core/useSecure.js +1 -5
- package/dist/core/useSecure.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/managers/AuthManager.d.ts.map +1 -1
- package/dist/managers/AuthManager.js +1 -89
- package/dist/managers/AuthManager.js.map +1 -1
- package/dist/managers/CorsManager.d.ts.map +1 -1
- package/dist/managers/CorsManager.js +1 -19
- package/dist/managers/CorsManager.js.map +1 -1
- package/dist/managers/HashManager.d.ts.map +1 -1
- package/dist/managers/HashManager.js +0 -243
- package/dist/managers/HashManager.js.map +1 -1
- package/dist/managers/JsonManager.d.ts.map +1 -1
- package/dist/managers/JsonManager.js +1 -77
- package/dist/managers/JsonManager.js.map +1 -1
- package/dist/managers/RateLimitManager.d.ts.map +1 -1
- package/dist/managers/RateLimitManager.js +3 -17
- package/dist/managers/RateLimitManager.js.map +1 -1
- package/dist/managers/SanitizerManager.d.ts +0 -6
- package/dist/managers/SanitizerManager.d.ts.map +1 -1
- package/dist/managers/SanitizerManager.js +1 -213
- package/dist/managers/SanitizerManager.js.map +1 -1
- package/dist/managers/ValidatorManager.d.ts.map +1 -1
- package/dist/managers/ValidatorManager.js +1 -109
- package/dist/managers/ValidatorManager.js.map +1 -1
- package/dist/middlewares/errorHandler.d.ts.map +1 -1
- package/dist/middlewares/errorHandler.js +0 -19
- package/dist/middlewares/errorHandler.js.map +1 -1
- package/dist/utils/deepFreeze.d.ts.map +1 -1
- package/dist/utils/deepFreeze.js +0 -25
- package/dist/utils/deepFreeze.js.map +1 -1
- package/dist/utils/deepMerge.d.ts.map +1 -1
- package/dist/utils/deepMerge.js +0 -26
- package/dist/utils/deepMerge.js.map +1 -1
- package/dist/utils/normalizeOptions.d.ts +1 -3
- package/dist/utils/normalizeOptions.d.ts.map +1 -1
- package/dist/utils/normalizeOptions.js +8 -9
- package/dist/utils/normalizeOptions.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/ArgonAdapter.ts +1 -1
- package/src/adapters/ExpressRLAdapter.ts +1 -2
- package/src/adapters/ExpressValidatorAdapter.ts +1 -54
- package/src/adapters/GoogleAdapter.ts +0 -129
- package/src/adapters/JWTAdapter.ts +5 -259
- package/src/adapters/RLFlexibleAdapter.ts +2 -65
- package/src/adapters/SanitizeHtmlAdapter.ts +3 -87
- package/src/adapters/XSSAdapter.ts +11 -19
- package/src/adapters/ZodAdapter.ts +2 -51
- package/src/core/HiSecure.ts +13 -24
- package/src/core/useSecure.ts +5 -7
- package/src/index.ts +4 -5
- package/src/managers/AuthManager.ts +5 -109
- package/src/managers/CorsManager.ts +1 -25
- package/src/managers/HashManager.ts +0 -286
- package/src/managers/JsonManager.ts +1 -91
- package/src/managers/RateLimitManager.ts +3 -262
- package/src/managers/SanitizerManager.ts +4 -263
- package/src/managers/ValidatorManager.ts +1 -135
- package/src/middlewares/errorHandler.ts +1 -176
- package/src/utils/deepFreeze.ts +0 -32
- package/src/utils/deepMerge.ts +0 -35
- package/src/utils/normalizeOptions.ts +16 -133
- package/src/examples/e1.ts +0 -1
- package/src/test/t1.ts +0 -1
|
@@ -1,95 +1,9 @@
|
|
|
1
|
-
// // import express from "express";
|
|
2
|
-
// // import { logger } from "../logging";
|
|
3
|
-
// // import { AdapterError } from "../core/errors/AdapterError";
|
|
4
|
-
|
|
5
|
-
// // export class JsonManager {
|
|
6
|
-
|
|
7
|
-
// // /**
|
|
8
|
-
// // * JSON parser middleware — global + dynamic override
|
|
9
|
-
// // */
|
|
10
|
-
// // middleware(options?: any) {
|
|
11
|
-
// // try {
|
|
12
|
-
// // const opts = options || {};
|
|
13
|
-
// // return express.json(opts);
|
|
14
|
-
// // } catch (err: any) {
|
|
15
|
-
// // logger.error("❌ JSON Manager: failed to create JSON parser", {
|
|
16
|
-
// // error: err?.message || err
|
|
17
|
-
// // });
|
|
18
|
-
// // throw new AdapterError("JSON parser initialization failed.");
|
|
19
|
-
// // }
|
|
20
|
-
// // }
|
|
21
|
-
|
|
22
|
-
// // /**
|
|
23
|
-
// // * URL-encoded parser — same global + dynamic style
|
|
24
|
-
// // */
|
|
25
|
-
// // urlencoded(options?: any) {
|
|
26
|
-
// // try {
|
|
27
|
-
// // const opts = options || { extended: true };
|
|
28
|
-
// // return express.urlencoded(opts);
|
|
29
|
-
// // } catch (err: any) {
|
|
30
|
-
// // logger.error("❌ JSON Manager: failed to create urlencoded parser", {
|
|
31
|
-
// // error: err?.message || err
|
|
32
|
-
// // });
|
|
33
|
-
// // throw new AdapterError("URL-encoded parser initialization failed.");
|
|
34
|
-
// // }
|
|
35
|
-
// // }
|
|
36
|
-
// // }
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// import express from "express";
|
|
41
|
-
// import qs from "qs";
|
|
42
|
-
// import { logger } from "../logging";
|
|
43
|
-
// import { AdapterError } from "../core/errors/AdapterError.js";
|
|
44
|
-
|
|
45
|
-
// export class JsonManager {
|
|
46
|
-
|
|
47
|
-
// // JSON parser
|
|
48
|
-
// middleware(options?: any) {
|
|
49
|
-
// try {
|
|
50
|
-
// return express.json(options || {});
|
|
51
|
-
// } catch (err: any) {
|
|
52
|
-
// logger.error("❌ JSON Manager: failed to create JSON parser");
|
|
53
|
-
// throw new AdapterError("JSON parser initialization failed.");
|
|
54
|
-
// }
|
|
55
|
-
// }
|
|
56
|
-
|
|
57
|
-
// // URL-encoded parser
|
|
58
|
-
// urlencoded(options?: any) {
|
|
59
|
-
// try {
|
|
60
|
-
// const opts = options || { extended: true };
|
|
61
|
-
// return express.urlencoded(opts);
|
|
62
|
-
// } catch (err: any) {
|
|
63
|
-
// logger.error("❌ URL-encoded parser failed");
|
|
64
|
-
// throw new AdapterError("URL-encoded parser initialization failed.");
|
|
65
|
-
// }
|
|
66
|
-
// }
|
|
67
|
-
|
|
68
|
-
// // NEW: Query-string parser
|
|
69
|
-
// queryParser() {
|
|
70
|
-
// return (req: any, res: any, next: any) => {
|
|
71
|
-
// try {
|
|
72
|
-
// req.query = qs.parse(req.url.split("?")[1] || "");
|
|
73
|
-
// } catch (err: any) {
|
|
74
|
-
// logger.error("❌ Failed to parse query", { error: err?.message });
|
|
75
|
-
// throw new AdapterError("Query parsing failed.");
|
|
76
|
-
// }
|
|
77
|
-
// next();
|
|
78
|
-
// };
|
|
79
|
-
// }
|
|
80
|
-
// }
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// src/managers/JsonManager.ts - FIXED
|
|
86
1
|
import express from "express";
|
|
87
2
|
import qs from "qs";
|
|
88
3
|
import { logger } from "../logging";
|
|
89
4
|
import { AdapterError } from "../core/errors/AdapterError.js";
|
|
90
5
|
|
|
91
6
|
export class JsonManager {
|
|
92
|
-
// JSON parser
|
|
93
7
|
middleware(options?: any) {
|
|
94
8
|
try {
|
|
95
9
|
const defaultOptions = {
|
|
@@ -104,7 +18,6 @@ export class JsonManager {
|
|
|
104
18
|
}
|
|
105
19
|
}
|
|
106
20
|
|
|
107
|
-
// URL-encoded parser
|
|
108
21
|
urlencoded(options?: any) {
|
|
109
22
|
try {
|
|
110
23
|
const defaultOptions = {
|
|
@@ -120,20 +33,17 @@ export class JsonManager {
|
|
|
120
33
|
}
|
|
121
34
|
}
|
|
122
35
|
|
|
123
|
-
// Query-string parser (doesn't override Express's query)
|
|
124
36
|
queryParser(options?: any) {
|
|
125
37
|
return (req: any, res: any, next: any) => {
|
|
126
38
|
try {
|
|
127
|
-
// Only parse if not already parsed by Express
|
|
128
39
|
if (!req.parsedQuery && req.url.includes('?')) {
|
|
129
40
|
const queryString = req.url.split("?")[1] || "";
|
|
130
41
|
const parsed = qs.parse(queryString, {
|
|
131
|
-
depth: 5,
|
|
42
|
+
depth: 5,
|
|
132
43
|
parameterLimit: 100,
|
|
133
44
|
...options
|
|
134
45
|
});
|
|
135
46
|
|
|
136
|
-
// Store separately, don't override req.query
|
|
137
47
|
req.parsedQuery = parsed;
|
|
138
48
|
logger.debug("🔍 Query parsed", {
|
|
139
49
|
keys: Object.keys(parsed)
|
|
@@ -1,252 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// // // src/managers/RateLimitManager.ts - COMPLETE FIXED
|
|
4
|
-
// // import { HiSecureConfig } from "../core/types/HiSecureConfig.js";
|
|
5
|
-
// // import { AdapterError } from "../core/errors/AdapterError.js";
|
|
6
|
-
// // import { logger } from "../logging";
|
|
7
|
-
|
|
8
|
-
// // interface RateLimiterAdapter {
|
|
9
|
-
// // getMiddleware: (options?: any) => any;
|
|
10
|
-
// // }
|
|
11
|
-
|
|
12
|
-
// // export class RateLimitManager {
|
|
13
|
-
// // private config: HiSecureConfig["rateLimiter"];
|
|
14
|
-
// // private primaryAdapter: RateLimiterAdapter;
|
|
15
|
-
// // private fallbackAdapter: RateLimiterAdapter | null;
|
|
16
|
-
|
|
17
|
-
// // constructor(
|
|
18
|
-
// // config: HiSecureConfig["rateLimiter"],
|
|
19
|
-
// // primaryAdapter: RateLimiterAdapter,
|
|
20
|
-
// // fallbackAdapter: RateLimiterAdapter | null
|
|
21
|
-
// // ) {
|
|
22
|
-
// // this.config = config;
|
|
23
|
-
// // this.primaryAdapter = primaryAdapter;
|
|
24
|
-
// // this.fallbackAdapter = fallbackAdapter;
|
|
25
|
-
// // }
|
|
26
|
-
|
|
27
|
-
// // middleware(opts?: { mode?: "strict" | "relaxed" | "api"; options?: any }) {
|
|
28
|
-
// // let finalOptions: any = {};
|
|
29
|
-
|
|
30
|
-
// // // Handle presets (user cannot override these)
|
|
31
|
-
// // if (opts?.mode === "strict") {
|
|
32
|
-
// // finalOptions = {
|
|
33
|
-
// // windowMs: 10_000,
|
|
34
|
-
// // max: 5,
|
|
35
|
-
// // points: 5,
|
|
36
|
-
// // duration: 10,
|
|
37
|
-
// // message: "Too many requests, please slow down."
|
|
38
|
-
// // };
|
|
39
|
-
// // } else if (opts?.mode === "relaxed") {
|
|
40
|
-
// // finalOptions = {
|
|
41
|
-
// // windowMs: 60_000,
|
|
42
|
-
// // max: 100,
|
|
43
|
-
// // points: 100,
|
|
44
|
-
// // duration: 60,
|
|
45
|
-
// // message: "Rate limit exceeded."
|
|
46
|
-
// // };
|
|
47
|
-
// // } else if (opts?.mode === "api") {
|
|
48
|
-
// // finalOptions = {
|
|
49
|
-
// // windowMs: 15 * 60 * 1000, // 15 minutes
|
|
50
|
-
// // max: 100,
|
|
51
|
-
// // points: 100,
|
|
52
|
-
// // duration: 900,
|
|
53
|
-
// // message: "API rate limit exceeded."
|
|
54
|
-
// // };
|
|
55
|
-
// // } else {
|
|
56
|
-
// // // Use defaults
|
|
57
|
-
// // finalOptions = {
|
|
58
|
-
// // windowMs: this.config.windowMs,
|
|
59
|
-
// // max: this.config.maxRequests,
|
|
60
|
-
// // duration: this.config.windowMs / 1000,
|
|
61
|
-
// // points: this.config.maxRequests,
|
|
62
|
-
// // message: this.config.message
|
|
63
|
-
// // };
|
|
64
|
-
// // }
|
|
65
|
-
|
|
66
|
-
// // // Apply custom options WITHOUT overriding preset values
|
|
67
|
-
// // if (opts?.options) {
|
|
68
|
-
// // // Only allow specific overrides, not preset overrides
|
|
69
|
-
// // const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders'];
|
|
70
|
-
// // for (const key of allowedOverrides) {
|
|
71
|
-
// // if (opts.options[key] !== undefined) {
|
|
72
|
-
// // finalOptions[key] = opts.options[key];
|
|
73
|
-
// // }
|
|
74
|
-
// // }
|
|
75
|
-
|
|
76
|
-
// // // Log if user tried to override preset
|
|
77
|
-
// // const attemptedOverrides = Object.keys(opts.options).filter(
|
|
78
|
-
// // k => !allowedOverrides.includes(k) && k !== 'mode'
|
|
79
|
-
// // );
|
|
80
|
-
// // if (attemptedOverrides.length > 0) {
|
|
81
|
-
// // logger.warn("⚠ Rate limit overrides ignored", { // ✅ FIXED: Better message
|
|
82
|
-
// // preset: opts?.mode || 'default', // ✅ FIXED: Handle undefined
|
|
83
|
-
// // ignoredOptions: attemptedOverrides
|
|
84
|
-
// // });
|
|
85
|
-
// // }
|
|
86
|
-
// // }
|
|
87
|
-
|
|
88
|
-
// // // Try primary adapter
|
|
89
|
-
// // try {
|
|
90
|
-
// // logger.info("📌 Applying rate limiting", {
|
|
91
|
-
// // mode: opts?.mode || 'default',
|
|
92
|
-
// // windowMs: finalOptions.windowMs,
|
|
93
|
-
// // max: finalOptions.max
|
|
94
|
-
// // });
|
|
95
|
-
|
|
96
|
-
// // return this.primaryAdapter.getMiddleware(finalOptions);
|
|
97
|
-
// // } catch (err: any) {
|
|
98
|
-
// // logger.warn("⚠ Primary rate limiter failed → fallback", {
|
|
99
|
-
// // error: err?.message
|
|
100
|
-
// // });
|
|
101
|
-
|
|
102
|
-
// // if (!this.fallbackAdapter) {
|
|
103
|
-
// // throw new AdapterError("Rate limiters failed; no fallback adapter.");
|
|
104
|
-
// // }
|
|
105
|
-
|
|
106
|
-
// // try {
|
|
107
|
-
// // logger.info("📌 Using fallback rate limiter");
|
|
108
|
-
// // return this.fallbackAdapter.getMiddleware(finalOptions);
|
|
109
|
-
// // } catch (fallbackErr: any) {
|
|
110
|
-
// // logger.error("❌ Fallback limiter also failed", {
|
|
111
|
-
// // error: fallbackErr?.message
|
|
112
|
-
// // });
|
|
113
|
-
// // throw new AdapterError("Both primary and fallback limiters failed.");
|
|
114
|
-
// // }
|
|
115
|
-
// // }
|
|
116
|
-
// // }
|
|
117
|
-
// // }
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// // src/managers/RateLimitManager.ts - FIXED
|
|
122
|
-
// import { HiSecureConfig } from "../core/types/HiSecureConfig.js";
|
|
123
|
-
// import { AdapterError } from "../core/errors/AdapterError.js";
|
|
124
|
-
// import { logger } from "../logging";
|
|
125
|
-
|
|
126
|
-
// interface RateLimiterAdapter {
|
|
127
|
-
// getMiddleware: (options?: any) => any;
|
|
128
|
-
// }
|
|
129
|
-
|
|
130
|
-
// export class RateLimitManager {
|
|
131
|
-
// private config: HiSecureConfig["rateLimiter"];
|
|
132
|
-
// private primaryAdapter: RateLimiterAdapter;
|
|
133
|
-
// private fallbackAdapter: RateLimiterAdapter | null;
|
|
134
|
-
|
|
135
|
-
// constructor(
|
|
136
|
-
// config: HiSecureConfig["rateLimiter"],
|
|
137
|
-
// primaryAdapter: RateLimiterAdapter,
|
|
138
|
-
// fallbackAdapter: RateLimiterAdapter | null
|
|
139
|
-
// ) {
|
|
140
|
-
// this.config = config;
|
|
141
|
-
// this.primaryAdapter = primaryAdapter;
|
|
142
|
-
// this.fallbackAdapter = fallbackAdapter;
|
|
143
|
-
// }
|
|
144
|
-
|
|
145
|
-
// middleware(opts?: { mode?: "strict" | "relaxed" | "api"; options?: any }) {
|
|
146
|
-
// let finalOptions: any = {};
|
|
147
|
-
|
|
148
|
-
// // Handle presets (user cannot override these)
|
|
149
|
-
// if (opts?.mode === "strict") {
|
|
150
|
-
// finalOptions = {
|
|
151
|
-
// windowMs: 10_000,
|
|
152
|
-
// max: 5,
|
|
153
|
-
// points: 5,
|
|
154
|
-
// // ❌ REMOVED: duration: 10,
|
|
155
|
-
// message: "Too many requests, please slow down."
|
|
156
|
-
// };
|
|
157
|
-
// } else if (opts?.mode === "relaxed") {
|
|
158
|
-
// finalOptions = {
|
|
159
|
-
// windowMs: 60_000,
|
|
160
|
-
// max: 100,
|
|
161
|
-
// points: 100,
|
|
162
|
-
// // ❌ REMOVED: duration: 60,
|
|
163
|
-
// message: "Rate limit exceeded."
|
|
164
|
-
// };
|
|
165
|
-
// } else if (opts?.mode === "api") {
|
|
166
|
-
// finalOptions = {
|
|
167
|
-
// windowMs: 15 * 60 * 1000, // 15 minutes
|
|
168
|
-
// max: 100,
|
|
169
|
-
// points: 100,
|
|
170
|
-
// // ❌ REMOVED: duration: 900,
|
|
171
|
-
// message: "API rate limit exceeded."
|
|
172
|
-
// };
|
|
173
|
-
// } else {
|
|
174
|
-
// // Use defaults
|
|
175
|
-
// finalOptions = {
|
|
176
|
-
// windowMs: this.config.windowMs,
|
|
177
|
-
// max: this.config.maxRequests,
|
|
178
|
-
// // ❌ REMOVED: duration: this.config.windowMs / 1000,
|
|
179
|
-
// points: this.config.maxRequests,
|
|
180
|
-
// message: this.config.message,
|
|
181
|
-
// standardHeaders: true, // ✅ ADD
|
|
182
|
-
// legacyHeaders: false // ✅ ADD
|
|
183
|
-
// };
|
|
184
|
-
// }
|
|
185
|
-
|
|
186
|
-
// // Apply custom options WITHOUT overriding preset values
|
|
187
|
-
// if (opts?.options) {
|
|
188
|
-
// // Only allow specific overrides, not preset overrides
|
|
189
|
-
// const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders', 'legacyHeaders'];
|
|
190
|
-
// for (const key of allowedOverrides) {
|
|
191
|
-
// if (opts.options[key] !== undefined) {
|
|
192
|
-
// finalOptions[key] = opts.options[key];
|
|
193
|
-
// }
|
|
194
|
-
// }
|
|
195
|
-
|
|
196
|
-
// // Log if user tried to override preset
|
|
197
|
-
// const attemptedOverrides = Object.keys(opts.options).filter(
|
|
198
|
-
// k => !allowedOverrides.includes(k) && k !== 'mode'
|
|
199
|
-
// );
|
|
200
|
-
// if (attemptedOverrides.length > 0) {
|
|
201
|
-
// logger.warn("⚠ Rate limit overrides ignored", {
|
|
202
|
-
// preset: opts?.mode || 'default',
|
|
203
|
-
// ignoredOptions: attemptedOverrides
|
|
204
|
-
// });
|
|
205
|
-
// }
|
|
206
|
-
// }
|
|
207
|
-
|
|
208
|
-
// // Add v8+ options if not present
|
|
209
|
-
// if (finalOptions.standardHeaders === undefined) {
|
|
210
|
-
// finalOptions.standardHeaders = true;
|
|
211
|
-
// }
|
|
212
|
-
// if (finalOptions.legacyHeaders === undefined) {
|
|
213
|
-
// finalOptions.legacyHeaders = false;
|
|
214
|
-
// }
|
|
215
|
-
|
|
216
|
-
// // Try primary adapter
|
|
217
|
-
// try {
|
|
218
|
-
// logger.info("📌 Applying rate limiting", {
|
|
219
|
-
// mode: opts?.mode || 'default',
|
|
220
|
-
// windowMs: finalOptions.windowMs,
|
|
221
|
-
// max: finalOptions.max
|
|
222
|
-
// });
|
|
223
|
-
|
|
224
|
-
// return this.primaryAdapter.getMiddleware(finalOptions);
|
|
225
|
-
// } catch (err: any) {
|
|
226
|
-
// logger.warn("⚠ Primary rate limiter failed → fallback", {
|
|
227
|
-
// error: err?.message
|
|
228
|
-
// });
|
|
229
|
-
|
|
230
|
-
// if (!this.fallbackAdapter) {
|
|
231
|
-
// throw new AdapterError("Rate limiters failed; no fallback adapter.");
|
|
232
|
-
// }
|
|
233
|
-
|
|
234
|
-
// try {
|
|
235
|
-
// logger.info("📌 Using fallback rate limiter");
|
|
236
|
-
// return this.fallbackAdapter.getMiddleware(finalOptions);
|
|
237
|
-
// } catch (fallbackErr: any) {
|
|
238
|
-
// logger.error("❌ Fallback limiter also failed", {
|
|
239
|
-
// error: fallbackErr?.message
|
|
240
|
-
// });
|
|
241
|
-
// throw new AdapterError("Both primary and fallback limiters failed.");
|
|
242
|
-
// }
|
|
243
|
-
// }
|
|
244
|
-
// }
|
|
245
|
-
// }
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
// src/managers/RateLimitManager.ts - COMPLETELY FIXED
|
|
250
1
|
import { HiSecureConfig } from "../core/types/HiSecureConfig.js";
|
|
251
2
|
import { AdapterError } from "../core/errors/AdapterError.js";
|
|
252
3
|
import { logger } from "../logging";
|
|
@@ -273,42 +24,35 @@ export class RateLimitManager {
|
|
|
273
24
|
middleware(opts?: { mode?: "strict" | "relaxed" | "api"; options?: any }) {
|
|
274
25
|
let finalOptions: any = {};
|
|
275
26
|
|
|
276
|
-
// Handle presets (user cannot override these)
|
|
277
27
|
if (opts?.mode === "strict") {
|
|
278
28
|
finalOptions = {
|
|
279
29
|
windowMs: 10_000,
|
|
280
30
|
max: 5,
|
|
281
|
-
// ❌ REMOVED: points: 5,
|
|
282
31
|
message: "Too many requests, please slow down."
|
|
283
32
|
};
|
|
284
33
|
} else if (opts?.mode === "relaxed") {
|
|
285
34
|
finalOptions = {
|
|
286
35
|
windowMs: 60_000,
|
|
287
36
|
max: 100,
|
|
288
|
-
// ❌ REMOVED: points: 100,
|
|
289
37
|
message: "Rate limit exceeded."
|
|
290
38
|
};
|
|
291
39
|
} else if (opts?.mode === "api") {
|
|
292
40
|
finalOptions = {
|
|
293
|
-
windowMs: 15 * 60 * 1000,
|
|
41
|
+
windowMs: 15 * 60 * 1000,
|
|
294
42
|
max: 100,
|
|
295
|
-
// ❌ REMOVED: points: 100,
|
|
296
43
|
message: "API rate limit exceeded."
|
|
297
44
|
};
|
|
298
45
|
} else {
|
|
299
|
-
// Use defaults
|
|
300
46
|
finalOptions = {
|
|
301
47
|
windowMs: this.config.windowMs,
|
|
302
48
|
max: this.config.maxRequests,
|
|
303
49
|
message: this.config.message,
|
|
304
|
-
standardHeaders: true,
|
|
305
|
-
legacyHeaders: false
|
|
50
|
+
standardHeaders: true,
|
|
51
|
+
legacyHeaders: false
|
|
306
52
|
};
|
|
307
53
|
}
|
|
308
54
|
|
|
309
|
-
// Apply custom options WITHOUT overriding preset values
|
|
310
55
|
if (opts?.options) {
|
|
311
|
-
// Only allow specific overrides, not preset overrides
|
|
312
56
|
const allowedOverrides = ['message', 'skipFailedRequests', 'standardHeaders', 'legacyHeaders'];
|
|
313
57
|
for (const key of allowedOverrides) {
|
|
314
58
|
if (opts.options[key] !== undefined) {
|
|
@@ -316,7 +60,6 @@ export class RateLimitManager {
|
|
|
316
60
|
}
|
|
317
61
|
}
|
|
318
62
|
|
|
319
|
-
// Log if user tried to override preset
|
|
320
63
|
const attemptedOverrides = Object.keys(opts.options).filter(
|
|
321
64
|
k => !allowedOverrides.includes(k) && k !== 'mode'
|
|
322
65
|
);
|
|
@@ -328,7 +71,6 @@ export class RateLimitManager {
|
|
|
328
71
|
}
|
|
329
72
|
}
|
|
330
73
|
|
|
331
|
-
// Add v8+ options if not present
|
|
332
74
|
if (finalOptions.standardHeaders === undefined) {
|
|
333
75
|
finalOptions.standardHeaders = true;
|
|
334
76
|
}
|
|
@@ -336,7 +78,6 @@ export class RateLimitManager {
|
|
|
336
78
|
finalOptions.legacyHeaders = false;
|
|
337
79
|
}
|
|
338
80
|
|
|
339
|
-
// Try primary adapter
|
|
340
81
|
try {
|
|
341
82
|
logger.info("📌 Applying rate limiting", {
|
|
342
83
|
mode: opts?.mode || 'default',
|