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.
- package/dist/adapters/ArgonAdapter.d.ts +1 -1
- package/dist/adapters/ArgonAdapter.d.ts.map +1 -1
- package/dist/adapters/ArgonAdapter.js +7 -5
- package/dist/adapters/ArgonAdapter.js.map +1 -1
- package/dist/adapters/BcryptAdapter.d.ts.map +1 -1
- package/dist/adapters/BcryptAdapter.js +7 -3
- package/dist/adapters/BcryptAdapter.js.map +1 -1
- package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressRLAdapter.js +10 -6
- package/dist/adapters/ExpressRLAdapter.js.map +1 -1
- package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressValidatorAdapter.js +14 -10
- package/dist/adapters/ExpressValidatorAdapter.js.map +1 -1
- package/dist/adapters/GoogleAdapter.d.ts.map +1 -1
- package/dist/adapters/GoogleAdapter.js +19 -16
- package/dist/adapters/GoogleAdapter.js.map +1 -1
- package/dist/adapters/JWTAdapter.d.ts.map +1 -1
- package/dist/adapters/JWTAdapter.js +25 -15
- package/dist/adapters/JWTAdapter.js.map +1 -1
- package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -1
- package/dist/adapters/RLFlexibleAdapter.js +23 -12
- package/dist/adapters/RLFlexibleAdapter.js.map +1 -1
- package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -1
- package/dist/adapters/SanitizeHtmlAdapter.js +17 -13
- package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -1
- package/dist/adapters/XSSAdapter.d.ts +1 -1
- package/dist/adapters/XSSAdapter.d.ts.map +1 -1
- package/dist/adapters/XSSAdapter.js +21 -20
- package/dist/adapters/XSSAdapter.js.map +1 -1
- package/dist/adapters/ZodAdapter.d.ts +1 -1
- package/dist/adapters/ZodAdapter.d.ts.map +1 -1
- package/dist/adapters/ZodAdapter.js +10 -8
- package/dist/adapters/ZodAdapter.js.map +1 -1
- package/dist/core/HiSecure.d.ts +3 -4
- package/dist/core/HiSecure.d.ts.map +1 -1
- package/dist/core/HiSecure.js +91 -120
- package/dist/core/HiSecure.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/morganSetup.d.ts.map +1 -1
- package/dist/logging/morganSetup.js +8 -1
- package/dist/logging/morganSetup.js.map +1 -1
- package/dist/logging/winstonSetup.d.ts.map +1 -1
- package/dist/logging/winstonSetup.js +17 -3
- package/dist/logging/winstonSetup.js.map +1 -1
- package/dist/managers/AuthManager.d.ts +2 -2
- package/dist/managers/AuthManager.d.ts.map +1 -1
- package/dist/managers/AuthManager.js +59 -31
- package/dist/managers/AuthManager.js.map +1 -1
- package/dist/managers/CorsManager.d.ts.map +1 -1
- package/dist/managers/CorsManager.js +18 -11
- package/dist/managers/CorsManager.js.map +1 -1
- package/dist/managers/HashManager.d.ts +1 -1
- package/dist/managers/HashManager.d.ts.map +1 -1
- package/dist/managers/HashManager.js +35 -17
- package/dist/managers/HashManager.js.map +1 -1
- package/dist/managers/JsonManager.d.ts +1 -1
- package/dist/managers/JsonManager.d.ts.map +1 -1
- package/dist/managers/JsonManager.js +44 -16
- package/dist/managers/JsonManager.js.map +1 -1
- package/dist/managers/RateLimitManager.d.ts +1 -1
- package/dist/managers/RateLimitManager.d.ts.map +1 -1
- package/dist/managers/RateLimitManager.js +43 -22
- package/dist/managers/RateLimitManager.js.map +1 -1
- package/dist/managers/SanitizerManager.d.ts.map +1 -1
- package/dist/managers/SanitizerManager.js +32 -15
- package/dist/managers/SanitizerManager.js.map +1 -1
- package/dist/managers/ValidatorManager.d.ts.map +1 -1
- package/dist/managers/ValidatorManager.js +31 -7
- package/dist/managers/ValidatorManager.js.map +1 -1
- package/package.json +2 -6
- package/readme.md +3 -6
- package/src/adapters/ArgonAdapter.ts +10 -6
- package/src/adapters/BcryptAdapter.ts +7 -8
- package/src/adapters/ExpressRLAdapter.ts +14 -9
- package/src/adapters/ExpressValidatorAdapter.ts +17 -11
- package/src/adapters/GoogleAdapter.ts +24 -21
- package/src/adapters/JWTAdapter.ts +33 -21
- package/src/adapters/RLFlexibleAdapter.ts +31 -16
- package/src/adapters/SanitizeHtmlAdapter.ts +28 -18
- package/src/adapters/XSSAdapter.ts +33 -38
- package/src/adapters/ZodAdapter.ts +10 -10
- package/src/core/HiSecure.ts +127 -161
- package/src/index.ts +4 -0
- package/src/logging/morganSetup.ts +11 -1
- package/src/logging/winstonSetup.ts +35 -8
- package/src/managers/AuthManager.ts +64 -34
- package/src/managers/CorsManager.ts +23 -16
- package/src/managers/HashManager.ts +48 -19
- package/src/managers/JsonManager.ts +57 -15
- package/src/managers/RateLimitManager.ts +61 -29
- package/src/managers/SanitizerManager.ts +47 -25
- package/src/managers/ValidatorManager.ts +40 -15
|
@@ -1,100 +1,128 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AuthManager = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
4
|
+
const JWTAdapter_1 = require("../adapters/JWTAdapter");
|
|
5
|
+
const GoogleAdapter_1 = require("../adapters/GoogleAdapter");
|
|
6
|
+
const AdapterError_1 = require("../core/errors/AdapterError");
|
|
7
|
+
const HttpError_1 = require("../core/errors/HttpError");
|
|
8
8
|
const logging_1 = require("../logging");
|
|
9
9
|
class AuthManager {
|
|
10
10
|
constructor(opts) {
|
|
11
11
|
if (!opts.jwtSecret) {
|
|
12
|
-
throw new
|
|
12
|
+
throw new AdapterError_1.AdapterError("jwtSecret required in AuthOptions");
|
|
13
13
|
}
|
|
14
14
|
if (opts.jwtSecret.length < 32) {
|
|
15
|
-
logging_1.logger.warn(" JWT secret
|
|
15
|
+
logging_1.logger.warn("Weak JWT secret detected", {
|
|
16
|
+
layer: "auth-manager",
|
|
17
|
+
operation: "init",
|
|
18
|
+
secretLength: opts.jwtSecret.length
|
|
19
|
+
});
|
|
16
20
|
}
|
|
17
|
-
logging_1.logger.info("AuthManager initialized"
|
|
18
|
-
|
|
21
|
+
logging_1.logger.info("AuthManager initialized", {
|
|
22
|
+
layer: "auth-manager",
|
|
23
|
+
jwtExpiresIn: opts.jwtExpiresIn ?? "1d",
|
|
24
|
+
googleEnabled: !!opts.googleClientId
|
|
25
|
+
});
|
|
26
|
+
this.jwtAdapter = new JWTAdapter_1.JWTAdapter({
|
|
19
27
|
secret: opts.jwtSecret,
|
|
20
|
-
expiresIn: opts.jwtExpiresIn ?? "1d"
|
|
28
|
+
expiresIn: opts.jwtExpiresIn ?? "1d"
|
|
21
29
|
});
|
|
22
30
|
if (opts.googleClientId) {
|
|
23
|
-
this.googleAdapter = new
|
|
24
|
-
logging_1.logger.info("
|
|
31
|
+
this.googleAdapter = new GoogleAdapter_1.GoogleAdapter(opts.googleClientId);
|
|
32
|
+
logging_1.logger.info("Google authentication enabled", {
|
|
33
|
+
layer: "auth-manager"
|
|
34
|
+
});
|
|
25
35
|
}
|
|
26
36
|
}
|
|
27
37
|
sign(payload, options) {
|
|
28
|
-
logging_1.logger.info("JWT
|
|
38
|
+
logging_1.logger.info("JWT sign requested", {
|
|
39
|
+
layer: "auth-manager",
|
|
40
|
+
operation: "sign"
|
|
41
|
+
});
|
|
29
42
|
return this.jwtAdapter.sign(payload, options);
|
|
30
43
|
}
|
|
31
44
|
verify(token) {
|
|
32
|
-
logging_1.logger.info("JWT
|
|
45
|
+
logging_1.logger.info("JWT verify requested", {
|
|
46
|
+
layer: "auth-manager",
|
|
47
|
+
operation: "verify"
|
|
48
|
+
});
|
|
33
49
|
return this.jwtAdapter.verify(token);
|
|
34
50
|
}
|
|
35
51
|
async verifyGoogleIdToken(idToken) {
|
|
36
52
|
if (!this.googleAdapter) {
|
|
37
|
-
throw new
|
|
53
|
+
throw new AdapterError_1.AdapterError("GoogleAdapter not configured.");
|
|
38
54
|
}
|
|
39
|
-
logging_1.logger.info("Google ID
|
|
55
|
+
logging_1.logger.info("Google ID token verification requested", {
|
|
56
|
+
layer: "auth-manager",
|
|
57
|
+
operation: "google-verify"
|
|
58
|
+
});
|
|
40
59
|
try {
|
|
41
60
|
return await this.googleAdapter.verifyIdToken(idToken);
|
|
42
61
|
}
|
|
43
62
|
catch (err) {
|
|
44
|
-
logging_1.logger.error("Google ID
|
|
45
|
-
|
|
63
|
+
logging_1.logger.error("Google ID token verification failed", {
|
|
64
|
+
layer: "auth-manager",
|
|
65
|
+
operation: "google-verify",
|
|
66
|
+
reason: err?.message
|
|
67
|
+
});
|
|
68
|
+
throw HttpError_1.HttpError.Unauthorized("Invalid Google ID token");
|
|
46
69
|
}
|
|
47
70
|
}
|
|
48
71
|
protect(options) {
|
|
49
72
|
const required = options?.required ?? true;
|
|
50
73
|
const roles = options?.roles;
|
|
51
|
-
return (req,
|
|
74
|
+
return (req, _res, next) => {
|
|
52
75
|
const header = req.headers["authorization"];
|
|
53
76
|
if (!required && !header) {
|
|
54
77
|
return next();
|
|
55
78
|
}
|
|
56
79
|
if (!header) {
|
|
57
|
-
logging_1.logger.warn("
|
|
80
|
+
logging_1.logger.warn("Authorization header missing", {
|
|
81
|
+
layer: "auth-manager",
|
|
82
|
+
operation: "protect",
|
|
58
83
|
path: req.path,
|
|
59
84
|
method: req.method
|
|
60
85
|
});
|
|
61
|
-
return next(
|
|
86
|
+
return next(HttpError_1.HttpError.Unauthorized("Missing Authorization header"));
|
|
62
87
|
}
|
|
63
88
|
const [type, token] = String(header).split(" ");
|
|
64
89
|
if (type !== "Bearer" || !token) {
|
|
65
|
-
logging_1.logger.warn("Invalid Authorization header", {
|
|
90
|
+
logging_1.logger.warn("Invalid Authorization header format", {
|
|
91
|
+
layer: "auth-manager",
|
|
92
|
+
operation: "protect",
|
|
66
93
|
path: req.path,
|
|
67
94
|
method: req.method
|
|
68
95
|
});
|
|
69
|
-
return next(
|
|
96
|
+
return next(HttpError_1.HttpError.Unauthorized("Invalid Authorization header"));
|
|
70
97
|
}
|
|
71
98
|
try {
|
|
72
|
-
// Verify JWT
|
|
73
99
|
const decoded = this.verify(token);
|
|
74
|
-
// Attach to request
|
|
75
100
|
req.auth = decoded;
|
|
76
101
|
req.user = decoded;
|
|
77
|
-
// Role-based authorization - role added Middleware
|
|
78
102
|
if (roles && roles.length > 0) {
|
|
79
103
|
const userRole = decoded.role || decoded.roles?.[0];
|
|
80
104
|
if (!userRole || !roles.includes(userRole)) {
|
|
81
|
-
logging_1.logger.warn("
|
|
105
|
+
logging_1.logger.warn("Access denied: insufficient role", {
|
|
106
|
+
layer: "auth-manager",
|
|
107
|
+
operation: "authorize",
|
|
82
108
|
path: req.path,
|
|
83
109
|
requiredRoles: roles,
|
|
84
110
|
userRole
|
|
85
111
|
});
|
|
86
|
-
return next(
|
|
112
|
+
return next(HttpError_1.HttpError.Forbidden("Insufficient permissions"));
|
|
87
113
|
}
|
|
88
114
|
}
|
|
89
115
|
return next();
|
|
90
116
|
}
|
|
91
117
|
catch (err) {
|
|
92
|
-
logging_1.logger.error("JWT
|
|
93
|
-
|
|
118
|
+
logging_1.logger.error("JWT authentication failed", {
|
|
119
|
+
layer: "auth-manager",
|
|
120
|
+
operation: "protect",
|
|
94
121
|
path: req.path,
|
|
95
|
-
method: req.method
|
|
122
|
+
method: req.method,
|
|
123
|
+
reason: err?.message
|
|
96
124
|
});
|
|
97
|
-
return next(
|
|
125
|
+
return next(HttpError_1.HttpError.Unauthorized("Invalid or expired token"));
|
|
98
126
|
}
|
|
99
127
|
};
|
|
100
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthManager.js","sourceRoot":"","sources":["../../src/managers/AuthManager.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"AuthManager.js","sourceRoot":"","sources":["../../src/managers/AuthManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { JWTAdapter } from \"../adapters/JWTAdapter\";\r\nimport { GoogleAdapter } from \"../adapters/GoogleAdapter\";\r\nimport { AdapterError } from \"../core/errors/AdapterError\";\r\nimport { HttpError } from \"../core/errors/HttpError\";\r\nimport { Request, Response, NextFunction } from \"express\";\r\nimport { logger } from \"../logging\";\r\n\r\nexport interface AuthOptions {\r\n jwtSecret: string;\r\n jwtExpiresIn?: string | number;\r\n googleClientId?: string;\r\n}\r\n\r\nexport interface ProtectOptions {\r\n required?: boolean;\r\n roles?: string[];\r\n}\r\n\r\nexport class AuthManager {\r\n private jwtAdapter: JWTAdapter;\r\n private googleAdapter?: GoogleAdapter;\r\n\r\n constructor(opts: AuthOptions) {\r\n if (!opts.jwtSecret) {\r\n throw new AdapterError(\"jwtSecret required in AuthOptions\");\r\n }\r\n\r\n if (opts.jwtSecret.length < 32) {\r\n logger.warn(\"Weak JWT secret detected\", {\r\n layer: \"auth-manager\",\r\n operation: \"init\",\r\n secretLength: opts.jwtSecret.length\r\n });\r\n }\r\n\r\n logger.info(\"AuthManager initialized\", {\r\n layer: \"auth-manager\",\r\n jwtExpiresIn: opts.jwtExpiresIn ?? \"1d\",\r\n googleEnabled: !!opts.googleClientId\r\n });\r\n\r\n this.jwtAdapter = new JWTAdapter({\r\n secret: opts.jwtSecret,\r\n expiresIn: opts.jwtExpiresIn ?? \"1d\"\r\n });\r\n\r\n if (opts.googleClientId) {\r\n this.googleAdapter = new GoogleAdapter(opts.googleClientId);\r\n logger.info(\"Google authentication enabled\", {\r\n layer: \"auth-manager\"\r\n });\r\n }\r\n }\r\n\r\n sign(payload: object, options?: { expiresIn?: string | number; jti?: string }) {\r\n logger.info(\"JWT sign requested\", {\r\n layer: \"auth-manager\",\r\n operation: \"sign\"\r\n });\r\n\r\n return this.jwtAdapter.sign(payload, options);\r\n }\r\n\r\n verify(token: string) {\r\n logger.info(\"JWT verify requested\", {\r\n layer: \"auth-manager\",\r\n operation: \"verify\"\r\n });\r\n\r\n return this.jwtAdapter.verify(token);\r\n }\r\n\r\n async verifyGoogleIdToken(idToken: string) {\r\n if (!this.googleAdapter) {\r\n throw new AdapterError(\"GoogleAdapter not configured.\");\r\n }\r\n\r\n logger.info(\"Google ID token verification requested\", {\r\n layer: \"auth-manager\",\r\n operation: \"google-verify\"\r\n });\r\n\r\n try {\r\n return await this.googleAdapter.verifyIdToken(idToken);\r\n } catch (err: any) {\r\n logger.error(\"Google ID token verification failed\", {\r\n layer: \"auth-manager\",\r\n operation: \"google-verify\",\r\n reason: err?.message\r\n });\r\n\r\n throw HttpError.Unauthorized(\"Invalid Google ID token\");\r\n }\r\n }\r\n\r\n protect(options?: ProtectOptions) {\r\n const required = options?.required ?? true;\r\n const roles = options?.roles;\r\n\r\n return (req: Request, _res: Response, next: NextFunction) => {\r\n const header = req.headers[\"authorization\"];\r\n\r\n if (!required && !header) {\r\n return next();\r\n }\r\n\r\n if (!header) {\r\n logger.warn(\"Authorization header missing\", {\r\n layer: \"auth-manager\",\r\n operation: \"protect\",\r\n path: req.path,\r\n method: req.method\r\n });\r\n return next(HttpError.Unauthorized(\"Missing Authorization header\"));\r\n }\r\n\r\n const [type, token] = String(header).split(\" \");\r\n if (type !== \"Bearer\" || !token) {\r\n logger.warn(\"Invalid Authorization header format\", {\r\n layer: \"auth-manager\",\r\n operation: \"protect\",\r\n path: req.path,\r\n method: req.method\r\n });\r\n return next(HttpError.Unauthorized(\"Invalid Authorization header\"));\r\n }\r\n\r\n try {\r\n const decoded = this.verify(token);\r\n\r\n (req as any).auth = decoded;\r\n (req as any).user = decoded;\r\n\r\n if (roles && roles.length > 0) {\r\n const userRole =\r\n (decoded as any).role || (decoded as any).roles?.[0];\r\n\r\n if (!userRole || !roles.includes(userRole)) {\r\n logger.warn(\"Access denied: insufficient role\", {\r\n layer: \"auth-manager\",\r\n operation: \"authorize\",\r\n path: req.path,\r\n requiredRoles: roles,\r\n userRole\r\n });\r\n\r\n return next(HttpError.Forbidden(\"Insufficient permissions\"));\r\n }\r\n }\r\n\r\n return next();\r\n } catch (err: any) {\r\n logger.error(\"JWT authentication failed\", {\r\n layer: \"auth-manager\",\r\n operation: \"protect\",\r\n path: req.path,\r\n method: req.method,\r\n reason: err?.message\r\n });\r\n\r\n return next(HttpError.Unauthorized(\"Invalid or expired token\"));\r\n }\r\n };\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CorsManager.d.ts","sourceRoot":"","sources":["../../src/managers/CorsManager.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,qBAAa,WAAW;
|
|
1
|
+
{"version":3,"file":"CorsManager.d.ts","sourceRoot":"","sources":["../../src/managers/CorsManager.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,qBAAa,WAAW;IACpB,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG;kBAoC6C,CAAC;;;iBAAmH,CAAC;CAD7L"}
|
|
@@ -6,30 +6,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.CorsManager = void 0;
|
|
7
7
|
const cors_1 = __importDefault(require("cors"));
|
|
8
8
|
const logging_1 = require("../logging");
|
|
9
|
-
const
|
|
9
|
+
const AdapterError_1 = require("../core/errors/AdapterError");
|
|
10
10
|
class CorsManager {
|
|
11
11
|
middleware(options) {
|
|
12
12
|
try {
|
|
13
13
|
const defaultOptions = {
|
|
14
|
-
origin:
|
|
15
|
-
methods: [
|
|
16
|
-
allowedHeaders: [
|
|
14
|
+
origin: "*",
|
|
15
|
+
methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
|
|
16
|
+
allowedHeaders: ["Content-Type", "Authorization"],
|
|
17
17
|
credentials: false,
|
|
18
18
|
maxAge: 86400
|
|
19
19
|
};
|
|
20
|
-
const finalOptions = options
|
|
21
|
-
|
|
20
|
+
const finalOptions = options
|
|
21
|
+
? { ...defaultOptions, ...options }
|
|
22
|
+
: defaultOptions;
|
|
23
|
+
// ✅ visible + clean log
|
|
24
|
+
logging_1.logger.info("CORS middleware configured", {
|
|
25
|
+
layer: "cors-manager",
|
|
26
|
+
operation: "init",
|
|
22
27
|
origin: finalOptions.origin,
|
|
23
|
-
methods: finalOptions.methods
|
|
28
|
+
methods: finalOptions.methods,
|
|
29
|
+
credentials: finalOptions.credentials
|
|
24
30
|
});
|
|
25
31
|
return (0, cors_1.default)(finalOptions);
|
|
26
32
|
}
|
|
27
33
|
catch (err) {
|
|
28
|
-
logging_1.logger.error("
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
logging_1.logger.error("CORS middleware initialization failed", {
|
|
35
|
+
layer: "cors-manager",
|
|
36
|
+
operation: "init",
|
|
37
|
+
reason: err?.message
|
|
31
38
|
});
|
|
32
|
-
throw new
|
|
39
|
+
throw new AdapterError_1.AdapterError("CORS middleware initialization failed.");
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CorsManager.js","sourceRoot":"","sources":["../../src/managers/CorsManager.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,wCAAoC;AACpC,
|
|
1
|
+
{"version":3,"file":"CorsManager.js","sourceRoot":"","sources":["../../src/managers/CorsManager.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,wCAAoC;AACpC,8DAA2D;AAE3D,MAAa,WAAW;IACpB,UAAU,CAAC,OAAa;QACpB,IAAI,CAAC;YACD,MAAM,cAAc,GAAG;gBACnB,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;gBAC7D,cAAc,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;gBACjD,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,KAAK;aAChB,CAAC;YAEF,MAAM,YAAY,GAAG,OAAO;gBACxB,CAAC,CAAC,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE;gBACnC,CAAC,CAAC,cAAc,CAAC;YAErB,wBAAwB;YACxB,gBAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;gBACtC,KAAK,EAAE,cAAc;gBACrB,SAAS,EAAE,MAAM;gBACjB,MAAM,EAAE,YAAY,CAAC,MAAM;gBAC3B,OAAO,EAAE,YAAY,CAAC,OAAO;gBAC7B,WAAW,EAAE,YAAY,CAAC,WAAW;aACxC,CAAC,CAAC;YAEH,OAAO,IAAA,cAAI,EAAC,YAAY,CAAC,CAAC;QAE9B,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,gBAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE;gBAClD,KAAK,EAAE,cAAc;gBACrB,SAAS,EAAE,MAAM;gBACjB,MAAM,EAAE,GAAG,EAAE,OAAO;aACvB,CAAC,CAAC;YAEH,MAAM,IAAI,2BAAY,CAAC,wCAAwC,CAAC,CAAC;QACrE,CAAC;IACL,CAAC;CACJ;AApCD,kCAoCC","sourcesContent":["import cors from \"cors\";\r\nimport { logger } from \"../logging\";\r\nimport { AdapterError } from \"../core/errors/AdapterError\";\r\n\r\nexport class CorsManager {\r\n middleware(options?: any) {\r\n try {\r\n const defaultOptions = {\r\n origin: \"*\",\r\n methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"],\r\n allowedHeaders: [\"Content-Type\", \"Authorization\"],\r\n credentials: false,\r\n maxAge: 86400\r\n };\r\n\r\n const finalOptions = options\r\n ? { ...defaultOptions, ...options }\r\n : defaultOptions;\r\n\r\n // ✅ visible + clean log\r\n logger.info(\"CORS middleware configured\", {\r\n layer: \"cors-manager\",\r\n operation: \"init\",\r\n origin: finalOptions.origin,\r\n methods: finalOptions.methods,\r\n credentials: finalOptions.credentials\r\n });\r\n\r\n return cors(finalOptions);\r\n\r\n } catch (err: any) {\r\n logger.error(\"CORS middleware initialization failed\", {\r\n layer: \"cors-manager\",\r\n operation: \"init\",\r\n reason: err?.message\r\n });\r\n\r\n throw new AdapterError(\"CORS middleware initialization failed.\");\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HashManager.d.ts","sourceRoot":"","sources":["../../src/managers/HashManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"HashManager.d.ts","sourceRoot":"","sources":["../../src/managers/HashManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,UAAU,WAAW;IACjB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;CACzB;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,eAAe,CAAqB;gBAGxC,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,EACjC,cAAc,EAAE,WAAW,EAC3B,eAAe,EAAE,WAAW,GAAG,IAAI;IAajC,IAAI,CACN,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GACtC,OAAO,CAAC,UAAU,CAAC;IAyDhB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAoChE"}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HashManager = void 0;
|
|
4
|
-
const
|
|
4
|
+
const AdapterError_1 = require("../core/errors/AdapterError");
|
|
5
5
|
const logging_1 = require("../logging");
|
|
6
6
|
class HashManager {
|
|
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("HashManager initialized", {
|
|
12
|
+
layer: "hash-manager",
|
|
13
|
+
primary: config.primary,
|
|
14
|
+
fallbackEnabled: !!fallbackAdapter
|
|
15
|
+
});
|
|
11
16
|
}
|
|
12
17
|
async hash(value, options) {
|
|
13
18
|
try {
|
|
@@ -20,55 +25,68 @@ class HashManager {
|
|
|
20
25
|
}
|
|
21
26
|
catch (err) {
|
|
22
27
|
logging_1.logger.warn("Primary hashing failed", {
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
layer: "hash-manager",
|
|
29
|
+
operation: "hash",
|
|
30
|
+
algorithm: this.config.primary,
|
|
31
|
+
reason: err?.message
|
|
25
32
|
});
|
|
26
33
|
if (!options?.allowFallback || !this.fallbackAdapter) {
|
|
27
|
-
throw new
|
|
34
|
+
throw new AdapterError_1.AdapterError(`Primary hashing (${this.config.primary}) failed. Fallback not allowed.`);
|
|
28
35
|
}
|
|
29
36
|
try {
|
|
30
37
|
const hash = await this.fallbackAdapter.hash(value);
|
|
31
|
-
//
|
|
32
|
-
logging_1.logger.warn("
|
|
38
|
+
// ⚠️ security downgrade log (VERY GOOD PRACTICE)
|
|
39
|
+
logging_1.logger.warn("Hashing fallback used (security downgrade)", {
|
|
40
|
+
layer: "hash-manager",
|
|
41
|
+
operation: "hash",
|
|
33
42
|
from: this.config.primary,
|
|
34
43
|
to: this.config.fallback
|
|
35
44
|
});
|
|
36
45
|
return {
|
|
37
46
|
hash,
|
|
38
|
-
algorithm: this.config.fallback ||
|
|
47
|
+
algorithm: this.config.fallback || "bcrypt",
|
|
39
48
|
usedFallback: true
|
|
40
49
|
};
|
|
41
50
|
}
|
|
42
51
|
catch (fallbackErr) {
|
|
43
52
|
logging_1.logger.error("Fallback hashing failed", {
|
|
44
|
-
|
|
53
|
+
layer: "hash-manager",
|
|
54
|
+
operation: "hash",
|
|
55
|
+
from: this.config.primary,
|
|
56
|
+
to: this.config.fallback,
|
|
57
|
+
reason: fallbackErr?.message
|
|
45
58
|
});
|
|
46
|
-
throw new
|
|
59
|
+
throw new AdapterError_1.AdapterError("Both primary and fallback hashing failed.");
|
|
47
60
|
}
|
|
48
61
|
}
|
|
49
62
|
}
|
|
50
63
|
async verify(value, hashed) {
|
|
51
|
-
// primary adapter - first
|
|
52
64
|
try {
|
|
53
65
|
return await this.primaryAdapter.verify(value, hashed);
|
|
54
66
|
}
|
|
55
67
|
catch (primaryErr) {
|
|
56
|
-
logging_1.logger.warn("Primary
|
|
57
|
-
|
|
68
|
+
logging_1.logger.warn("Primary hash verification failed", {
|
|
69
|
+
layer: "hash-manager",
|
|
70
|
+
operation: "verify",
|
|
71
|
+
algorithm: this.config.primary,
|
|
72
|
+
reason: primaryErr?.message
|
|
58
73
|
});
|
|
59
|
-
// fallback exists - try it
|
|
60
74
|
if (this.fallbackAdapter) {
|
|
61
75
|
try {
|
|
62
76
|
return await this.fallbackAdapter.verify(value, hashed);
|
|
63
77
|
}
|
|
64
78
|
catch (fallbackErr) {
|
|
65
|
-
logging_1.logger.error("
|
|
66
|
-
|
|
79
|
+
logging_1.logger.error("Fallback hash verification failed", {
|
|
80
|
+
layer: "hash-manager",
|
|
81
|
+
operation: "verify",
|
|
82
|
+
from: this.config.primary,
|
|
83
|
+
to: this.config.fallback,
|
|
84
|
+
reason: fallbackErr?.message
|
|
67
85
|
});
|
|
68
|
-
throw new
|
|
86
|
+
throw new AdapterError_1.AdapterError("Both primary and fallback verify failed.");
|
|
69
87
|
}
|
|
70
88
|
}
|
|
71
|
-
throw new
|
|
89
|
+
throw new AdapterError_1.AdapterError("Primary verify failed and no fallback adapter configured.");
|
|
72
90
|
}
|
|
73
91
|
}
|
|
74
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HashManager.js","sourceRoot":"","sources":["../../src/managers/HashManager.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"HashManager.js","sourceRoot":"","sources":["../../src/managers/HashManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { AdapterError } from \"../core/errors/AdapterError\";\r\nimport { HiSecureConfig } from \"../core/types/HiSecureConfig\";\r\nimport { logger } from \"../logging\";\r\n\r\ninterface HashAdapter {\r\n hash(value: string): Promise<string>;\r\n verify(value: string, hashed: string): Promise<boolean>;\r\n}\r\n\r\nexport interface HashResult {\r\n hash: string;\r\n algorithm: string;\r\n usedFallback: boolean;\r\n}\r\n\r\nexport class HashManager {\r\n private config: HiSecureConfig[\"hashing\"];\r\n private primaryAdapter: HashAdapter;\r\n private fallbackAdapter: HashAdapter | null;\r\n\r\n constructor(\r\n config: HiSecureConfig[\"hashing\"],\r\n primaryAdapter: HashAdapter,\r\n fallbackAdapter: HashAdapter | null\r\n ) {\r\n this.config = config;\r\n this.primaryAdapter = primaryAdapter;\r\n this.fallbackAdapter = fallbackAdapter;\r\n\r\n logger.info(\"HashManager initialized\", {\r\n layer: \"hash-manager\",\r\n primary: config.primary,\r\n fallbackEnabled: !!fallbackAdapter\r\n });\r\n }\r\n\r\n async hash(\r\n value: string,\r\n options?: { allowFallback?: boolean }\r\n ): Promise<HashResult> {\r\n try {\r\n const hash = await this.primaryAdapter.hash(value);\r\n\r\n return {\r\n hash,\r\n algorithm: this.config.primary,\r\n usedFallback: false\r\n };\r\n\r\n } catch (err: any) {\r\n logger.warn(\"Primary hashing failed\", {\r\n layer: \"hash-manager\",\r\n operation: \"hash\",\r\n algorithm: this.config.primary,\r\n reason: err?.message\r\n });\r\n\r\n if (!options?.allowFallback || !this.fallbackAdapter) {\r\n throw new AdapterError(\r\n `Primary hashing (${this.config.primary}) failed. Fallback not allowed.`\r\n );\r\n }\r\n\r\n try {\r\n const hash = await this.fallbackAdapter.hash(value);\r\n\r\n // ⚠️ security downgrade log (VERY GOOD PRACTICE)\r\n logger.warn(\"Hashing fallback used (security downgrade)\", {\r\n layer: \"hash-manager\",\r\n operation: \"hash\",\r\n from: this.config.primary,\r\n to: this.config.fallback\r\n });\r\n\r\n return {\r\n hash,\r\n algorithm: this.config.fallback || \"bcrypt\",\r\n usedFallback: true\r\n };\r\n\r\n } catch (fallbackErr: any) {\r\n logger.error(\"Fallback hashing failed\", {\r\n layer: \"hash-manager\",\r\n operation: \"hash\",\r\n from: this.config.primary,\r\n to: this.config.fallback,\r\n reason: fallbackErr?.message\r\n });\r\n\r\n throw new AdapterError(\r\n \"Both primary and fallback hashing failed.\"\r\n );\r\n }\r\n }\r\n }\r\n\r\n async verify(value: string, hashed: string): Promise<boolean> {\r\n try {\r\n return await this.primaryAdapter.verify(value, hashed);\r\n\r\n } catch (primaryErr: any) {\r\n logger.warn(\"Primary hash verification failed\", {\r\n layer: \"hash-manager\",\r\n operation: \"verify\",\r\n algorithm: this.config.primary,\r\n reason: primaryErr?.message\r\n });\r\n\r\n if (this.fallbackAdapter) {\r\n try {\r\n return await this.fallbackAdapter.verify(value, hashed);\r\n\r\n } catch (fallbackErr: any) {\r\n logger.error(\"Fallback hash verification failed\", {\r\n layer: \"hash-manager\",\r\n operation: \"verify\",\r\n from: this.config.primary,\r\n to: this.config.fallback,\r\n reason: fallbackErr?.message\r\n });\r\n\r\n throw new AdapterError(\r\n \"Both primary and fallback verify failed.\"\r\n );\r\n }\r\n }\r\n\r\n throw new AdapterError(\r\n \"Primary verify failed and no fallback adapter configured.\"\r\n );\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare class JsonManager {
|
|
2
2
|
middleware(options?: any): import("connect").NextHandleFunction;
|
|
3
3
|
urlencoded(options?: any): import("connect").NextHandleFunction;
|
|
4
|
-
queryParser(options?: any): (req: any,
|
|
4
|
+
queryParser(options?: any): (req: any, _res: any, next: any) => void;
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=JsonManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonManager.d.ts","sourceRoot":"","sources":["../../src/managers/JsonManager.ts"],"names":[],"mappings":"AAKA,qBAAa,WAAW;IACpB,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG;
|
|
1
|
+
{"version":3,"file":"JsonManager.d.ts","sourceRoot":"","sources":["../../src/managers/JsonManager.ts"],"names":[],"mappings":"AAKA,qBAAa,WAAW;IACpB,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG;IA8BxB,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG;IA8BxB,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,IACb,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;CAiC7C"}
|
|
@@ -7,41 +7,62 @@ exports.JsonManager = void 0;
|
|
|
7
7
|
const express_1 = __importDefault(require("express"));
|
|
8
8
|
const qs_1 = __importDefault(require("qs"));
|
|
9
9
|
const logging_1 = require("../logging");
|
|
10
|
-
const
|
|
10
|
+
const AdapterError_1 = require("../core/errors/AdapterError");
|
|
11
11
|
class JsonManager {
|
|
12
12
|
middleware(options) {
|
|
13
13
|
try {
|
|
14
14
|
const defaultOptions = {
|
|
15
|
-
limit:
|
|
15
|
+
limit: "1mb",
|
|
16
16
|
inflate: true,
|
|
17
17
|
strict: true
|
|
18
18
|
};
|
|
19
|
-
|
|
19
|
+
const finalOptions = { ...defaultOptions, ...(options || {}) };
|
|
20
|
+
logging_1.logger.info("JSON body parser configured", {
|
|
21
|
+
layer: "json-manager",
|
|
22
|
+
operation: "json",
|
|
23
|
+
limit: finalOptions.limit,
|
|
24
|
+
strict: finalOptions.strict
|
|
25
|
+
});
|
|
26
|
+
return express_1.default.json(finalOptions);
|
|
20
27
|
}
|
|
21
28
|
catch (err) {
|
|
22
|
-
logging_1.logger.error("JSON
|
|
23
|
-
|
|
29
|
+
logging_1.logger.error("JSON body parser initialization failed", {
|
|
30
|
+
layer: "json-manager",
|
|
31
|
+
operation: "json",
|
|
32
|
+
reason: err?.message
|
|
33
|
+
});
|
|
34
|
+
throw new AdapterError_1.AdapterError("JSON parser initialization failed.");
|
|
24
35
|
}
|
|
25
36
|
}
|
|
26
37
|
urlencoded(options) {
|
|
27
38
|
try {
|
|
28
39
|
const defaultOptions = {
|
|
29
40
|
extended: true,
|
|
30
|
-
limit:
|
|
41
|
+
limit: "1mb",
|
|
31
42
|
parameterLimit: 1000
|
|
32
43
|
};
|
|
33
|
-
const
|
|
34
|
-
|
|
44
|
+
const finalOptions = { ...defaultOptions, ...(options || {}) };
|
|
45
|
+
logging_1.logger.info("URL-encoded parser configured", {
|
|
46
|
+
layer: "json-manager",
|
|
47
|
+
operation: "urlencoded",
|
|
48
|
+
limit: finalOptions.limit,
|
|
49
|
+
parameterLimit: finalOptions.parameterLimit
|
|
50
|
+
});
|
|
51
|
+
return express_1.default.urlencoded(finalOptions);
|
|
35
52
|
}
|
|
36
53
|
catch (err) {
|
|
37
|
-
logging_1.logger.error("URL-encoded parser failed"
|
|
38
|
-
|
|
54
|
+
logging_1.logger.error("URL-encoded parser initialization failed", {
|
|
55
|
+
layer: "json-manager",
|
|
56
|
+
operation: "urlencoded",
|
|
57
|
+
reason: err?.message
|
|
58
|
+
});
|
|
59
|
+
throw new AdapterError_1.AdapterError("URL-encoded parser initialization failed.");
|
|
39
60
|
}
|
|
40
61
|
}
|
|
41
62
|
queryParser(options) {
|
|
42
|
-
return (req,
|
|
63
|
+
return (req, _res, next) => {
|
|
43
64
|
try {
|
|
44
|
-
if (!req.parsedQuery && req.url.includes(
|
|
65
|
+
if (!req.parsedQuery && req.url.includes("?")) {
|
|
45
66
|
const queryString = req.url.split("?")[1] || "";
|
|
46
67
|
const parsed = qs_1.default.parse(queryString, {
|
|
47
68
|
depth: 5,
|
|
@@ -49,15 +70,22 @@ class JsonManager {
|
|
|
49
70
|
...options
|
|
50
71
|
});
|
|
51
72
|
req.parsedQuery = parsed;
|
|
52
|
-
|
|
53
|
-
|
|
73
|
+
// ✅ visible + safe info
|
|
74
|
+
logging_1.logger.info("Query parameters parsed", {
|
|
75
|
+
layer: "json-manager",
|
|
76
|
+
operation: "query-parse",
|
|
77
|
+
keyCount: Object.keys(parsed).length
|
|
54
78
|
});
|
|
55
79
|
}
|
|
56
80
|
next();
|
|
57
81
|
}
|
|
58
82
|
catch (err) {
|
|
59
|
-
logging_1.logger.error("
|
|
60
|
-
|
|
83
|
+
logging_1.logger.error("Query parsing failed", {
|
|
84
|
+
layer: "json-manager",
|
|
85
|
+
operation: "query-parse",
|
|
86
|
+
reason: err?.message
|
|
87
|
+
});
|
|
88
|
+
next(new AdapterError_1.AdapterError("Query parsing failed."));
|
|
61
89
|
}
|
|
62
90
|
};
|
|
63
91
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonManager.js","sourceRoot":"","sources":["../../src/managers/JsonManager.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA8B;AAC9B,4CAAoB;AACpB,wCAAoC;AACpC,
|
|
1
|
+
{"version":3,"file":"JsonManager.js","sourceRoot":"","sources":["../../src/managers/JsonManager.ts"],"names":[],"mappings":"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","sourcesContent":["import express from \"express\";\r\nimport qs from \"qs\";\r\nimport { logger } from \"../logging\";\r\nimport { AdapterError } from \"../core/errors/AdapterError\";\r\n\r\nexport class JsonManager {\r\n middleware(options?: any) {\r\n try {\r\n const defaultOptions = {\r\n limit: \"1mb\",\r\n inflate: true,\r\n strict: true\r\n };\r\n\r\n const finalOptions = { ...defaultOptions, ...(options || {}) };\r\n\r\n logger.info(\"JSON body parser configured\", {\r\n layer: \"json-manager\",\r\n operation: \"json\",\r\n limit: finalOptions.limit,\r\n strict: finalOptions.strict\r\n });\r\n\r\n return express.json(finalOptions);\r\n\r\n } catch (err: any) {\r\n logger.error(\"JSON body parser initialization failed\", {\r\n layer: \"json-manager\",\r\n operation: \"json\",\r\n reason: err?.message\r\n });\r\n\r\n throw new AdapterError(\"JSON parser initialization failed.\");\r\n }\r\n }\r\n\r\n urlencoded(options?: any) {\r\n try {\r\n const defaultOptions = {\r\n extended: true,\r\n limit: \"1mb\",\r\n parameterLimit: 1000\r\n };\r\n\r\n const finalOptions = { ...defaultOptions, ...(options || {}) };\r\n\r\n logger.info(\"URL-encoded parser configured\", {\r\n layer: \"json-manager\",\r\n operation: \"urlencoded\",\r\n limit: finalOptions.limit,\r\n parameterLimit: finalOptions.parameterLimit\r\n });\r\n\r\n return express.urlencoded(finalOptions);\r\n\r\n } catch (err: any) {\r\n logger.error(\"URL-encoded parser initialization failed\", {\r\n layer: \"json-manager\",\r\n operation: \"urlencoded\",\r\n reason: err?.message\r\n });\r\n\r\n throw new AdapterError(\"URL-encoded parser initialization failed.\");\r\n }\r\n }\r\n\r\n queryParser(options?: any) {\r\n return (req: any, _res: any, next: any) => {\r\n try {\r\n if (!req.parsedQuery && req.url.includes(\"?\")) {\r\n const queryString = req.url.split(\"?\")[1] || \"\";\r\n\r\n const parsed = qs.parse(queryString, {\r\n depth: 5,\r\n parameterLimit: 100,\r\n ...options\r\n });\r\n\r\n req.parsedQuery = parsed;\r\n\r\n // ✅ visible + safe info\r\n logger.info(\"Query parameters parsed\", {\r\n layer: \"json-manager\",\r\n operation: \"query-parse\",\r\n keyCount: Object.keys(parsed).length\r\n });\r\n }\r\n\r\n next();\r\n } catch (err: any) {\r\n logger.error(\"Query parsing failed\", {\r\n layer: \"json-manager\",\r\n operation: \"query-parse\",\r\n reason: err?.message\r\n });\r\n\r\n next(new AdapterError(\"Query parsing failed.\"));\r\n }\r\n };\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RateLimitManager.d.ts","sourceRoot":"","sources":["../../src/managers/RateLimitManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"RateLimitManager.d.ts","sourceRoot":"","sources":["../../src/managers/RateLimitManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAI9D,UAAU,kBAAkB;IACxB,aAAa,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC;CACzC;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,eAAe,CAA4B;gBAG/C,MAAM,EAAE,cAAc,CAAC,aAAa,CAAC,EACrC,cAAc,EAAE,kBAAkB,EAClC,eAAe,EAAE,kBAAkB,GAAG,IAAI;IAa9C,UAAU,CAAC,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE;CA+G3E"}
|