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
package/src/core/HiSecure.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { defaultConfig } from "./config.js";
|
|
|
3
3
|
import { LIB_NAME, LIB_VERSION } from "./constants.js";
|
|
4
4
|
import { deepMerge } from "../utils/deepMerge.js";
|
|
5
5
|
import { deepFreeze } from "../utils/deepFreeze.js";
|
|
6
|
-
import { logger } from "../logging
|
|
6
|
+
import { logger } from "../logging";
|
|
7
7
|
|
|
8
8
|
// Adapters
|
|
9
9
|
import { ArgonAdapter } from "../adapters/ArgonAdapter.js";
|
|
@@ -31,7 +31,7 @@ import compression from "compression";
|
|
|
31
31
|
import { errorHandler } from "../middlewares/errorHandler.js";
|
|
32
32
|
|
|
33
33
|
// Types
|
|
34
|
-
import { SecureOptions, ValidationSchema} from "./types/SecureOptions.js";
|
|
34
|
+
import { SecureOptions, ValidationSchema } from "./types/SecureOptions.js";
|
|
35
35
|
|
|
36
36
|
export class HiSecure {
|
|
37
37
|
private static instance: HiSecure | null = null;
|
|
@@ -55,15 +55,17 @@ export class HiSecure {
|
|
|
55
55
|
private sanitizerPrimary: any;
|
|
56
56
|
private sanitizerFallback: any;
|
|
57
57
|
|
|
58
|
-
// Private constructor for singleton
|
|
59
58
|
private constructor(userConfig: Partial<HiSecureConfig> = {}) {
|
|
60
59
|
this.config = deepMerge(defaultConfig, userConfig);
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
//
|
|
64
|
-
|
|
62
|
+
// Singleton & Init
|
|
63
|
+
|
|
65
64
|
static getInstance(config?: Partial<HiSecureConfig>): HiSecure {
|
|
66
65
|
if (!HiSecure.instance) {
|
|
66
|
+
logger.info("Creating HiSecure singleton", {
|
|
67
|
+
layer: "hisecure-core"
|
|
68
|
+
});
|
|
67
69
|
HiSecure.instance = new HiSecure(config);
|
|
68
70
|
HiSecure.instance.init();
|
|
69
71
|
}
|
|
@@ -76,36 +78,33 @@ export class HiSecure {
|
|
|
76
78
|
|
|
77
79
|
init(): void {
|
|
78
80
|
if (this.initialized) {
|
|
79
|
-
logger.warn("
|
|
81
|
+
logger.warn("Initialization skipped (already initialized)", {
|
|
82
|
+
layer: "hisecure-core"
|
|
83
|
+
});
|
|
80
84
|
return;
|
|
81
85
|
}
|
|
82
86
|
|
|
83
|
-
logger.info(
|
|
87
|
+
logger.info("Framework initialization started", {
|
|
88
|
+
layer: "hisecure-core",
|
|
89
|
+
lib: LIB_NAME,
|
|
90
|
+
version: LIB_VERSION
|
|
91
|
+
});
|
|
84
92
|
|
|
85
93
|
this.setupAdapters();
|
|
86
94
|
this.setupManagers();
|
|
87
95
|
this.setupDynamicManagers();
|
|
88
96
|
|
|
89
97
|
deepFreeze(this.config);
|
|
90
|
-
// deep Freeze - for now we remove from manager it needs to manage the adapters
|
|
91
|
-
// deepFreeze(this.hashManager);
|
|
92
|
-
// deepFreeze(this.rateLimitManager);
|
|
93
|
-
// deepFreeze(this.validatorManager);
|
|
94
|
-
// deepFreeze(this.sanitizerManager);
|
|
95
|
-
// deepFreeze(this.jsonManager);
|
|
96
|
-
// deepFreeze(this.corsManager);
|
|
97
|
-
// if (this.authManager) deepFreeze(this.authManager);
|
|
98
|
-
|
|
99
98
|
this.initialized = true;
|
|
100
|
-
logger.info("HiSecure initialized successfully");
|
|
101
|
-
}
|
|
102
99
|
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
logger.info("Framework initialized successfully", {
|
|
101
|
+
layer: "hisecure-core"
|
|
102
|
+
});
|
|
105
103
|
}
|
|
106
104
|
|
|
107
|
-
//
|
|
105
|
+
// Public Fluent APIs
|
|
108
106
|
|
|
107
|
+
|
|
109
108
|
static auth(options?: { required?: boolean; roles?: string[] }) {
|
|
110
109
|
const instance = this.getInstance();
|
|
111
110
|
if (!instance.authManager) {
|
|
@@ -124,16 +123,21 @@ export class HiSecure {
|
|
|
124
123
|
|
|
125
124
|
static rateLimit(preset: "strict" | "relaxed" | "api" | object) {
|
|
126
125
|
const instance = this.getInstance();
|
|
127
|
-
|
|
126
|
+
|
|
128
127
|
if (typeof preset === "string") {
|
|
129
|
-
|
|
128
|
+
logger.info("Rate limit preset applied", {
|
|
129
|
+
layer: "hisecure-core",
|
|
130
|
+
preset
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const presets: any = {
|
|
130
134
|
strict: { mode: "strict" },
|
|
131
135
|
relaxed: { mode: "relaxed" },
|
|
132
|
-
api: { mode: "api"
|
|
136
|
+
api: { mode: "api" }
|
|
133
137
|
};
|
|
134
|
-
return instance.rateLimitManager.middleware(presets[preset]
|
|
138
|
+
return instance.rateLimitManager.middleware(presets[preset]);
|
|
135
139
|
}
|
|
136
|
-
|
|
140
|
+
|
|
137
141
|
return instance.rateLimitManager.middleware({ options: preset });
|
|
138
142
|
}
|
|
139
143
|
|
|
@@ -143,115 +147,105 @@ export class HiSecure {
|
|
|
143
147
|
|
|
144
148
|
static json(options?: any) {
|
|
145
149
|
const instance = this.getInstance();
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
return [
|
|
151
|
+
instance.jsonManager.middleware(options),
|
|
152
|
+
instance.jsonManager.urlencoded()
|
|
153
|
+
];
|
|
150
154
|
}
|
|
151
155
|
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
static async hash(
|
|
156
|
+
// Utilities
|
|
157
|
+
|
|
158
|
+
static async hash(value: string): Promise<string> {
|
|
155
159
|
const instance = this.getInstance();
|
|
156
|
-
const result = await instance.hashManager.hash(
|
|
160
|
+
const result = await instance.hashManager.hash(value, { allowFallback: true });
|
|
157
161
|
return result.hash;
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
static async verify(
|
|
161
|
-
return this.getInstance().hashManager.verify(
|
|
164
|
+
static async verify(value: string, hash: string): Promise<boolean> {
|
|
165
|
+
return this.getInstance().hashManager.verify(value, hash);
|
|
162
166
|
}
|
|
163
167
|
|
|
164
168
|
static jwt = {
|
|
165
|
-
sign: (payload: object, options?: any) =>
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
},
|
|
172
|
-
|
|
173
|
-
verify: (token: string) => {
|
|
174
|
-
const instance = HiSecure.getInstance();
|
|
175
|
-
if (!instance.authManager) {
|
|
176
|
-
throw new Error("Auth not enabled");
|
|
177
|
-
}
|
|
178
|
-
return instance.authManager.verify(token);
|
|
179
|
-
},
|
|
180
|
-
|
|
169
|
+
sign: (payload: object, options?: any) =>
|
|
170
|
+
HiSecure.getInstance().authManager!.sign(payload, options),
|
|
171
|
+
|
|
172
|
+
verify: (token: string) =>
|
|
173
|
+
HiSecure.getInstance().authManager!.verify(token),
|
|
174
|
+
|
|
181
175
|
google: {
|
|
182
|
-
verifyIdToken: (idToken: string) =>
|
|
183
|
-
|
|
184
|
-
if (!instance.authManager) {
|
|
185
|
-
throw new Error("Auth not enabled");
|
|
186
|
-
}
|
|
187
|
-
return instance.authManager.verifyGoogleIdToken(idToken);
|
|
188
|
-
}
|
|
176
|
+
verifyIdToken: (idToken: string) =>
|
|
177
|
+
HiSecure.getInstance().authManager!.verifyGoogleIdToken(idToken)
|
|
189
178
|
}
|
|
190
179
|
};
|
|
191
180
|
|
|
192
|
-
//
|
|
193
|
-
|
|
181
|
+
// Global Middleware
|
|
182
|
+
|
|
194
183
|
static middleware(options?: SecureOptions | "api" | "strict" | "public") {
|
|
195
184
|
const instance = this.getInstance();
|
|
196
|
-
|
|
197
|
-
// Handle preset strings
|
|
185
|
+
|
|
198
186
|
if (typeof options === "string") {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
187
|
+
logger.info("Global middleware preset applied", {
|
|
188
|
+
layer: "hisecure-core",
|
|
189
|
+
preset: options
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const presets: any = {
|
|
193
|
+
api: { cors: true, rateLimit: "relaxed", sanitize: true },
|
|
194
|
+
strict: { cors: true, rateLimit: "strict", sanitize: true, auth: true },
|
|
195
|
+
public: { cors: true, rateLimit: true, sanitize: false }
|
|
203
196
|
};
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return instance.createMiddlewareChain(presetOptions);
|
|
207
|
-
}
|
|
208
|
-
return instance.createMiddlewareChain({});
|
|
197
|
+
|
|
198
|
+
return instance.createMiddlewareChain(presets[options] || {});
|
|
209
199
|
}
|
|
210
|
-
|
|
200
|
+
|
|
211
201
|
return instance.createMiddlewareChain(options || {});
|
|
212
202
|
}
|
|
213
203
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
204
|
+
// Internal Setup
|
|
205
|
+
|
|
206
|
+
private setupAdapters() {
|
|
207
|
+
logger.info("Adapters setup started", {
|
|
208
|
+
layer: "hisecure-core"
|
|
209
|
+
});
|
|
219
210
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
211
|
+
this.hashingPrimary =
|
|
212
|
+
this.config.hashing.primary === "argon2"
|
|
213
|
+
? new ArgonAdapter()
|
|
214
|
+
: new BcryptAdapter(this.config.hashing.saltRounds);
|
|
224
215
|
|
|
225
|
-
this.hashingFallback =
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
this.hashingFallback =
|
|
217
|
+
this.config.hashing.fallback === "bcrypt"
|
|
218
|
+
? new BcryptAdapter(this.config.hashing.saltRounds)
|
|
219
|
+
: null;
|
|
220
|
+
|
|
221
|
+
logger.info("Hashing adapters configured", {
|
|
222
|
+
layer: "hisecure-core",
|
|
223
|
+
primary: this.config.hashing.primary,
|
|
224
|
+
fallback: this.config.hashing.fallback ?? null
|
|
225
|
+
});
|
|
228
226
|
|
|
229
|
-
// Rate limiting
|
|
230
227
|
this.rateLimiterPrimary = this.config.rateLimiter.useAdaptiveMode
|
|
231
228
|
? new RLFlexibleAdapter()
|
|
232
229
|
: new ExpressRLAdapter();
|
|
233
|
-
this.rateLimiterFallback = new ExpressRLAdapter();
|
|
234
|
-
|
|
235
230
|
|
|
231
|
+
this.rateLimiterFallback = new ExpressRLAdapter();
|
|
236
232
|
|
|
233
|
+
logger.info("Rate limiter adapters configured", {
|
|
234
|
+
layer: "hisecure-core",
|
|
235
|
+
adaptive: this.config.rateLimiter.useAdaptiveMode
|
|
236
|
+
});
|
|
237
237
|
|
|
238
|
-
// // Validation - we handle this in d/f way for now
|
|
239
|
-
// this.validatorPrimary = this.config.validation.mode === "zod"
|
|
240
|
-
// ? new ZodAdapter()
|
|
241
|
-
// : new ExpressValidatorAdapter();
|
|
242
|
-
// this.validatorFallback = this.config.validation.fallback === "express-validator"
|
|
243
|
-
// ? new ExpressValidatorAdapter()
|
|
244
|
-
// : null;
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
// Sanitization
|
|
248
238
|
this.sanitizerPrimary = new SanitizeHtmlAdapter(this.config.sanitizer);
|
|
249
239
|
this.sanitizerFallback = new XSSAdapter(this.config.sanitizer);
|
|
250
240
|
|
|
251
|
-
logger.info("
|
|
241
|
+
logger.info("Sanitizer adapters configured", {
|
|
242
|
+
layer: "hisecure-core",
|
|
243
|
+
primary: "sanitize-html",
|
|
244
|
+
fallback: "xss"
|
|
245
|
+
});
|
|
252
246
|
}
|
|
253
247
|
|
|
254
|
-
private setupManagers()
|
|
248
|
+
private setupManagers() {
|
|
255
249
|
this.hashManager = new HashManager(
|
|
256
250
|
this.config.hashing,
|
|
257
251
|
this.hashingPrimary,
|
|
@@ -265,9 +259,6 @@ export class HiSecure {
|
|
|
265
259
|
);
|
|
266
260
|
|
|
267
261
|
this.validatorManager = new ValidatorManager(
|
|
268
|
-
// this.config.validation,
|
|
269
|
-
// this.validatorPrimary,
|
|
270
|
-
// this.validatorFallback
|
|
271
262
|
new ZodAdapter(),
|
|
272
263
|
new ExpressValidatorAdapter()
|
|
273
264
|
);
|
|
@@ -276,84 +267,59 @@ export class HiSecure {
|
|
|
276
267
|
this.sanitizerPrimary,
|
|
277
268
|
this.sanitizerFallback
|
|
278
269
|
);
|
|
270
|
+
|
|
271
|
+
logger.info("Core managers initialized", {
|
|
272
|
+
layer: "hisecure-core",
|
|
273
|
+
managers: ["hash", "rate-limit", "validator", "sanitizer"]
|
|
274
|
+
});
|
|
279
275
|
}
|
|
280
276
|
|
|
281
|
-
private setupDynamicManagers()
|
|
277
|
+
private setupDynamicManagers() {
|
|
282
278
|
this.jsonManager = new JsonManager();
|
|
283
279
|
this.corsManager = new CorsManager();
|
|
284
280
|
|
|
285
|
-
// Auth manager (only if enabled)
|
|
286
281
|
if (this.config.auth.enabled) {
|
|
287
|
-
const jwtSecret = process.env.JWT_SECRET || this.config.auth.jwtSecret;
|
|
288
|
-
if (!jwtSecret) {
|
|
289
|
-
throw new Error("JWT_SECRET environment variable or jwtSecret in config is required when auth.enabled=true");
|
|
290
|
-
}
|
|
291
|
-
|
|
292
282
|
this.authManager = new AuthManager({
|
|
293
|
-
jwtSecret
|
|
283
|
+
jwtSecret: process.env.JWT_SECRET || this.config.auth.jwtSecret!,
|
|
294
284
|
jwtExpiresIn: this.config.auth.jwtExpiresIn,
|
|
295
|
-
googleClientId:
|
|
285
|
+
googleClientId:
|
|
286
|
+
process.env.GOOGLE_CLIENT_ID || this.config.auth.googleClientId
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
logger.info("Authentication enabled", {
|
|
290
|
+
layer: "hisecure-core",
|
|
291
|
+
google: !!this.config.auth.googleClientId
|
|
292
|
+
});
|
|
293
|
+
} else {
|
|
294
|
+
logger.info("Authentication disabled", {
|
|
295
|
+
layer: "hisecure-core"
|
|
296
296
|
});
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
private createMiddlewareChain(options: SecureOptions): any[] {
|
|
301
301
|
const chain: any[] = [];
|
|
302
|
-
|
|
303
|
-
// JSON parsing
|
|
302
|
+
|
|
304
303
|
chain.push(this.jsonManager.middleware(this.config.json));
|
|
305
304
|
chain.push(this.jsonManager.urlencoded(this.config.urlencoded));
|
|
306
|
-
|
|
307
|
-
// Security headers
|
|
305
|
+
|
|
308
306
|
if (this.config.enableHelmet) chain.push(helmet());
|
|
309
307
|
if (this.config.enableHPP) chain.push(hpp());
|
|
310
|
-
|
|
311
|
-
// Compression (check if compression config exists)
|
|
312
|
-
if (this.config.enableCompression && this.config.compression) {
|
|
313
|
-
chain.push(compression(this.config.compression));
|
|
314
|
-
} else if (this.config.enableCompression) {
|
|
315
|
-
chain.push(compression()); // Use defaults
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// CORS
|
|
319
|
-
if (this.config.enableCORS || options.cors) {
|
|
320
|
-
const corsOptions = options.cors === true ? this.config.cors :
|
|
321
|
-
(typeof options.cors === 'object' ? options.cors : this.config.cors);
|
|
322
|
-
chain.push(this.corsManager.middleware(corsOptions));
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Sanitization
|
|
326
|
-
if (this.config.enableSanitizer || options.sanitize) {
|
|
327
|
-
const sanitizeOptions = options.sanitize === true ? undefined :
|
|
328
|
-
(typeof options.sanitize === 'object' ? options.sanitize : undefined);
|
|
329
|
-
chain.push(this.sanitizerManager.middleware(sanitizeOptions));
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Rate limiting
|
|
333
|
-
if (this.config.enableRateLimiter || options.rateLimit) {
|
|
334
|
-
const rateLimitOpts = typeof options.rateLimit === 'object' ?
|
|
335
|
-
{ options: options.rateLimit } : {};
|
|
336
|
-
chain.push(this.rateLimitManager.middleware(rateLimitOpts));
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Authentication
|
|
340
|
-
if (options.auth && this.authManager) {
|
|
341
|
-
const authOpts = options.auth === true ? undefined :
|
|
342
|
-
(typeof options.auth === 'object' ? options.auth : undefined);
|
|
343
|
-
chain.push(this.authManager.protect(authOpts));
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Error handler - at last usage
|
|
347
|
-
chain.push(errorHandler);
|
|
348
|
-
|
|
349
|
-
return chain;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
308
|
|
|
309
|
+
if (this.config.enableCompression)
|
|
310
|
+
chain.push(compression(this.config.compression));
|
|
356
311
|
|
|
312
|
+
if (options.cors) chain.push(this.corsManager.middleware(this.config.cors));
|
|
313
|
+
if (options.sanitize)
|
|
314
|
+
chain.push(this.sanitizerManager.middleware());
|
|
357
315
|
|
|
316
|
+
if (options.rateLimit)
|
|
317
|
+
chain.push(this.rateLimitManager.middleware({}));
|
|
358
318
|
|
|
319
|
+
if (options.auth && this.authManager)
|
|
320
|
+
chain.push(this.authManager.protect());
|
|
359
321
|
|
|
322
|
+
chain.push(errorHandler);
|
|
323
|
+
return chain;
|
|
324
|
+
}
|
|
325
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { HiSecure } from "./core/HiSecure.js";
|
|
2
2
|
import { useSecure, secureRoute } from "./core/useSecure.js";
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
export { z } from "zod";
|
|
6
|
+
export { body, query, param, header } from "express-validator";
|
|
7
|
+
|
|
4
8
|
const hiSecure = HiSecure.getInstance();
|
|
5
9
|
|
|
6
10
|
export {
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import morgan from "morgan";
|
|
2
|
+
import { logger } from "./winstonSetup";
|
|
2
3
|
|
|
3
|
-
export const requestLogger = morgan(
|
|
4
|
+
export const requestLogger = morgan(
|
|
5
|
+
":method :url :status :response-time ms",
|
|
6
|
+
{
|
|
7
|
+
stream: {
|
|
8
|
+
write: (message) => {
|
|
9
|
+
logger.http(message.trim());
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
);
|
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
import winston from "winston";
|
|
2
2
|
|
|
3
|
+
const { combine, timestamp, printf, colorize, errors } = winston.format;
|
|
4
|
+
|
|
5
|
+
//colors added
|
|
6
|
+
winston.addColors({
|
|
7
|
+
error: "red",
|
|
8
|
+
warn: "yellow",
|
|
9
|
+
info: "green",
|
|
10
|
+
http: "cyan"
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const logFormat = printf(({ level, message, timestamp, ...meta }) => {
|
|
14
|
+
const metaString =
|
|
15
|
+
Object.keys(meta).length > 0 ? ` | ${JSON.stringify(meta)}` : "";
|
|
16
|
+
|
|
17
|
+
return `${timestamp} ${level}: ${message}${metaString}`;
|
|
18
|
+
});
|
|
19
|
+
|
|
3
20
|
export const logger = winston.createLogger({
|
|
4
|
-
level: "
|
|
5
|
-
format:
|
|
6
|
-
|
|
7
|
-
|
|
21
|
+
level: "http",
|
|
22
|
+
format: combine(
|
|
23
|
+
errors({ stack: true }),
|
|
24
|
+
timestamp({ format: "HH:mm:ss" })
|
|
8
25
|
),
|
|
9
26
|
transports: [
|
|
10
|
-
new winston.transports.Console(
|
|
27
|
+
new winston.transports.Console({
|
|
28
|
+
format: combine(
|
|
29
|
+
colorize({ all: true }),
|
|
30
|
+
logFormat
|
|
31
|
+
)
|
|
32
|
+
})
|
|
11
33
|
]
|
|
12
34
|
});
|
|
13
35
|
|
|
14
36
|
// Shortcut helpers
|
|
15
|
-
export const logInfo = (msg: string, meta: any = {}) =>
|
|
16
|
-
|
|
17
|
-
|
|
37
|
+
export const logInfo = (msg: string, meta: any = {}) =>
|
|
38
|
+
logger.info(msg, meta);
|
|
39
|
+
|
|
40
|
+
export const logWarn = (msg: string, meta: any = {}) =>
|
|
41
|
+
logger.warn(msg, meta);
|
|
42
|
+
|
|
43
|
+
export const logError = (msg: string, meta: any = {}) =>
|
|
44
|
+
logger.error(msg, meta);
|