hi-secure 1.0.0
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 +8 -0
- package/dist/adapters/ArgonAdapter.d.ts.map +1 -0
- package/dist/adapters/ArgonAdapter.js +45 -0
- package/dist/adapters/ArgonAdapter.js.map +1 -0
- package/dist/adapters/BcryptAdapter.d.ts +7 -0
- package/dist/adapters/BcryptAdapter.d.ts.map +1 -0
- package/dist/adapters/BcryptAdapter.js +48 -0
- package/dist/adapters/BcryptAdapter.js.map +1 -0
- package/dist/adapters/DomPurifyAdapter.d.ts +13 -0
- package/dist/adapters/DomPurifyAdapter.d.ts.map +1 -0
- package/dist/adapters/DomPurifyAdapter.js +61 -0
- package/dist/adapters/DomPurifyAdapter.js.map +1 -0
- package/dist/adapters/ExpressRLAdapter.d.ts +13 -0
- package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -0
- package/dist/adapters/ExpressRLAdapter.js +68 -0
- package/dist/adapters/ExpressRLAdapter.js.map +1 -0
- package/dist/adapters/ExpressValidatorAdapter.d.ts +6 -0
- package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -0
- package/dist/adapters/ExpressValidatorAdapter.js +78 -0
- package/dist/adapters/ExpressValidatorAdapter.js.map +1 -0
- package/dist/adapters/GoggleAdapter.d.ts +15 -0
- package/dist/adapters/GoggleAdapter.d.ts.map +1 -0
- package/dist/adapters/GoggleAdapter.js +91 -0
- package/dist/adapters/GoggleAdapter.js.map +1 -0
- package/dist/adapters/GoogleAdapter.d.ts +15 -0
- package/dist/adapters/GoogleAdapter.d.ts.map +1 -0
- package/dist/adapters/GoogleAdapter.js +159 -0
- package/dist/adapters/GoogleAdapter.js.map +1 -0
- package/dist/adapters/JWTAdapter.d.ts +28 -0
- package/dist/adapters/JWTAdapter.d.ts.map +1 -0
- package/dist/adapters/JWTAdapter.js +276 -0
- package/dist/adapters/JWTAdapter.js.map +1 -0
- package/dist/adapters/RLFlexibleAdapter.d.ts +11 -0
- package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -0
- package/dist/adapters/RLFlexibleAdapter.js +115 -0
- package/dist/adapters/RLFlexibleAdapter.js.map +1 -0
- package/dist/adapters/SanitizeHtmlAdapter.d.ts +12 -0
- package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -0
- package/dist/adapters/SanitizeHtmlAdapter.js +141 -0
- package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -0
- package/dist/adapters/XSSAdapter.d.ts +33 -0
- package/dist/adapters/XSSAdapter.d.ts.map +1 -0
- package/dist/adapters/XSSAdapter.js +127 -0
- package/dist/adapters/XSSAdapter.js.map +1 -0
- package/dist/adapters/ZodAdapter.d.ts +7 -0
- package/dist/adapters/ZodAdapter.d.ts.map +1 -0
- package/dist/adapters/ZodAdapter.js +39 -0
- package/dist/adapters/ZodAdapter.js.map +1 -0
- package/dist/core/HiSecure.d.ts +62 -0
- package/dist/core/HiSecure.d.ts.map +1 -0
- package/dist/core/HiSecure.js +273 -0
- package/dist/core/HiSecure.js.map +1 -0
- package/dist/core/config.d.ts +3 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +53 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.d.ts +37 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +67 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/errors/AdapterError.d.ts +5 -0
- package/dist/core/errors/AdapterError.d.ts.map +1 -0
- package/dist/core/errors/AdapterError.js +15 -0
- package/dist/core/errors/AdapterError.js.map +1 -0
- package/dist/core/errors/HttpErrror.d.ts +17 -0
- package/dist/core/errors/HttpErrror.d.ts.map +1 -0
- package/dist/core/errors/HttpErrror.js +36 -0
- package/dist/core/errors/HttpErrror.js.map +1 -0
- package/dist/core/errors/SanitizerError.d.ts +5 -0
- package/dist/core/errors/SanitizerError.d.ts.map +1 -0
- package/dist/core/errors/SanitizerError.js +14 -0
- package/dist/core/errors/SanitizerError.js.map +1 -0
- package/dist/core/errors/SecurityError.d.ts +5 -0
- package/dist/core/errors/SecurityError.d.ts.map +1 -0
- package/dist/core/errors/SecurityError.js +14 -0
- package/dist/core/errors/SecurityError.js.map +1 -0
- package/dist/core/errors/ValidationError.d.ts +5 -0
- package/dist/core/errors/ValidationError.d.ts.map +1 -0
- package/dist/core/errors/ValidationError.js +14 -0
- package/dist/core/errors/ValidationError.js.map +1 -0
- package/dist/core/types/HiSecureConfig.d.ts +47 -0
- package/dist/core/types/HiSecureConfig.d.ts.map +1 -0
- package/dist/core/types/HiSecureConfig.js +3 -0
- package/dist/core/types/HiSecureConfig.js.map +1 -0
- package/dist/core/types/SecureOptions.d.ts +30 -0
- package/dist/core/types/SecureOptions.d.ts.map +1 -0
- package/dist/core/types/SecureOptions.js +4 -0
- package/dist/core/types/SecureOptions.js.map +1 -0
- package/dist/core/useSecure.d.ts +10 -0
- package/dist/core/useSecure.d.ts.map +1 -0
- package/dist/core/useSecure.js +85 -0
- package/dist/core/useSecure.js.map +1 -0
- package/dist/examples/e1.d.ts +1 -0
- package/dist/examples/e1.d.ts.map +1 -0
- package/dist/examples/e1.js +3 -0
- package/dist/examples/e1.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/index.d.ts +3 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +19 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/morganSetup.d.ts +2 -0
- package/dist/logging/morganSetup.d.ts.map +1 -0
- package/dist/logging/morganSetup.js +9 -0
- package/dist/logging/morganSetup.js.map +1 -0
- package/dist/logging/winstonSetup.d.ts +6 -0
- package/dist/logging/winstonSetup.d.ts.map +1 -0
- package/dist/logging/winstonSetup.js +22 -0
- package/dist/logging/winstonSetup.js.map +1 -0
- package/dist/managers/AuthManager.d.ts +23 -0
- package/dist/managers/AuthManager.d.ts.map +1 -0
- package/dist/managers/AuthManager.js +190 -0
- package/dist/managers/AuthManager.js.map +1 -0
- package/dist/managers/CorsManager.d.ts +9 -0
- package/dist/managers/CorsManager.d.ts.map +1 -0
- package/dist/managers/CorsManager.js +55 -0
- package/dist/managers/CorsManager.js.map +1 -0
- package/dist/managers/HashManager.d.ts +22 -0
- package/dist/managers/HashManager.d.ts.map +1 -0
- package/dist/managers/HashManager.js +319 -0
- package/dist/managers/HashManager.js.map +1 -0
- package/dist/managers/JsonManager.d.ts +6 -0
- package/dist/managers/JsonManager.d.ts.map +1 -0
- package/dist/managers/JsonManager.js +142 -0
- package/dist/managers/JsonManager.js.map +1 -0
- package/dist/managers/RateLimitManager.d.ts +16 -0
- package/dist/managers/RateLimitManager.d.ts.map +1 -0
- package/dist/managers/RateLimitManager.js +108 -0
- package/dist/managers/RateLimitManager.js.map +1 -0
- package/dist/managers/SanitizerManager.d.ts +18 -0
- package/dist/managers/SanitizerManager.d.ts.map +1 -0
- package/dist/managers/SanitizerManager.js +296 -0
- package/dist/managers/SanitizerManager.js.map +1 -0
- package/dist/managers/ValidatorManager.d.ts +13 -0
- package/dist/managers/ValidatorManager.d.ts.map +1 -0
- package/dist/managers/ValidatorManager.js +218 -0
- package/dist/managers/ValidatorManager.js.map +1 -0
- package/dist/middlewares/errorHandler.d.ts +3 -0
- package/dist/middlewares/errorHandler.d.ts.map +1 -0
- package/dist/middlewares/errorHandler.js +94 -0
- package/dist/middlewares/errorHandler.js.map +1 -0
- package/dist/middlewares/index.d.ts +3 -0
- package/dist/middlewares/index.d.ts.map +1 -0
- package/dist/middlewares/index.js +19 -0
- package/dist/middlewares/index.js.map +1 -0
- package/dist/middlewares/requestLogger.d.ts +2 -0
- package/dist/middlewares/requestLogger.d.ts.map +1 -0
- package/dist/middlewares/requestLogger.js +8 -0
- package/dist/middlewares/requestLogger.js.map +1 -0
- package/dist/test/t1.d.ts +1 -0
- package/dist/test/t1.d.ts.map +1 -0
- package/dist/test/t1.js +3 -0
- package/dist/test/t1.js.map +1 -0
- package/dist/utils/deepFreeze.d.ts +2 -0
- package/dist/utils/deepFreeze.d.ts.map +1 -0
- package/dist/utils/deepFreeze.js +69 -0
- package/dist/utils/deepFreeze.js.map +1 -0
- package/dist/utils/deepMerge.d.ts +5 -0
- package/dist/utils/deepMerge.d.ts.map +1 -0
- package/dist/utils/deepMerge.js +68 -0
- package/dist/utils/deepMerge.js.map +1 -0
- package/dist/utils/normalizeOptions.d.ts +38 -0
- package/dist/utils/normalizeOptions.d.ts.map +1 -0
- package/dist/utils/normalizeOptions.js +119 -0
- package/dist/utils/normalizeOptions.js.map +1 -0
- package/package.json +50 -0
- package/src/adapters/ArgonAdapter.ts +41 -0
- package/src/adapters/BcryptAdapter.ts +49 -0
- package/src/adapters/ExpressRLAdapter.ts +84 -0
- package/src/adapters/ExpressValidatorAdapter.ts +99 -0
- package/src/adapters/GoogleAdapter.ts +206 -0
- package/src/adapters/JWTAdapter.ts +346 -0
- package/src/adapters/RLFlexibleAdapter.ts +139 -0
- package/src/adapters/SanitizeHtmlAdapter.ts +162 -0
- package/src/adapters/XSSAdapter.ts +153 -0
- package/src/adapters/ZodAdapter.ts +91 -0
- package/src/core/HiSecure.ts +955 -0
- package/src/core/config.ts +156 -0
- package/src/core/constants.ts +73 -0
- package/src/core/errors/AdapterError.ts +14 -0
- package/src/core/errors/HttpErrror.ts +46 -0
- package/src/core/errors/SanitizerError.ts +13 -0
- package/src/core/errors/SecurityError.ts +13 -0
- package/src/core/errors/ValidationError.ts +13 -0
- package/src/core/types/HiSecureConfig.ts +62 -0
- package/src/core/types/SecureOptions.ts +61 -0
- package/src/core/useSecure.ts +111 -0
- package/src/examples/e1.ts +1 -0
- package/src/index.ts +17 -0
- package/src/logging/index.ts +2 -0
- package/src/logging/morganSetup.ts +3 -0
- package/src/logging/winstonSetup.ts +17 -0
- package/src/managers/AuthManager.ts +237 -0
- package/src/managers/CorsManager.ts +58 -0
- package/src/managers/HashManager.ts +390 -0
- package/src/managers/JsonManager.ts +149 -0
- package/src/managers/RateLimitManager.ts +368 -0
- package/src/managers/SanitizerManager.ts +359 -0
- package/src/managers/ValidatorManager.ts +269 -0
- package/src/middlewares/errorHandler.ts +265 -0
- package/src/middlewares/index.ts +2 -0
- package/src/middlewares/requestLogger.ts +5 -0
- package/src/test/t1.ts +1 -0
- package/src/utils/deepFreeze.ts +76 -0
- package/src/utils/deepMerge.ts +87 -0
- package/src/utils/normalizeOptions.ts +265 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// // // import { SanitizerError } from "../core/errors/SanitizerError";
|
|
3
|
+
// // // import { logger } from "../logging";
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.SanitizerManager = void 0;
|
|
6
|
+
// // // interface SanitizerAdapter {
|
|
7
|
+
// // // sanitize: (value: string) => string;
|
|
8
|
+
// // // middleware?: () => any;
|
|
9
|
+
// // // }
|
|
10
|
+
// // // export class SanitizerManager {
|
|
11
|
+
// // // private primary: SanitizerAdapter;
|
|
12
|
+
// // // private fallback: SanitizerAdapter | null;
|
|
13
|
+
// // // constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {
|
|
14
|
+
// // // this.primary = primary;
|
|
15
|
+
// // // this.fallback = fallback;
|
|
16
|
+
// // // }
|
|
17
|
+
// // // sanitize(value: string): string {
|
|
18
|
+
// // // try {
|
|
19
|
+
// // // return this.primary.sanitize(value);
|
|
20
|
+
// // // } catch (err: any) {
|
|
21
|
+
// // // logger.warn("⚠ Sanitizer primary adapter failed", { error: err?.message });
|
|
22
|
+
// // // if (!this.fallback) {
|
|
23
|
+
// // // throw new SanitizerError("Primary sanitizer failed, no fallback available.");
|
|
24
|
+
// // // }
|
|
25
|
+
// // // try {
|
|
26
|
+
// // // logger.info("📌 Using fallback sanitizer");
|
|
27
|
+
// // // return this.fallback.sanitize(value);
|
|
28
|
+
// // // } catch (fallbackErr: any) {
|
|
29
|
+
// // // logger.error("❌ Fallback sanitizer failed", {
|
|
30
|
+
// // // error: fallbackErr?.message
|
|
31
|
+
// // // });
|
|
32
|
+
// // // throw new SanitizerError("Both primary and fallback sanitizers failed.");
|
|
33
|
+
// // // }
|
|
34
|
+
// // // }
|
|
35
|
+
// // // }
|
|
36
|
+
// // // middleware() {
|
|
37
|
+
// // // return (req: any, _res: any, next: any) => {
|
|
38
|
+
// // // try {
|
|
39
|
+
// // // if (req.body && typeof req.body === "object") {
|
|
40
|
+
// // // for (const key of Object.keys(req.body)) {
|
|
41
|
+
// // // const value = req.body[key];
|
|
42
|
+
// // // if (typeof value === "string") {
|
|
43
|
+
// // // const clean = this.sanitize(value);
|
|
44
|
+
// // // logger.debug("🧼 Sanitized field", {
|
|
45
|
+
// // // field: key,
|
|
46
|
+
// // // before: value.slice(0, 80),
|
|
47
|
+
// // // after: clean.slice(0, 80),
|
|
48
|
+
// // // });
|
|
49
|
+
// // // req.body[key] = clean;
|
|
50
|
+
// // // }
|
|
51
|
+
// // // }
|
|
52
|
+
// // // }
|
|
53
|
+
// // // next();
|
|
54
|
+
// // // } catch (err: any) {
|
|
55
|
+
// // // logger.error("❌ Sanitizer middleware failed", { error: err?.message });
|
|
56
|
+
// // // next(new SanitizerError("Sanitizer middleware failure"));
|
|
57
|
+
// // // }
|
|
58
|
+
// // // };
|
|
59
|
+
// // // }
|
|
60
|
+
// // // }
|
|
61
|
+
// // // src/managers/SanitizerManager.ts
|
|
62
|
+
// // import { SanitizerError } from "../core/errors/SanitizerError.js";
|
|
63
|
+
// // import { logger } from "../logging";
|
|
64
|
+
// // interface SanitizerAdapter {
|
|
65
|
+
// // sanitize: (value: string, options?: any) => string;
|
|
66
|
+
// // }
|
|
67
|
+
// // export class SanitizerManager {
|
|
68
|
+
// // private primary: SanitizerAdapter;
|
|
69
|
+
// // private fallback: SanitizerAdapter | null;
|
|
70
|
+
// // constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {
|
|
71
|
+
// // this.primary = primary;
|
|
72
|
+
// // this.fallback = fallback;
|
|
73
|
+
// // }
|
|
74
|
+
// // /**
|
|
75
|
+
// // * Sanitize a single value with optional dynamic options.
|
|
76
|
+
// // */
|
|
77
|
+
// // sanitize(value: string, options?: any): string {
|
|
78
|
+
// // try {
|
|
79
|
+
// // return this.primary.sanitize(value, options);
|
|
80
|
+
// // } catch (err: any) {
|
|
81
|
+
// // logger.warn("⚠ Primary sanitizer failed", { error: err?.message });
|
|
82
|
+
// // if (!this.fallback) {
|
|
83
|
+
// // throw new SanitizerError("Primary sanitizer failed and no fallback available.");
|
|
84
|
+
// // }
|
|
85
|
+
// // try {
|
|
86
|
+
// // logger.info("📌 Using fallback sanitizer");
|
|
87
|
+
// // return this.fallback.sanitize(value, options);
|
|
88
|
+
// // } catch (fallbackErr: any) {
|
|
89
|
+
// // logger.error("❌ Fallback sanitizer failed", {
|
|
90
|
+
// // error: fallbackErr?.message
|
|
91
|
+
// // });
|
|
92
|
+
// // throw new SanitizerError("Both primary and fallback sanitizers failed.");
|
|
93
|
+
// // }
|
|
94
|
+
// // }
|
|
95
|
+
// // }
|
|
96
|
+
// // /**
|
|
97
|
+
// // * Dynamic express middleware for sanitizing body.
|
|
98
|
+
// // * Options can override global config on each route.
|
|
99
|
+
// // */
|
|
100
|
+
// // middleware(options?: any) {
|
|
101
|
+
// // return (req: any, _res: any, next: any) => {
|
|
102
|
+
// // try {
|
|
103
|
+
// // if (req.body && typeof req.body === "object") {
|
|
104
|
+
// // for (const key of Object.keys(req.body)) {
|
|
105
|
+
// // const original = req.body[key];
|
|
106
|
+
// // if (typeof original === "string") {
|
|
107
|
+
// // const sanitized = this.sanitize(original, options);
|
|
108
|
+
// // logger.debug("🧼 Sanitized field", {
|
|
109
|
+
// // field: key,
|
|
110
|
+
// // before: original.slice(0, 80),
|
|
111
|
+
// // after: sanitized.slice(0, 80)
|
|
112
|
+
// // });
|
|
113
|
+
// // req.body[key] = sanitized;
|
|
114
|
+
// // }
|
|
115
|
+
// // }
|
|
116
|
+
// // }
|
|
117
|
+
// // next();
|
|
118
|
+
// // } catch (err: any) {
|
|
119
|
+
// // logger.error("❌ Sanitizer middleware failed", {
|
|
120
|
+
// // error: err?.message
|
|
121
|
+
// // });
|
|
122
|
+
// // next(new SanitizerError("Sanitizer middleware failure"));
|
|
123
|
+
// // }
|
|
124
|
+
// // };
|
|
125
|
+
// // }
|
|
126
|
+
// // }
|
|
127
|
+
// // src/managers/SanitizerManager.ts - FIXED
|
|
128
|
+
// import { SanitizerError } from "../core/errors/SanitizerError.js";
|
|
129
|
+
// import { logger } from "../logging";
|
|
130
|
+
// interface SanitizerAdapter {
|
|
131
|
+
// sanitize: (value: string, options?: any) => string;
|
|
132
|
+
// }
|
|
133
|
+
// export class SanitizerManager {
|
|
134
|
+
// private primary: SanitizerAdapter;
|
|
135
|
+
// private fallback: SanitizerAdapter | null;
|
|
136
|
+
// private useFallbackOnly: boolean = false;
|
|
137
|
+
// constructor(primary: SanitizerAdapter, fallback: SanitizerAdapter | null = null) {
|
|
138
|
+
// this.primary = primary;
|
|
139
|
+
// this.fallback = fallback;
|
|
140
|
+
// }
|
|
141
|
+
// /**
|
|
142
|
+
// * Sanitize a single value
|
|
143
|
+
// */
|
|
144
|
+
// sanitize(value: string, options?: any): string {
|
|
145
|
+
// // Don't process non-strings
|
|
146
|
+
// if (typeof value !== 'string') {
|
|
147
|
+
// return value;
|
|
148
|
+
// }
|
|
149
|
+
// // Use only one sanitizer, not both
|
|
150
|
+
// if (this.useFallbackOnly && this.fallback) {
|
|
151
|
+
// return this.fallback.sanitize(value, options);
|
|
152
|
+
// }
|
|
153
|
+
// try {
|
|
154
|
+
// return this.primary.sanitize(value, options);
|
|
155
|
+
// } catch (err: any) {
|
|
156
|
+
// logger.warn("⚠ Primary sanitizer failed", { error: err?.message });
|
|
157
|
+
// if (!this.fallback) {
|
|
158
|
+
// throw new SanitizerError("Primary sanitizer failed and no fallback available.");
|
|
159
|
+
// }
|
|
160
|
+
// logger.info("📌 Using fallback sanitizer");
|
|
161
|
+
// this.useFallbackOnly = true; // Use fallback for subsequent calls
|
|
162
|
+
// return this.fallback.sanitize(value, options);
|
|
163
|
+
// }
|
|
164
|
+
// }
|
|
165
|
+
// /**
|
|
166
|
+
// * Middleware that doesn't mutate original request
|
|
167
|
+
// */
|
|
168
|
+
// middleware(options?: any) {
|
|
169
|
+
// return (req: any, _res: any, next: any) => {
|
|
170
|
+
// try {
|
|
171
|
+
// // Create a sanitized copy of body instead of mutating
|
|
172
|
+
// if (req.body && typeof req.body === "object") {
|
|
173
|
+
// const originalBody = req.body;
|
|
174
|
+
// const sanitizedBody: any = Array.isArray(originalBody) ? [] : {};
|
|
175
|
+
// for (const key of Object.keys(originalBody)) {
|
|
176
|
+
// const value = originalBody[key];
|
|
177
|
+
// if (typeof value === "string") {
|
|
178
|
+
// sanitizedBody[key] = this.sanitize(value, options);
|
|
179
|
+
// } else if (Array.isArray(value)) {
|
|
180
|
+
// sanitizedBody[key] = value.map(item =>
|
|
181
|
+
// typeof item === "string" ? this.sanitize(item, options) : item
|
|
182
|
+
// );
|
|
183
|
+
// } else {
|
|
184
|
+
// sanitizedBody[key] = value;
|
|
185
|
+
// }
|
|
186
|
+
// }
|
|
187
|
+
// // Store sanitized version separately
|
|
188
|
+
// req.sanitizedBody = sanitizedBody;
|
|
189
|
+
// logger.debug("🧼 Request body sanitized", {
|
|
190
|
+
// originalKeys: Object.keys(originalBody),
|
|
191
|
+
// sanitizedKeys: Object.keys(sanitizedBody)
|
|
192
|
+
// });
|
|
193
|
+
// }
|
|
194
|
+
// next();
|
|
195
|
+
// } catch (err: any) {
|
|
196
|
+
// logger.error("❌ Sanitizer middleware failed", {
|
|
197
|
+
// error: err?.message
|
|
198
|
+
// });
|
|
199
|
+
// next(new SanitizerError("Sanitizer middleware failure"));
|
|
200
|
+
// }
|
|
201
|
+
// };
|
|
202
|
+
// }
|
|
203
|
+
// }
|
|
204
|
+
// src/managers/SanitizerManager.ts - COMPLETE FIXED
|
|
205
|
+
const SanitizerError_js_1 = require("../core/errors/SanitizerError.js");
|
|
206
|
+
const logging_1 = require("../logging");
|
|
207
|
+
class SanitizerManager {
|
|
208
|
+
constructor(primary, fallback = null) {
|
|
209
|
+
this.primary = primary;
|
|
210
|
+
this.fallback = fallback;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Sanitize a single value (public API)
|
|
214
|
+
*/
|
|
215
|
+
sanitize(value, options) {
|
|
216
|
+
// Don't process non-strings
|
|
217
|
+
if (typeof value !== 'string') {
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
return this.primary.sanitize(value, options);
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
logging_1.logger.warn("⚠ Primary sanitizer failed", { error: err?.message });
|
|
225
|
+
if (!this.fallback) {
|
|
226
|
+
throw new SanitizerError_js_1.SanitizerError("Primary sanitizer failed and no fallback available.");
|
|
227
|
+
}
|
|
228
|
+
logging_1.logger.info("📌 Using fallback sanitizer");
|
|
229
|
+
return this.fallback.sanitize(value, options);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Middleware - Per-request fallback logic
|
|
234
|
+
*/
|
|
235
|
+
middleware(options) {
|
|
236
|
+
return (req, _res, next) => {
|
|
237
|
+
let fallbackTriggered = false;
|
|
238
|
+
// Helper function with per-request fallback logic
|
|
239
|
+
const safeSanitize = (value) => {
|
|
240
|
+
if (fallbackTriggered && this.fallback) {
|
|
241
|
+
return this.fallback.sanitize(value, options);
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
return this.primary.sanitize(value, options);
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
if (!this.fallback) {
|
|
248
|
+
throw err;
|
|
249
|
+
}
|
|
250
|
+
fallbackTriggered = true;
|
|
251
|
+
logging_1.logger.warn("⚠ Switching to fallback sanitizer for this request");
|
|
252
|
+
return this.fallback.sanitize(value, options);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
try {
|
|
256
|
+
// Create a sanitized copy of body instead of mutating
|
|
257
|
+
if (req.body && typeof req.body === "object") {
|
|
258
|
+
const originalBody = req.body;
|
|
259
|
+
const sanitizedBody = Array.isArray(originalBody) ? [] : {};
|
|
260
|
+
for (const key of Object.keys(originalBody)) {
|
|
261
|
+
const value = originalBody[key];
|
|
262
|
+
if (typeof value === "string") {
|
|
263
|
+
sanitizedBody[key] = safeSanitize(value);
|
|
264
|
+
}
|
|
265
|
+
else if (Array.isArray(value)) {
|
|
266
|
+
sanitizedBody[key] = value.map(item => typeof item === "string" ? safeSanitize(item) : item);
|
|
267
|
+
}
|
|
268
|
+
else if (value && typeof value === "object") {
|
|
269
|
+
// Recursive sanitization for nested objects (optional)
|
|
270
|
+
sanitizedBody[key] = value; // Keep as-is for now
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
sanitizedBody[key] = value;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Store sanitized version separately
|
|
277
|
+
req.sanitizedBody = sanitizedBody;
|
|
278
|
+
logging_1.logger.debug("🧼 Request body sanitized", {
|
|
279
|
+
originalKeys: Object.keys(originalBody),
|
|
280
|
+
sanitizedKeys: Object.keys(sanitizedBody),
|
|
281
|
+
usedFallback: fallbackTriggered
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
next();
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
logging_1.logger.error("❌ Sanitizer middleware failed", {
|
|
288
|
+
error: err?.message
|
|
289
|
+
});
|
|
290
|
+
next(new SanitizerError_js_1.SanitizerError("Sanitizer middleware failure"));
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
exports.SanitizerManager = SanitizerManager;
|
|
296
|
+
//# sourceMappingURL=SanitizerManager.js.map
|
|
@@ -0,0 +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\";\r\n// // // import { logger } from \"../logging\";\r\n\r\n// // // interface SanitizerAdapter {\r\n// // // sanitize: (value: string) => string;\r\n// // // middleware?: () => any;\r\n// // // }\r\n\r\n// // // export 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): string {\r\n// // // try {\r\n// // // return this.primary.sanitize(value);\r\n// // // } catch (err: any) {\r\n// // // logger.warn(\"⚠ Sanitizer primary adapter failed\", { error: err?.message });\r\n\r\n// // // if (!this.fallback) {\r\n// // // throw new SanitizerError(\"Primary sanitizer failed, no fallback available.\");\r\n// // // }\r\n\r\n// // // try {\r\n// // // logger.info(\"📌 Using fallback sanitizer\");\r\n// // // return this.fallback.sanitize(value);\r\n// // // } catch (fallbackErr: any) {\r\n// // // logger.error(\"❌ Fallback sanitizer failed\", {\r\n// // // error: fallbackErr?.message\r\n// // // });\r\n// // // throw new SanitizerError(\"Both primary and fallback sanitizers failed.\");\r\n// // // }\r\n// // // }\r\n// // // }\r\n\r\n// // // middleware() {\r\n// // // return (req: any, _res: any, next: any) => {\r\n// // // try {\r\n// // // if (req.body && typeof req.body === \"object\") {\r\n// // // for (const key of Object.keys(req.body)) {\r\n// // // const value = req.body[key];\r\n\r\n// // // if (typeof value === \"string\") {\r\n// // // const clean = this.sanitize(value);\r\n\r\n// // // logger.debug(\"🧼 Sanitized field\", {\r\n// // // field: key,\r\n// // // before: value.slice(0, 80),\r\n// // // after: clean.slice(0, 80),\r\n// // // });\r\n\r\n// // // req.body[key] = clean;\r\n// // // }\r\n// // // }\r\n// // // }\r\n\r\n// // // next();\r\n// // // } catch (err: any) {\r\n// // // logger.error(\"❌ Sanitizer middleware failed\", { error: err?.message });\r\n// // // next(new SanitizerError(\"Sanitizer middleware failure\"));\r\n// // // }\r\n// // // };\r\n// // // }\r\n// // // }\r\n\r\n\r\n\r\n// // // src/managers/SanitizerManager.ts\r\n// // import { SanitizerError } from \"../core/errors/SanitizerError.js\";\r\n// // import { logger } from \"../logging\";\r\n\r\n// // interface SanitizerAdapter {\r\n// // sanitize: (value: string, options?: any) => string;\r\n// // }\r\n\r\n// // export 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// // /**\r\n// // * Sanitize a single value with optional dynamic options.\r\n// // */\r\n// // sanitize(value: string, options?: any): string {\r\n// // try {\r\n// // return this.primary.sanitize(value, options);\r\n\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// // try {\r\n// // logger.info(\"📌 Using fallback sanitizer\");\r\n// // return this.fallback.sanitize(value, options);\r\n\r\n// // } catch (fallbackErr: any) {\r\n// // logger.error(\"❌ Fallback sanitizer failed\", {\r\n// // error: fallbackErr?.message\r\n// // });\r\n\r\n// // throw new SanitizerError(\"Both primary and fallback sanitizers failed.\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n// // /**\r\n// // * Dynamic express middleware for sanitizing body.\r\n// // * Options can override global config on each route.\r\n// // */\r\n// // middleware(options?: any) {\r\n// // return (req: any, _res: any, next: any) => {\r\n// // try {\r\n// // if (req.body && typeof req.body === \"object\") {\r\n// // for (const key of Object.keys(req.body)) {\r\n// // const original = req.body[key];\r\n\r\n// // if (typeof original === \"string\") {\r\n// // const sanitized = this.sanitize(original, options);\r\n\r\n// // logger.debug(\"🧼 Sanitized field\", {\r\n// // field: key,\r\n// // before: original.slice(0, 80),\r\n// // after: sanitized.slice(0, 80)\r\n// // });\r\n\r\n// // req.body[key] = sanitized;\r\n// // }\r\n// // }\r\n// // }\r\n\r\n// // next();\r\n\r\n// // } catch (err: any) {\r\n// // logger.error(\"❌ Sanitizer middleware failed\", {\r\n// // error: err?.message\r\n// // });\r\n\r\n// // next(new SanitizerError(\"Sanitizer middleware failure\"));\r\n// // }\r\n// // };\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n// // src/managers/SanitizerManager.ts - FIXED\r\n// import { SanitizerError } from \"../core/errors/SanitizerError.js\";\r\n// import { logger } from \"../logging\";\r\n\r\n// interface SanitizerAdapter {\r\n// sanitize: (value: string, options?: any) => string;\r\n// }\r\n\r\n// export class SanitizerManager {\r\n// private primary: SanitizerAdapter;\r\n// private fallback: SanitizerAdapter | null;\r\n// private useFallbackOnly: boolean = false;\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// /**\r\n// * Sanitize a single value\r\n// */\r\n// sanitize(value: string, options?: any): string {\r\n// // Don't process non-strings\r\n// if (typeof value !== 'string') {\r\n// return value;\r\n// }\r\n\r\n// // Use only one sanitizer, not both\r\n// if (this.useFallbackOnly && 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// 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// this.useFallbackOnly = true; // Use fallback for subsequent calls\r\n \r\n// return this.fallback.sanitize(value, options);\r\n// }\r\n// }\r\n\r\n// /**\r\n// * Middleware that doesn't mutate original request\r\n// */\r\n// middleware(options?: any) {\r\n// return (req: any, _res: any, next: any) => {\r\n// try {\r\n// // Create a sanitized copy of body instead of mutating\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] = this.sanitize(value, options);\r\n// } else if (Array.isArray(value)) {\r\n// sanitizedBody[key] = value.map(item => \r\n// typeof item === \"string\" ? this.sanitize(item, options) : item\r\n// );\r\n// } else {\r\n// sanitizedBody[key] = value;\r\n// }\r\n// }\r\n \r\n// // Store sanitized version separately\r\n// req.sanitizedBody = sanitizedBody;\r\n// logger.debug(\"🧼 Request body sanitized\", {\r\n// originalKeys: Object.keys(originalBody),\r\n// sanitizedKeys: Object.keys(sanitizedBody)\r\n// });\r\n// }\r\n\r\n// next();\r\n// } catch (err: any) {\r\n// logger.error(\"❌ 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// }\r\n\r\n\r\n\r\n// src/managers/SanitizerManager.ts - COMPLETE FIXED\r\nimport { 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 /**\r\n * Sanitize a single value (public API)\r\n */\r\n sanitize(value: string, options?: any): string {\r\n // Don't process non-strings\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 - Per-request fallback logic\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 // Helper function with per-request fallback logic\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 // Create a sanitized copy of body instead of mutating\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 // Recursive sanitization for nested objects (optional)\r\n sanitizedBody[key] = value; // Keep as-is for now\r\n } else {\r\n sanitizedBody[key] = value;\r\n }\r\n }\r\n \r\n // Store sanitized version separately\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}"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HiSecureConfig } from "../core/types/HiSecureConfig.js";
|
|
2
|
+
interface ValidatorAdapter {
|
|
3
|
+
validate: (schema?: any) => any;
|
|
4
|
+
}
|
|
5
|
+
export declare class ValidatorManager {
|
|
6
|
+
private config;
|
|
7
|
+
private primaryAdapter;
|
|
8
|
+
private fallbackAdapter;
|
|
9
|
+
constructor(config: HiSecureConfig["validation"], primaryAdapter: ValidatorAdapter, fallbackAdapter: ValidatorAdapter | null);
|
|
10
|
+
validate(schema?: any): (req: any, res: any, next: any) => void;
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=ValidatorManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidatorManager.d.ts","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"AAyMA,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjE,UAAU,gBAAgB;IACtB,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,eAAe,CAA0B;gBAG7C,MAAM,EAAE,cAAc,CAAC,YAAY,CAAC,EACpC,cAAc,EAAE,gBAAgB,EAChC,eAAe,EAAE,gBAAgB,GAAG,IAAI;IAO5C,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,IACT,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG;CA6C5C"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// // // import { HiSecureConfig } from "../core/config";
|
|
3
|
+
// // // import { logger } from "../logging";
|
|
4
|
+
// // // import { ValidationError } from "../core/errors/ValidationError";
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ValidatorManager = void 0;
|
|
7
|
+
// // // export class ValidatorManager {
|
|
8
|
+
// // // private config: HiSecureConfig["validation"];
|
|
9
|
+
// // // private primaryAdapter: any;
|
|
10
|
+
// // // private fallbackAdapter: any;
|
|
11
|
+
// // // constructor(
|
|
12
|
+
// // // config: HiSecureConfig["validation"],
|
|
13
|
+
// // // primaryAdapter: any,
|
|
14
|
+
// // // fallbackAdapter: any
|
|
15
|
+
// // // ) {
|
|
16
|
+
// // // this.config = config;
|
|
17
|
+
// // // this.primaryAdapter = primaryAdapter;
|
|
18
|
+
// // // this.fallbackAdapter = fallbackAdapter;
|
|
19
|
+
// // // }
|
|
20
|
+
// // // /**
|
|
21
|
+
// // // * Validate request body using primary adapter (Zod/express-validator).
|
|
22
|
+
// // // * Fallback is only used if the adapter implementation itself throws.
|
|
23
|
+
// // // */
|
|
24
|
+
// // // validate(schema: any) {
|
|
25
|
+
// // // return (req: any, res: any, next: any) => {
|
|
26
|
+
// // // try {
|
|
27
|
+
// // // const middleware = this.primaryAdapter.validate(schema);
|
|
28
|
+
// // // return middleware(req, res, next);
|
|
29
|
+
// // // } catch (err: any) {
|
|
30
|
+
// // // logger.warn("⚠ Primary validator failed", {
|
|
31
|
+
// // // error: err?.message,
|
|
32
|
+
// // // path: req.path,
|
|
33
|
+
// // // method: req.method
|
|
34
|
+
// // // });
|
|
35
|
+
// // // if (!this.fallbackAdapter) {
|
|
36
|
+
// // // return next(new ValidationError("Validation failed."));
|
|
37
|
+
// // // }
|
|
38
|
+
// // // try {
|
|
39
|
+
// // // logger.info("📌 Using fallback validator");
|
|
40
|
+
// // // const fallbackMiddleware = this.fallbackAdapter.validate(schema);
|
|
41
|
+
// // // return fallbackMiddleware(req, res, next);
|
|
42
|
+
// // // } catch (fallbackErr: any) {
|
|
43
|
+
// // // logger.error("❌ Fallback validation also failed", {
|
|
44
|
+
// // // error: fallbackErr?.message
|
|
45
|
+
// // // });
|
|
46
|
+
// // // return next(new ValidationError("Both validators failed."));
|
|
47
|
+
// // // }
|
|
48
|
+
// // // }
|
|
49
|
+
// // // };
|
|
50
|
+
// // // }
|
|
51
|
+
// // // }
|
|
52
|
+
// // import { HiSecureConfig } from "../core/config.js";
|
|
53
|
+
// // import { logger } from "../logging";
|
|
54
|
+
// // import { ValidationError } from "../core/errors/ValidationError.js";
|
|
55
|
+
// // interface ValidatorAdapter {
|
|
56
|
+
// // validate: (schema?: any) => any;
|
|
57
|
+
// // }
|
|
58
|
+
// // export class ValidatorManager {
|
|
59
|
+
// // private config: HiSecureConfig["validation"];
|
|
60
|
+
// // private primaryAdapter: ValidatorAdapter;
|
|
61
|
+
// // private fallbackAdapter: ValidatorAdapter | null;
|
|
62
|
+
// // constructor(
|
|
63
|
+
// // config: HiSecureConfig["validation"],
|
|
64
|
+
// // primaryAdapter: ValidatorAdapter,
|
|
65
|
+
// // fallbackAdapter: ValidatorAdapter | null
|
|
66
|
+
// // ) {
|
|
67
|
+
// // this.config = config;
|
|
68
|
+
// // this.primaryAdapter = primaryAdapter;
|
|
69
|
+
// // this.fallbackAdapter = fallbackAdapter;
|
|
70
|
+
// // }
|
|
71
|
+
// // /**
|
|
72
|
+
// // * MAIN DYNAMIC VALIDATOR ENTRY
|
|
73
|
+
// // * schema = per-route schema
|
|
74
|
+
// // * If schema is undefined → use global schema
|
|
75
|
+
// // */
|
|
76
|
+
// // validate(schema?: any) {
|
|
77
|
+
// // return (req: any, res: any, next: any) => {
|
|
78
|
+
// // try {
|
|
79
|
+
// // const middleware = this.primaryAdapter.validate(schema);
|
|
80
|
+
// // return middleware(req, res, next);
|
|
81
|
+
// // } catch (err: any) {
|
|
82
|
+
// // logger.warn("⚠ Primary validator failed", {
|
|
83
|
+
// // error: err?.message,
|
|
84
|
+
// // path: req.path,
|
|
85
|
+
// // method: req.method
|
|
86
|
+
// // });
|
|
87
|
+
// // if (!this.fallbackAdapter) {
|
|
88
|
+
// // return next(new ValidationError("Validation failed"));
|
|
89
|
+
// // }
|
|
90
|
+
// // try {
|
|
91
|
+
// // logger.info("📌 Using fallback validator");
|
|
92
|
+
// // const fallbackMiddleware = this.fallbackAdapter.validate(schema);
|
|
93
|
+
// // return fallbackMiddleware(req, res, next);
|
|
94
|
+
// // } catch (fallbackErr: any) {
|
|
95
|
+
// // logger.error("❌ Fallback validator also failed", {
|
|
96
|
+
// // error: fallbackErr?.message
|
|
97
|
+
// // });
|
|
98
|
+
// // return next(new ValidationError("Both validators failed"));
|
|
99
|
+
// // }
|
|
100
|
+
// // }
|
|
101
|
+
// // };
|
|
102
|
+
// // }
|
|
103
|
+
// // }
|
|
104
|
+
// // src/managers/ValidatorManager.ts - FIXED
|
|
105
|
+
// import { logger } from "../logging";
|
|
106
|
+
// import { ValidationError } from "../core/errors/ValidationError.js";
|
|
107
|
+
// import { HiSecureConfig } from "../core/types/HiSecureConfig";
|
|
108
|
+
// interface ValidatorAdapter {
|
|
109
|
+
// validate: (schema?: any) => any;
|
|
110
|
+
// }
|
|
111
|
+
// export class ValidatorManager {
|
|
112
|
+
// private config: HiSecureConfig["validation"];
|
|
113
|
+
// private primaryAdapter: ValidatorAdapter;
|
|
114
|
+
// private fallbackAdapter: ValidatorAdapter | null;
|
|
115
|
+
// constructor(
|
|
116
|
+
// config: HiSecureConfig["validation"],
|
|
117
|
+
// primaryAdapter: ValidatorAdapter,
|
|
118
|
+
// fallbackAdapter: ValidatorAdapter | null
|
|
119
|
+
// ) {
|
|
120
|
+
// this.config = config;
|
|
121
|
+
// this.primaryAdapter = primaryAdapter;
|
|
122
|
+
// this.fallbackAdapter = fallbackAdapter;
|
|
123
|
+
// }
|
|
124
|
+
// validate(schema?: any) {
|
|
125
|
+
// return (req: any, res: any, next: any) => {
|
|
126
|
+
// // Execute primary adapter middleware
|
|
127
|
+
// const primaryMiddleware = this.primaryAdapter.validate(schema);
|
|
128
|
+
// // Run middleware and handle errors properly
|
|
129
|
+
// primaryMiddleware(req, res, (err?: any) => {
|
|
130
|
+
// if (!err) {
|
|
131
|
+
// return next(); // Validation passed
|
|
132
|
+
// }
|
|
133
|
+
// // If error is a ValidationError, pass it through (don't fallback!)
|
|
134
|
+
// if (err instanceof ValidationError) {
|
|
135
|
+
// logger.warn("⚠ Validation failed", {
|
|
136
|
+
// path: req.path,
|
|
137
|
+
// method: req.method,
|
|
138
|
+
// error: err.message
|
|
139
|
+
// });
|
|
140
|
+
// return next(err);
|
|
141
|
+
// }
|
|
142
|
+
// // Only use fallback for ADAPTER errors, not validation errors
|
|
143
|
+
// logger.warn("⚠ Primary validator adapter failed", {
|
|
144
|
+
// error: err?.message,
|
|
145
|
+
// path: req.path,
|
|
146
|
+
// method: req.method
|
|
147
|
+
// });
|
|
148
|
+
// if (!this.fallbackAdapter) {
|
|
149
|
+
// return next(new ValidationError("Validation system error"));
|
|
150
|
+
// }
|
|
151
|
+
// // Try fallback adapter
|
|
152
|
+
// const fallbackMiddleware = this.fallbackAdapter.validate(schema);
|
|
153
|
+
// fallbackMiddleware(req, res, (fallbackErr?: any) => {
|
|
154
|
+
// if (fallbackErr) {
|
|
155
|
+
// logger.error("❌ Fallback validator also failed", {
|
|
156
|
+
// error: fallbackErr?.message
|
|
157
|
+
// });
|
|
158
|
+
// return next(new ValidationError("Validation system unavailable"));
|
|
159
|
+
// }
|
|
160
|
+
// next(); // Fallback validation passed
|
|
161
|
+
// });
|
|
162
|
+
// });
|
|
163
|
+
// };
|
|
164
|
+
// }
|
|
165
|
+
// }
|
|
166
|
+
// src/managers/ValidatorManager.ts - COMPLETE FIXED
|
|
167
|
+
const logging_1 = require("../logging");
|
|
168
|
+
const ValidationError_js_1 = require("../core/errors/ValidationError.js");
|
|
169
|
+
class ValidatorManager {
|
|
170
|
+
constructor(config, primaryAdapter, fallbackAdapter) {
|
|
171
|
+
this.config = config;
|
|
172
|
+
this.primaryAdapter = primaryAdapter;
|
|
173
|
+
this.fallbackAdapter = fallbackAdapter;
|
|
174
|
+
}
|
|
175
|
+
validate(schema) {
|
|
176
|
+
return (req, res, next) => {
|
|
177
|
+
// Execute primary adapter middleware
|
|
178
|
+
const primaryMiddleware = this.primaryAdapter.validate(schema);
|
|
179
|
+
// Run middleware and handle errors properly
|
|
180
|
+
primaryMiddleware(req, res, (err) => {
|
|
181
|
+
if (!err) {
|
|
182
|
+
return next(); // Validation passed
|
|
183
|
+
}
|
|
184
|
+
// If error is a ValidationError, pass it through (don't fallback!)
|
|
185
|
+
if (err instanceof ValidationError_js_1.ValidationError) {
|
|
186
|
+
logging_1.logger.warn("⚠ Validation failed", {
|
|
187
|
+
path: req.path,
|
|
188
|
+
method: req.method,
|
|
189
|
+
error: err.message
|
|
190
|
+
});
|
|
191
|
+
return next(err);
|
|
192
|
+
}
|
|
193
|
+
// Only use fallback for ADAPTER errors, not validation errors
|
|
194
|
+
logging_1.logger.warn("⚠ Primary validator adapter failed", {
|
|
195
|
+
error: err?.message,
|
|
196
|
+
path: req.path,
|
|
197
|
+
method: req.method
|
|
198
|
+
});
|
|
199
|
+
if (!this.fallbackAdapter) {
|
|
200
|
+
return next(new ValidationError_js_1.ValidationError("Validation system error"));
|
|
201
|
+
}
|
|
202
|
+
// Try fallback adapter
|
|
203
|
+
const fallbackMiddleware = this.fallbackAdapter.validate(schema);
|
|
204
|
+
fallbackMiddleware(req, res, (fallbackErr) => {
|
|
205
|
+
if (fallbackErr) {
|
|
206
|
+
logging_1.logger.error("❌ Fallback validator also failed", {
|
|
207
|
+
error: fallbackErr?.message
|
|
208
|
+
});
|
|
209
|
+
return next(new ValidationError_js_1.ValidationError("Validation system unavailable"));
|
|
210
|
+
}
|
|
211
|
+
next(); // Fallback validation passed
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
exports.ValidatorManager = ValidatorManager;
|
|
218
|
+
//# sourceMappingURL=ValidatorManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidatorManager.js","sourceRoot":"","sources":["../../src/managers/ValidatorManager.ts"],"names":[],"mappings":"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","sourcesContent":["// // // import { HiSecureConfig } from \"../core/config\";\r\n// // // import { logger } from \"../logging\";\r\n// // // import { ValidationError } from \"../core/errors/ValidationError\";\r\n\r\n// // // export class ValidatorManager {\r\n// // // private config: HiSecureConfig[\"validation\"];\r\n// // // private primaryAdapter: any;\r\n// // // private fallbackAdapter: any;\r\n\r\n// // // constructor(\r\n// // // config: HiSecureConfig[\"validation\"],\r\n// // // primaryAdapter: any,\r\n// // // fallbackAdapter: any\r\n// // // ) {\r\n// // // this.config = config;\r\n// // // this.primaryAdapter = primaryAdapter;\r\n// // // this.fallbackAdapter = fallbackAdapter;\r\n// // // }\r\n\r\n// // // /**\r\n// // // * Validate request body using primary adapter (Zod/express-validator).\r\n// // // * Fallback is only used if the adapter implementation itself throws.\r\n// // // */\r\n// // // validate(schema: any) {\r\n// // // return (req: any, res: any, next: any) => {\r\n// // // try {\r\n// // // const middleware = this.primaryAdapter.validate(schema);\r\n// // // return middleware(req, res, next);\r\n\r\n// // // } catch (err: any) {\r\n// // // logger.warn(\"⚠ Primary validator failed\", {\r\n// // // error: err?.message,\r\n// // // path: req.path,\r\n// // // method: req.method\r\n// // // });\r\n\r\n// // // if (!this.fallbackAdapter) {\r\n// // // return next(new ValidationError(\"Validation failed.\"));\r\n// // // }\r\n\r\n// // // try {\r\n// // // logger.info(\"📌 Using fallback validator\");\r\n// // // const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n// // // return fallbackMiddleware(req, res, next);\r\n\r\n// // // } catch (fallbackErr: any) {\r\n// // // logger.error(\"❌ Fallback validation also failed\", {\r\n// // // error: fallbackErr?.message\r\n// // // });\r\n\r\n// // // return next(new ValidationError(\"Both validators failed.\"));\r\n// // // }\r\n// // // }\r\n// // // };\r\n// // // }\r\n// // // }\r\n\r\n\r\n\r\n// // import { HiSecureConfig } from \"../core/config.js\";\r\n// // import { logger } from \"../logging\";\r\n// // import { ValidationError } from \"../core/errors/ValidationError.js\";\r\n\r\n// // interface ValidatorAdapter {\r\n// // validate: (schema?: any) => any;\r\n// // }\r\n\r\n// // export class ValidatorManager {\r\n// // private config: HiSecureConfig[\"validation\"];\r\n// // private primaryAdapter: ValidatorAdapter;\r\n// // private fallbackAdapter: ValidatorAdapter | null;\r\n\r\n// // constructor(\r\n// // config: HiSecureConfig[\"validation\"],\r\n// // primaryAdapter: ValidatorAdapter,\r\n// // fallbackAdapter: ValidatorAdapter | null\r\n// // ) {\r\n// // this.config = config;\r\n// // this.primaryAdapter = primaryAdapter;\r\n// // this.fallbackAdapter = fallbackAdapter;\r\n// // }\r\n\r\n// // /**\r\n// // * MAIN DYNAMIC VALIDATOR ENTRY\r\n// // * schema = per-route schema\r\n// // * If schema is undefined → use global schema\r\n// // */\r\n// // validate(schema?: any) {\r\n// // return (req: any, res: any, next: any) => {\r\n// // try {\r\n// // const middleware = this.primaryAdapter.validate(schema);\r\n// // return middleware(req, res, next);\r\n\r\n// // } catch (err: any) {\r\n// // logger.warn(\"⚠ Primary validator failed\", {\r\n// // error: err?.message,\r\n// // path: req.path,\r\n// // method: req.method\r\n// // });\r\n\r\n// // if (!this.fallbackAdapter) {\r\n// // return next(new ValidationError(\"Validation failed\"));\r\n// // }\r\n\r\n// // try {\r\n// // logger.info(\"📌 Using fallback validator\");\r\n// // const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n// // return fallbackMiddleware(req, res, next);\r\n\r\n// // } catch (fallbackErr: any) {\r\n// // logger.error(\"❌ Fallback validator also failed\", {\r\n// // error: fallbackErr?.message\r\n// // });\r\n\r\n// // return next(new ValidationError(\"Both validators failed\"));\r\n// // }\r\n// // }\r\n// // };\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n\r\n\r\n// // src/managers/ValidatorManager.ts - FIXED\r\n// import { logger } from \"../logging\";\r\n// import { ValidationError } from \"../core/errors/ValidationError.js\";\r\n// import { HiSecureConfig } from \"../core/types/HiSecureConfig\";\r\n\r\n// interface ValidatorAdapter {\r\n// validate: (schema?: any) => any;\r\n// }\r\n\r\n// export class ValidatorManager {\r\n// private config: HiSecureConfig[\"validation\"];\r\n// private primaryAdapter: ValidatorAdapter;\r\n// private fallbackAdapter: ValidatorAdapter | null;\r\n\r\n// constructor(\r\n// config: HiSecureConfig[\"validation\"],\r\n// primaryAdapter: ValidatorAdapter,\r\n// fallbackAdapter: ValidatorAdapter | null\r\n// ) {\r\n// this.config = config;\r\n// this.primaryAdapter = primaryAdapter;\r\n// this.fallbackAdapter = fallbackAdapter;\r\n// }\r\n\r\n// validate(schema?: any) {\r\n// return (req: any, res: any, next: any) => {\r\n// // Execute primary adapter middleware\r\n// const primaryMiddleware = this.primaryAdapter.validate(schema);\r\n \r\n// // Run middleware and handle errors properly\r\n// primaryMiddleware(req, res, (err?: any) => {\r\n// if (!err) {\r\n// return next(); // Validation passed\r\n// }\r\n \r\n// // If error is a ValidationError, pass it through (don't fallback!)\r\n// if (err instanceof ValidationError) {\r\n// logger.warn(\"⚠ Validation failed\", {\r\n// path: req.path,\r\n// method: req.method,\r\n// error: err.message\r\n// });\r\n// return next(err);\r\n// }\r\n \r\n// // Only use fallback for ADAPTER errors, not validation errors\r\n// logger.warn(\"⚠ Primary validator adapter failed\", {\r\n// error: err?.message,\r\n// path: req.path,\r\n// method: req.method\r\n// });\r\n\r\n// if (!this.fallbackAdapter) {\r\n// return next(new ValidationError(\"Validation system error\"));\r\n// }\r\n\r\n// // Try fallback adapter\r\n// const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n// fallbackMiddleware(req, res, (fallbackErr?: any) => {\r\n// if (fallbackErr) {\r\n// logger.error(\"❌ Fallback validator also failed\", {\r\n// error: fallbackErr?.message\r\n// });\r\n// return next(new ValidationError(\"Validation system unavailable\"));\r\n// }\r\n// next(); // Fallback validation passed\r\n// });\r\n// });\r\n// };\r\n// }\r\n// }\r\n\r\n\r\n// src/managers/ValidatorManager.ts - COMPLETE FIXED\r\nimport { logger } from \"../logging\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\";\r\nimport { HiSecureConfig } from \"../core/types/HiSecureConfig.js\"; // ✅ FIXED IMPORT\r\n\r\ninterface ValidatorAdapter {\r\n validate: (schema?: any) => any;\r\n}\r\n\r\nexport class ValidatorManager {\r\n private config: HiSecureConfig[\"validation\"];\r\n private primaryAdapter: ValidatorAdapter;\r\n private fallbackAdapter: ValidatorAdapter | null;\r\n\r\n constructor(\r\n config: HiSecureConfig[\"validation\"],\r\n primaryAdapter: ValidatorAdapter,\r\n fallbackAdapter: ValidatorAdapter | null\r\n ) {\r\n this.config = config;\r\n this.primaryAdapter = primaryAdapter;\r\n this.fallbackAdapter = fallbackAdapter;\r\n }\r\n\r\n validate(schema?: any) {\r\n return (req: any, res: any, next: any) => {\r\n // Execute primary adapter middleware\r\n const primaryMiddleware = this.primaryAdapter.validate(schema);\r\n \r\n // Run middleware and handle errors properly\r\n primaryMiddleware(req, res, (err?: any) => {\r\n if (!err) {\r\n return next(); // Validation passed\r\n }\r\n \r\n // If error is a ValidationError, pass it through (don't fallback!)\r\n if (err instanceof ValidationError) {\r\n logger.warn(\"⚠ Validation failed\", {\r\n path: req.path,\r\n method: req.method,\r\n error: err.message\r\n });\r\n return next(err);\r\n }\r\n \r\n // Only use fallback for ADAPTER errors, not validation errors\r\n logger.warn(\"⚠ Primary validator adapter failed\", {\r\n error: err?.message,\r\n path: req.path,\r\n method: req.method\r\n });\r\n\r\n if (!this.fallbackAdapter) {\r\n return next(new ValidationError(\"Validation system error\"));\r\n }\r\n\r\n // Try fallback adapter\r\n const fallbackMiddleware = this.fallbackAdapter.validate(schema);\r\n fallbackMiddleware(req, res, (fallbackErr?: any) => {\r\n if (fallbackErr) {\r\n logger.error(\"❌ Fallback validator also failed\", {\r\n error: fallbackErr?.message\r\n });\r\n return next(new ValidationError(\"Validation system unavailable\"));\r\n }\r\n next(); // Fallback validation passed\r\n });\r\n });\r\n };\r\n }\r\n}"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/middlewares/errorHandler.ts"],"names":[],"mappings":"AAmKA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAS1D,wBAAgB,YAAY,CACxB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,sCAwFtB"}
|