hi-secure 1.0.6 → 1.0.7

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.
@@ -6,7 +6,7 @@ import { SanitizerManager } from "../managers/SanitizerManager.js";
6
6
  import { JsonManager } from "../managers/JsonManager.js";
7
7
  import { CorsManager } from "../managers/CorsManager.js";
8
8
  import { AuthManager } from "../managers/AuthManager.js";
9
- import { ValidationSchema } from "./types/SecureOptions.js";
9
+ import { SecureOptions, ValidationSchema } from "./types/SecureOptions.js";
10
10
  export declare class HiSecure {
11
11
  private static instance;
12
12
  private config;
@@ -22,23 +22,38 @@ export declare class HiSecure {
22
22
  private hashingFallback;
23
23
  private rateLimiterPrimary;
24
24
  private rateLimiterFallback;
25
+ private validatorPrimary;
26
+ private validatorFallback;
27
+ private sanitizerPrimary;
28
+ private sanitizerFallback;
25
29
  private constructor();
26
30
  static getInstance(config?: Partial<HiSecureConfig>): HiSecure;
27
31
  static resetInstance(): void;
28
32
  init(): void;
33
+ isInitialized(): boolean;
29
34
  static auth(options?: {
30
35
  required?: boolean;
31
36
  roles?: string[];
32
37
  }): (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => void;
33
38
  static validate(schema: ValidationSchema): (req: any, res: any, next: any) => any;
34
39
  static sanitize(options?: any): (req: any, _res: any, next: any) => void;
40
+ static rateLimit(preset: "strict" | "relaxed" | "api" | object): any;
35
41
  static cors(options?: any): (req: import("cors").CorsRequest, res: {
36
42
  statusCode?: number | undefined;
37
43
  setHeader(key: string, value: string): any;
38
44
  end(): any;
39
45
  }, next: (err?: any) => any) => void;
40
- static rateLimit(preset: "strict" | "relaxed" | "api" | object): any;
41
46
  static json(options?: any): import("connect").NextHandleFunction[];
47
+ static hash(password: string): Promise<string>;
48
+ static verify(password: string, hash: string): Promise<boolean>;
49
+ static jwt: {
50
+ sign: (payload: object, options?: any) => string;
51
+ verify: (token: string) => string | import("jsonwebtoken").Jwt | import("jsonwebtoken").JwtPayload;
52
+ google: {
53
+ verifyIdToken: (idToken: string) => Promise<import("../adapters/GoogleAdapter.js").GoogleTokenPayload>;
54
+ };
55
+ };
56
+ static middleware(options?: SecureOptions | "api" | "strict" | "public"): any[];
42
57
  private setupAdapters;
43
58
  private setupManagers;
44
59
  private setupDynamicManagers;
@@ -1 +1 @@
1
- {"version":3,"file":"HiSecure.d.ts","sourceRoot":"","sources":["../../src/core/HiSecure.ts"],"names":[],"mappings":"AAo8BA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAkB3D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AASzD,OAAO,EAAiB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE3E,qBAAa,QAAQ;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAyB;IAChD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,WAAW,CAAS;IAGrB,WAAW,EAAG,WAAW,CAAC;IAC1B,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAGjC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,mBAAmB,CAAM;IAEjC,OAAO;IAOP,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,QAAQ;IAQ9D,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B,IAAI,IAAI,IAAI;IAqBZ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;IAI9D,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB;IAIxC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG;IAI7B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;kBArhCsB,CAAC;;;iBAGjB,CAAC;IAshChC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM;IAc9D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;IAYzB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,qBAAqB;CAmChC"}
1
+ {"version":3,"file":"HiSecure.d.ts","sourceRoot":"","sources":["../../src/core/HiSecure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAkB3D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AASzD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAoB,MAAM,0BAA0B,CAAC;AAE7F,qBAAa,QAAQ;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAyB;IAChD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,WAAW,CAAS;IAGrB,WAAW,EAAG,WAAW,CAAC;IAC1B,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,gBAAgB,EAAG,gBAAgB,CAAC;IACpC,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,EAAG,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAGjC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,mBAAmB,CAAM;IACjC,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,iBAAiB,CAAM;IAG/B,OAAO;IAQP,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,QAAQ;IAQ9D,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B,IAAI,IAAI,IAAI;IA0BZ,aAAa,IAAI,OAAO;IAQxB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;IAQ9D,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB;IAIxC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG;IAI7B,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM;IAe9D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;kBArHxB,CAAC;;;iBAEmD,CAAC;IAuHtD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;WAYZ,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;WAMvC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrE,MAAM,CAAC,GAAG;wBACU,MAAM,YAAY,GAAG;wBAQrB,MAAM;;qCASO,MAAM;;MAQrC;IAMF,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ;IAwBvE,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,qBAAqB;CAmDhC"}
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
- // // // src/core/HiSecure.ts
3
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
4
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
4
  };
@@ -33,12 +32,13 @@ const hpp_1 = __importDefault(require("hpp"));
33
32
  const compression_1 = __importDefault(require("compression"));
34
33
  const errorHandler_js_1 = require("../middlewares/errorHandler.js");
35
34
  class HiSecure {
35
+ // Private constructor for singleton
36
36
  constructor(userConfig = {}) {
37
37
  this.initialized = false;
38
38
  this.config = (0, deepMerge_js_1.deepMerge)(config_js_1.defaultConfig, userConfig);
39
39
  }
40
40
  // =====================================================
41
- // SINGLETON
41
+ // SINGLETON & INITIALIZATION
42
42
  // =====================================================
43
43
  static getInstance(config) {
44
44
  if (!HiSecure.instance) {
@@ -51,23 +51,38 @@ class HiSecure {
51
51
  HiSecure.instance = null;
52
52
  }
53
53
  init() {
54
- if (this.initialized)
54
+ if (this.initialized) {
55
+ index_js_1.logger.warn("⚠ HiSecure already initialized");
55
56
  return;
57
+ }
56
58
  index_js_1.logger.info(`🔐 ${constants_js_1.LIB_NAME} v${constants_js_1.LIB_VERSION} initializing...`);
57
59
  this.setupAdapters();
58
60
  this.setupManagers();
59
61
  this.setupDynamicManagers();
60
- // DO NOT FREEZE MANAGERS
61
- // ✔ Only freeze config
62
+ // Make everything immutable
62
63
  (0, deepFreeze_js_1.deepFreeze)(this.config);
64
+ // deepFreeze(this.hashManager);
65
+ // deepFreeze(this.rateLimitManager);
66
+ // deepFreeze(this.validatorManager);
67
+ // deepFreeze(this.sanitizerManager);
68
+ // deepFreeze(this.jsonManager);
69
+ // deepFreeze(this.corsManager);
70
+ // if (this.authManager) deepFreeze(this.authManager);
63
71
  this.initialized = true;
64
72
  index_js_1.logger.info("✅ HiSecure initialized successfully");
65
73
  }
74
+ isInitialized() {
75
+ return this.initialized;
76
+ }
66
77
  // =====================================================
67
- // FLUENT API (Route-level)
78
+ // FLUENT API METHODS (Route-level security)
68
79
  // =====================================================
69
80
  static auth(options) {
70
- return this.getInstance().authManager.protect(options);
81
+ const instance = this.getInstance();
82
+ if (!instance.authManager) {
83
+ throw new Error("Auth not enabled. Set auth.enabled=true in config.");
84
+ }
85
+ return instance.authManager.protect(options);
71
86
  }
72
87
  static validate(schema) {
73
88
  return this.getInstance().validatorManager.validate(schema);
@@ -75,9 +90,6 @@ class HiSecure {
75
90
  static sanitize(options) {
76
91
  return this.getInstance().sanitizerManager.middleware(options);
77
92
  }
78
- static cors(options) {
79
- return this.getInstance().corsManager.middleware(options);
80
- }
81
93
  static rateLimit(preset) {
82
94
  const instance = this.getInstance();
83
95
  if (typeof preset === "string") {
@@ -90,81 +102,174 @@ class HiSecure {
90
102
  }
91
103
  return instance.rateLimitManager.middleware({ options: preset });
92
104
  }
105
+ static cors(options) {
106
+ return this.getInstance().corsManager.middleware(options);
107
+ }
93
108
  static json(options) {
94
109
  const instance = this.getInstance();
95
- return [
96
- instance.jsonManager.middleware(options),
97
- instance.jsonManager.urlencoded()
98
- ];
110
+ const chain = [];
111
+ chain.push(instance.jsonManager.middleware(options));
112
+ chain.push(instance.jsonManager.urlencoded());
113
+ return chain;
114
+ }
115
+ // =====================================================
116
+ // UTILITY METHODS (Direct usage)
117
+ // =====================================================
118
+ static async hash(password) {
119
+ const instance = this.getInstance();
120
+ const result = await instance.hashManager.hash(password, { allowFallback: true });
121
+ return result.hash;
122
+ }
123
+ static async verify(password, hash) {
124
+ return this.getInstance().hashManager.verify(password, hash);
125
+ }
126
+ // =====================================================
127
+ // GLOBAL MIDDLEWARE (app.use())
128
+ // =====================================================
129
+ static middleware(options) {
130
+ const instance = this.getInstance();
131
+ // Handle preset strings
132
+ if (typeof options === "string") {
133
+ const presets = {
134
+ api: { cors: true, rateLimit: "relaxed", sanitize: true },
135
+ strict: { cors: true, rateLimit: "strict", sanitize: true, auth: true },
136
+ public: { cors: true, rateLimit: true, sanitize: false }
137
+ };
138
+ const presetOptions = presets[options];
139
+ if (presetOptions) {
140
+ return instance.createMiddlewareChain(presetOptions);
141
+ }
142
+ return instance.createMiddlewareChain({});
143
+ }
144
+ return instance.createMiddlewareChain(options || {});
99
145
  }
100
146
  // =====================================================
101
- // INTERNAL SETUP
147
+ // INTERNAL METHODS
102
148
  // =====================================================
103
149
  setupAdapters() {
104
150
  index_js_1.logger.info("🧩 Setting up adapters...");
151
+ // Hashing
105
152
  this.hashingPrimary = this.config.hashing.primary === "argon2"
106
153
  ? new ArgonAdapter_js_1.ArgonAdapter()
107
154
  : new BcryptAdapter_js_1.BcryptAdapter(this.config.hashing.saltRounds);
108
155
  this.hashingFallback = this.config.hashing.fallback === "bcrypt"
109
156
  ? new BcryptAdapter_js_1.BcryptAdapter(this.config.hashing.saltRounds)
110
157
  : null;
158
+ // Rate limiting
111
159
  this.rateLimiterPrimary = this.config.rateLimiter.useAdaptiveMode
112
160
  ? new RLFlexibleAdapter_js_1.RLFlexibleAdapter()
113
161
  : new ExpressRLAdapter_js_1.ExpressRLAdapter();
114
162
  this.rateLimiterFallback = new ExpressRLAdapter_js_1.ExpressRLAdapter();
163
+ // Validation
164
+ this.validatorPrimary = this.config.validation.mode === "zod"
165
+ ? new ZodAdapter_js_1.ZodAdapter()
166
+ : new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter();
167
+ this.validatorFallback = this.config.validation.fallback === "express-validator"
168
+ ? new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter()
169
+ : null;
170
+ // Sanitization
171
+ this.sanitizerPrimary = new SanitizeHtmlAdapter_js_1.SanitizeHtmlAdapter(this.config.sanitizer);
172
+ this.sanitizerFallback = new XSSAdapter_js_1.XSSAdapter(this.config.sanitizer);
115
173
  index_js_1.logger.info("✅ Adapters ready");
116
174
  }
117
175
  setupManagers() {
118
176
  this.hashManager = new HashManager_js_1.HashManager(this.config.hashing, this.hashingPrimary, this.hashingFallback);
119
177
  this.rateLimitManager = new RateLimitManager_js_1.RateLimitManager(this.config.rateLimiter, this.rateLimiterPrimary, this.rateLimiterFallback);
120
- // AUTO-DETECT VALIDATION (ZOD + EXPRESS-VALIDATOR)
121
- this.validatorManager = new ValidatorManager_js_1.ValidatorManager(new ZodAdapter_js_1.ZodAdapter(), new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter());
122
- this.sanitizerManager = new SanitizerManager_js_1.SanitizerManager(new SanitizeHtmlAdapter_js_1.SanitizeHtmlAdapter(this.config.sanitizer), new XSSAdapter_js_1.XSSAdapter(this.config.sanitizer));
178
+ this.validatorManager = new ValidatorManager_js_1.ValidatorManager(
179
+ // this.config.validation,
180
+ // this.validatorPrimary,
181
+ // this.validatorFallback
182
+ new ZodAdapter_js_1.ZodAdapter(), new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter());
183
+ this.sanitizerManager = new SanitizerManager_js_1.SanitizerManager(this.sanitizerPrimary, this.sanitizerFallback);
123
184
  }
124
185
  setupDynamicManagers() {
125
186
  this.jsonManager = new JsonManager_js_1.JsonManager();
126
187
  this.corsManager = new CorsManager_js_1.CorsManager();
188
+ // Auth manager (only if enabled)
127
189
  if (this.config.auth.enabled) {
128
190
  const jwtSecret = process.env.JWT_SECRET || this.config.auth.jwtSecret;
129
- if (!jwtSecret)
130
- throw new Error("JWT_SECRET is required when auth.enabled=true");
191
+ if (!jwtSecret) {
192
+ throw new Error("JWT_SECRET environment variable or jwtSecret in config is required when auth.enabled=true");
193
+ }
131
194
  this.authManager = new AuthManager_js_1.AuthManager({
132
195
  jwtSecret,
133
196
  jwtExpiresIn: this.config.auth.jwtExpiresIn,
134
- googleClientId: this.config.auth.googleClientId
197
+ googleClientId: process.env.GOOGLE_CLIENT_ID || this.config.auth.googleClientId
198
+ // Removed algorithm - handled in AuthManager
135
199
  });
136
200
  }
137
201
  }
138
202
  createMiddlewareChain(options) {
139
203
  const chain = [];
204
+ // JSON parsing
140
205
  chain.push(this.jsonManager.middleware(this.config.json));
141
206
  chain.push(this.jsonManager.urlencoded(this.config.urlencoded));
207
+ // Security headers
142
208
  if (this.config.enableHelmet)
143
209
  chain.push((0, helmet_1.default)());
144
210
  if (this.config.enableHPP)
145
211
  chain.push((0, hpp_1.default)());
146
- if (this.config.enableCompression)
212
+ // Compression (check if compression config exists)
213
+ if (this.config.enableCompression && this.config.compression) {
147
214
  chain.push((0, compression_1.default)(this.config.compression));
215
+ }
216
+ else if (this.config.enableCompression) {
217
+ chain.push((0, compression_1.default)()); // Use defaults
218
+ }
219
+ // CORS
148
220
  if (this.config.enableCORS || options.cors) {
149
- const opts = typeof options.cors === "object" ? options.cors : this.config.cors;
150
- chain.push(this.corsManager.middleware(opts));
221
+ const corsOptions = options.cors === true ? this.config.cors :
222
+ (typeof options.cors === 'object' ? options.cors : this.config.cors);
223
+ chain.push(this.corsManager.middleware(corsOptions));
151
224
  }
225
+ // Sanitization
152
226
  if (this.config.enableSanitizer || options.sanitize) {
153
- const opts = typeof options.sanitize === "object" ? options.sanitize : undefined;
154
- chain.push(this.sanitizerManager.middleware(opts));
227
+ const sanitizeOptions = options.sanitize === true ? undefined :
228
+ (typeof options.sanitize === 'object' ? options.sanitize : undefined);
229
+ chain.push(this.sanitizerManager.middleware(sanitizeOptions));
155
230
  }
231
+ // Rate limiting
156
232
  if (this.config.enableRateLimiter || options.rateLimit) {
157
- const opts = typeof options.rateLimit === "object" ? { options: options.rateLimit } : {};
158
- chain.push(this.rateLimitManager.middleware(opts));
233
+ const rateLimitOpts = typeof options.rateLimit === 'object' ?
234
+ { options: options.rateLimit } : {};
235
+ chain.push(this.rateLimitManager.middleware(rateLimitOpts));
159
236
  }
237
+ // Authentication
160
238
  if (options.auth && this.authManager) {
161
- const opts = typeof options.auth === "object" ? options.auth : undefined;
162
- chain.push(this.authManager.protect(opts));
239
+ const authOpts = options.auth === true ? undefined :
240
+ (typeof options.auth === 'object' ? options.auth : undefined);
241
+ chain.push(this.authManager.protect(authOpts));
163
242
  }
243
+ // Error handler (always last)
164
244
  chain.push(errorHandler_js_1.errorHandler);
165
245
  return chain;
166
246
  }
167
247
  }
168
248
  exports.HiSecure = HiSecure;
169
249
  HiSecure.instance = null;
250
+ HiSecure.jwt = {
251
+ sign: (payload, options) => {
252
+ const instance = HiSecure.getInstance();
253
+ if (!instance.authManager) {
254
+ throw new Error("Auth not enabled");
255
+ }
256
+ return instance.authManager.sign(payload, options);
257
+ },
258
+ verify: (token) => {
259
+ const instance = HiSecure.getInstance();
260
+ if (!instance.authManager) {
261
+ throw new Error("Auth not enabled");
262
+ }
263
+ return instance.authManager.verify(token);
264
+ },
265
+ google: {
266
+ verifyIdToken: (idToken) => {
267
+ const instance = HiSecure.getInstance();
268
+ if (!instance.authManager) {
269
+ throw new Error("Auth not enabled");
270
+ }
271
+ return instance.authManager.verifyGoogleIdToken(idToken);
272
+ }
273
+ }
274
+ };
170
275
  //# sourceMappingURL=HiSecure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HiSecure.js","sourceRoot":"","sources":["../../src/core/HiSecure.ts"],"names":[],"mappings":"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","sourcesContent":["// // // src/core/HiSecure.ts\r\n\r\n// // import { HiSecureConfig } from \"./types/HiSecureConfig.js\";\r\n// // import { defaultConfig } from \"./config.js\";\r\n// // import { LIB_NAME, LIB_VERSION } from \"./constants.js\";\r\n// // import { deepMerge } from \"../utils/deepMerge.js\";\r\n// // import { deepFreeze } from \"../utils/deepFreeze.js\";\r\n\r\n// // import { logger } from \"../logging\";\r\n\r\n// // // Adapters\r\n// // import { ArgonAdapter } from \"../adapters/ArgonAdapter.js\";\r\n// // import { BcryptAdapter } from \"../adapters/BcryptAdapter.js\";\r\n// // import { RLFlexibleAdapter } from \"../adapters/RLFlexibleAdapter.js\";\r\n// // import { ExpressRLAdapter } from \"../adapters/ExpressRLAdapter.js\";\r\n// // import { ZodAdapter } from \"../adapters/ZodAdapter.js\";\r\n// // import { ExpressValidatorAdapter } from \"../adapters/ExpressValidatorAdapter.js\";\r\n// // import { SanitizeHtmlAdapter } from \"../adapters/SanitizeHtmlAdapter.js\";\r\n// // import { DomPurifyAdapter } from \"../adapters/DomPurifyAdapter.js\";\r\n\r\n// // // Managers\r\n// // import { HashManager } from \"../managers/HashManager.js\";\r\n// // import { RateLimitManager } from \"../managers/RateLimitManager.js\";\r\n// // import { ValidatorManager } from \"../managers/ValidatorManager.js\";\r\n// // import { SanitizerManager } from \"../managers/SanitizerManager.js\";\r\n// // import { JsonManager } from \"../managers/JsonManager.js\";\r\n// // import { CorsManager } from \"../managers/CorsManager.js\";\r\n// // import { AuthManager } from \"../managers/AuthManager.js\";\r\n\r\n// // // 3rd-party express middlewares\r\n// // import helmet from \"helmet\";\r\n// // import hpp from \"hpp\";\r\n\r\n// // // Shared error handler\r\n// // import { errorHandler } from \"../middlewares/errorHandler.js\";\r\n\r\n// // export class HiSecure {\r\n// // private config: HiSecureConfig;\r\n// // private initialized = false;\r\n\r\n// // // Managers exposed for user\r\n// // public hashManager!: HashManager;\r\n// // public rateLimitManager!: RateLimitManager;\r\n// // public validatorManager!: ValidatorManager;\r\n// // public sanitizerManager!: SanitizerManager;\r\n// // public jsonManager!: JsonManager;\r\n// // public corsManager!: CorsManager;\r\n// // public authManager?: AuthManager;\r\n\r\n// // // Internal adapters\r\n// // private hashingPrimary: any;\r\n// // private hashingFallback: any;\r\n// // private rateLimiterPrimary: any;\r\n// // private rateLimiterFallback: any;\r\n// // private validatorPrimary: any;\r\n// // private validatorFallback: any;\r\n// // private sanitizerPrimary: any;\r\n// // private sanitizerFallback: any;\r\n\r\n// // constructor(userConfig: Partial<HiSecureConfig> = {}) {\r\n// // this.config = deepMerge(defaultConfig, userConfig);\r\n// // }\r\n\r\n// // // ---------------------------------------------------------\r\n// // // INIT\r\n// // // ---------------------------------------------------------\r\n// // init() {\r\n// // if (this.initialized) {\r\n// // logger.warn(\"⚠ HiSecure.init() called twice → ignored.\");\r\n// // return;\r\n// // }\r\n\r\n// // logger.info(`🔐 ${LIB_NAME} v${LIB_VERSION} initialized`);\r\n// // logger.info(\"⚙ Loaded configuration:\", this.config);\r\n\r\n// // this.setupAdapters();\r\n// // this.setupManagers();\r\n// // this.setupDynamicManagers();\r\n\r\n// // // IMMUTABLE — library cannot be modified at runtime\r\n// // deepFreeze(this.config);\r\n// // deepFreeze(this.hashManager);\r\n// // deepFreeze(this.rateLimitManager);\r\n// // deepFreeze(this.validatorManager);\r\n// // deepFreeze(this.sanitizerManager);\r\n// // deepFreeze(this.jsonManager);\r\n// // deepFreeze(this.corsManager);\r\n// // if (this.authManager) deepFreeze(this.authManager);\r\n\r\n// // this.initialized = true;\r\n\r\n// // logger.info(\"🔒 HiSecure locked — production-ready\");\r\n// // }\r\n\r\n// // isInitialized() {\r\n// // return this.initialized;\r\n// // }\r\n\r\n// // // ---------------------------------------------------------\r\n// // // ADAPTER SETUP\r\n// // // ---------------------------------------------------------\r\n// // private setupAdapters() {\r\n// // logger.info(\"🧩 Setting up adapters...\");\r\n\r\n// // // Hashing\r\n// // this.hashingPrimary =\r\n// // this.config.hashing.primary === \"argon2\"\r\n// // ? new ArgonAdapter()\r\n// // : new BcryptAdapter(this.config.hashing.saltRounds);\r\n\r\n// // this.hashingFallback =\r\n// // this.config.hashing.fallback === \"bcrypt\"\r\n// // ? new BcryptAdapter(this.config.hashing.saltRounds)\r\n// // : null;\r\n\r\n// // // Rate limiter\r\n// // this.rateLimiterPrimary =\r\n// // this.config.rateLimiter.useAdaptiveMode\r\n// // ? new RLFlexibleAdapter()\r\n// // : new ExpressRLAdapter();\r\n\r\n// // this.rateLimiterFallback = new ExpressRLAdapter();\r\n\r\n// // // Validator\r\n// // this.validatorPrimary =\r\n// // this.config.validation.mode === \"zod\"\r\n// // ? new ZodAdapter()\r\n// // : new ExpressValidatorAdapter();\r\n\r\n// // this.validatorFallback =\r\n// // this.config.validation.fallback === \"express-validator\"\r\n// // ? new ExpressValidatorAdapter()\r\n// // : null;\r\n\r\n// // // Sanitizer\r\n// // this.sanitizerPrimary = new SanitizeHtmlAdapter(this.config.sanitizer);\r\n// // this.sanitizerFallback = new DomPurifyAdapter();\r\n\r\n// // logger.info(\"✔ Adapters ready\");\r\n// // }\r\n\r\n// // // ---------------------------------------------------------\r\n// // // MANAGER SETUP\r\n// // // ---------------------------------------------------------\r\n// // private setupManagers() {\r\n// // this.hashManager = new HashManager(\r\n// // this.config.hashing,\r\n// // this.hashingPrimary,\r\n// // this.hashingFallback\r\n// // );\r\n\r\n// // this.rateLimitManager = new RateLimitManager(\r\n// // this.config.rateLimiter,\r\n// // this.rateLimiterPrimary,\r\n// // this.rateLimiterFallback\r\n// // );\r\n\r\n// // this.validatorManager = new ValidatorManager(\r\n// // this.config.validation,\r\n// // this.validatorPrimary,\r\n// // this.validatorFallback\r\n// // );\r\n\r\n// // this.sanitizerManager = new SanitizerManager(\r\n// // this.sanitizerPrimary,\r\n// // this.sanitizerFallback\r\n// // );\r\n// // }\r\n\r\n// // // ---------------------------------------------------------\r\n// // // DYNAMIC MANAGERS (JSON, CORS, AUTH)\r\n// // // ---------------------------------------------------------\r\n// // private setupDynamicManagers() {\r\n// // this.jsonManager = new JsonManager();\r\n// // this.corsManager = new CorsManager();\r\n\r\n// // // AUTH SUPPORT\r\n// // if (this.config.auth?.enabled) {\r\n// // this.authManager = new AuthManager({\r\n// // jwtSecret: process.env.JWT_SECRET!,\r\n// // jwtExpiresIn: this.config.auth.jwtExpiresIn,\r\n// // googleClientId: process.env.GOOGLE_CLIENT_ID\r\n// // });\r\n// // }\r\n// // }\r\n\r\n// // // ---------------------------------------------------------\r\n// // // PUBLIC API METHODS\r\n// // // ---------------------------------------------------------\r\n// // hash(value: string) {\r\n// // return this.hashManager.hash(value);\r\n// // }\r\n\r\n// // verify(value: string, hashed: string) {\r\n// // return this.hashManager.verify(value, hashed);\r\n// // }\r\n\r\n// // sanitize(value: string) {\r\n// // return this.sanitizerManager.sanitize(value);\r\n// // }\r\n\r\n// // validate(schema: any) {\r\n// // return this.validatorManager.validate(schema);\r\n// // }\r\n\r\n// // // ---------------------------------------------------------\r\n// // // EXPRESS GLOBAL PIPELINE\r\n// // // ---------------------------------------------------------\r\n// // middleware() {\r\n// // const chain: any[] = [];\r\n\r\n// // // JSON + URL encoded\r\n// // chain.push(this.jsonManager.middleware(this.config.json));\r\n// // chain.push(this.jsonManager.urlencoded(this.config.urlencoded));\r\n\r\n// // // add qs\r\n// // chain.push(this.jsonManager.queryParser());\r\n\r\n// // // Core security\r\n// // if (this.config.enableHelmet) chain.push(helmet());\r\n// // if (this.config.enableHPP) chain.push(hpp());\r\n\r\n// // if (this.config.enableCORS)\r\n// // chain.push(this.corsManager.middleware(this.config.cors));\r\n\r\n// // if (this.config.enableSanitizer)\r\n// // chain.push(this.sanitizerManager.middleware());\r\n\r\n// // if (this.config.enableRateLimiter)\r\n// // chain.push(this.rateLimitManager.middleware());\r\n\r\n// // // Centralized error handling\r\n// // chain.push(errorHandler);\r\n\r\n// // return chain;\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n// // src/core/HiSecure.ts - COMPLETE FIXED\r\n// import { HiSecureConfig } from \"./types/HiSecureConfig.js\";\r\n// import { defaultConfig } from \"./config.js\";\r\n// import { LIB_NAME, LIB_VERSION } from \"./constants.js\";\r\n// import { deepMerge } from \"../utils/deepMerge.js\";\r\n// import { deepFreeze } from \"../utils/deepFreeze.js\";\r\n// import { logger } from \"../logging/index.js\";\r\n\r\n// // Adapters\r\n// import { ArgonAdapter } from \"../adapters/ArgonAdapter.js\";\r\n// import { BcryptAdapter } from \"../adapters/BcryptAdapter.js\";\r\n// import { RLFlexibleAdapter } from \"../adapters/RLFlexibleAdapter.js\";\r\n// import { ExpressRLAdapter } from \"../adapters/ExpressRLAdapter.js\";\r\n// import { ZodAdapter } from \"../adapters/ZodAdapter.js\";\r\n// import { ExpressValidatorAdapter } from \"../adapters/ExpressValidatorAdapter.js\";\r\n// import { SanitizeHtmlAdapter } from \"../adapters/SanitizeHtmlAdapter.js\";\r\n// import { XSSAdapter } from \"../adapters/XSSAdapter.js\"; // ✅ FIXED IMPORT\r\n\r\n// // Managers\r\n// import { HashManager } from \"../managers/HashManager.js\";\r\n// import { RateLimitManager } from \"../managers/RateLimitManager.js\";\r\n// import { ValidatorManager } from \"../managers/ValidatorManager.js\";\r\n// import { SanitizerManager } from \"../managers/SanitizerManager.js\";\r\n// import { JsonManager } from \"../managers/JsonManager.js\";\r\n// import { CorsManager } from \"../managers/CorsManager.js\";\r\n// import { AuthManager } from \"../managers/AuthManager.js\";\r\n\r\n// // Middlewares\r\n// import helmet from \"helmet\";\r\n// import hpp from \"hpp\";\r\n// import compression from \"compression\";\r\n// import { errorHandler } from \"../middlewares/errorHandler.js\";\r\n\r\n// // Types\r\n// import { SecureOptions, ValidationSchema } from \"./types/SecureOptions.js\";\r\n\r\n// export class HiSecure {\r\n// private static instance: HiSecure | null = null;\r\n// private config: HiSecureConfig;\r\n// private initialized = false;\r\n\r\n// // Managers\r\n// public hashManager!: HashManager;\r\n// public rateLimitManager!: RateLimitManager;\r\n// public validatorManager!: ValidatorManager;\r\n// public sanitizerManager!: SanitizerManager;\r\n// public jsonManager!: JsonManager;\r\n// public corsManager!: CorsManager;\r\n// public authManager?: AuthManager;\r\n\r\n// // Internal adapters\r\n// private hashingPrimary: any;\r\n// private hashingFallback: any;\r\n// private rateLimiterPrimary: any;\r\n// private rateLimiterFallback: any;\r\n// private validatorPrimary: any;\r\n// private validatorFallback: any;\r\n// private sanitizerPrimary: any;\r\n// private sanitizerFallback: any;\r\n\r\n// // Private constructor for singleton\r\n// private constructor(userConfig: Partial<HiSecureConfig> = {}) {\r\n// this.config = deepMerge(defaultConfig, userConfig);\r\n// }\r\n\r\n// // =====================================================\r\n// // SINGLETON & INITIALIZATION\r\n// // =====================================================\r\n \r\n// static getInstance(config?: Partial<HiSecureConfig>): HiSecure {\r\n// if (!HiSecure.instance) {\r\n// HiSecure.instance = new HiSecure(config);\r\n// HiSecure.instance.init();\r\n// }\r\n// return HiSecure.instance;\r\n// }\r\n\r\n// static resetInstance(): void {\r\n// HiSecure.instance = null;\r\n// }\r\n\r\n// init(): void {\r\n// if (this.initialized) {\r\n// logger.warn(\"⚠ HiSecure already initialized\");\r\n// return;\r\n// }\r\n\r\n// logger.info(`🔐 ${LIB_NAME} v${LIB_VERSION} initializing...`);\r\n\r\n// this.setupAdapters();\r\n// this.setupManagers();\r\n// this.setupDynamicManagers();\r\n\r\n// // Make everything immutable\r\n// deepFreeze(this.config);\r\n// deepFreeze(this.hashManager);\r\n// deepFreeze(this.rateLimitManager);\r\n// deepFreeze(this.validatorManager);\r\n// deepFreeze(this.sanitizerManager);\r\n// deepFreeze(this.jsonManager);\r\n// deepFreeze(this.corsManager);\r\n// if (this.authManager) deepFreeze(this.authManager);\r\n\r\n// this.initialized = true;\r\n// logger.info(\"✅ HiSecure initialized successfully\");\r\n// }\r\n\r\n// isInitialized(): boolean {\r\n// return this.initialized;\r\n// }\r\n\r\n// // =====================================================\r\n// // FLUENT API METHODS (Route-level security)\r\n// // =====================================================\r\n \r\n// static auth(options?: { required?: boolean; roles?: string[] }) {\r\n// const instance = this.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled. Set auth.enabled=true in config.\");\r\n// }\r\n// return instance.authManager.protect(options);\r\n// }\r\n\r\n// static validate(schema: ValidationSchema) {\r\n// return this.getInstance().validatorManager.validate(schema);\r\n// }\r\n\r\n// static sanitize(options?: any) {\r\n// return this.getInstance().sanitizerManager.middleware(options);\r\n// }\r\n\r\n// static rateLimit(preset: \"strict\" | \"relaxed\" | \"api\" | object) {\r\n// const instance = this.getInstance();\r\n \r\n// if (typeof preset === \"string\") {\r\n// const presets = {\r\n// strict: { mode: \"strict\" as const },\r\n// relaxed: { mode: \"relaxed\" as const },\r\n// api: { max: 100, windowMs: 60000 }\r\n// };\r\n// return instance.rateLimitManager.middleware(presets[preset] || {});\r\n// }\r\n \r\n// return instance.rateLimitManager.middleware({ options: preset });\r\n// }\r\n\r\n// static cors(options?: any) {\r\n// return this.getInstance().corsManager.middleware(options);\r\n// }\r\n\r\n// static json(options?: any) {\r\n// const instance = this.getInstance();\r\n// const chain = [];\r\n// chain.push(instance.jsonManager.middleware(options));\r\n// chain.push(instance.jsonManager.urlencoded());\r\n// return chain;\r\n// }\r\n\r\n// // =====================================================\r\n// // UTILITY METHODS (Direct usage)\r\n// // =====================================================\r\n \r\n// static async hash(password: string): Promise<string> {\r\n// const instance = this.getInstance();\r\n// const result = await instance.hashManager.hash(password, { allowFallback: true });\r\n// return result.hash;\r\n// }\r\n\r\n// static async verify(password: string, hash: string): Promise<boolean> {\r\n// return this.getInstance().hashManager.verify(password, hash);\r\n// }\r\n\r\n// static jwt = {\r\n// sign: (payload: object, options?: any) => {\r\n// const instance = HiSecure.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled\");\r\n// }\r\n// return instance.authManager.sign(payload, options);\r\n// },\r\n \r\n// verify: (token: string) => {\r\n// const instance = HiSecure.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled\");\r\n// }\r\n// return instance.authManager.verify(token);\r\n// },\r\n \r\n// google: {\r\n// verifyIdToken: (idToken: string) => {\r\n// const instance = HiSecure.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled\");\r\n// }\r\n// return instance.authManager.verifyGoogleIdToken(idToken);\r\n// }\r\n// }\r\n// };\r\n\r\n// // =====================================================\r\n// // GLOBAL MIDDLEWARE (app.use())\r\n// // =====================================================\r\n \r\n// static middleware(options?: SecureOptions | \"api\" | \"strict\" | \"public\") {\r\n// const instance = this.getInstance();\r\n \r\n// // Handle preset strings\r\n// if (typeof options === \"string\") {\r\n// const presets = {\r\n// api: { cors: true, rateLimit: \"relaxed\", sanitize: true },\r\n// strict: { cors: true, rateLimit: \"strict\", sanitize: true, auth: true },\r\n// public: { cors: true, rateLimit: true }\r\n// };\r\n// options = presets[options] || {};\r\n// }\r\n \r\n// return instance.createMiddlewareChain(options || {});\r\n// }\r\n\r\n// // =====================================================\r\n// // INTERNAL METHODS\r\n// // =====================================================\r\n \r\n// private setupAdapters(): void {\r\n// logger.info(\"🧩 Setting up adapters...\");\r\n\r\n// // Hashing\r\n// this.hashingPrimary = this.config.hashing.primary === \"argon2\"\r\n// ? new ArgonAdapter()\r\n// : new BcryptAdapter(this.config.hashing.saltRounds);\r\n\r\n// this.hashingFallback = this.config.hashing.fallback === \"bcrypt\"\r\n// ? new BcryptAdapter(this.config.hashing.saltRounds)\r\n// : null;\r\n\r\n// // Rate limiting\r\n// this.rateLimiterPrimary = this.config.rateLimiter.useAdaptiveMode\r\n// ? new RLFlexibleAdapter()\r\n// : new ExpressRLAdapter();\r\n// this.rateLimiterFallback = new ExpressRLAdapter();\r\n\r\n// // Validation\r\n// this.validatorPrimary = this.config.validation.mode === \"zod\"\r\n// ? new ZodAdapter()\r\n// : new ExpressValidatorAdapter();\r\n// this.validatorFallback = this.config.validation.fallback === \"express-validator\"\r\n// ? new ExpressValidatorAdapter()\r\n// : null;\r\n\r\n// // Sanitization\r\n// this.sanitizerPrimary = new SanitizeHtmlAdapter(this.config.sanitizer);\r\n// this.sanitizerFallback = new XSSAdapter(this.config.sanitizer); // ✅ XSSAdapter, NOT DomPurifyAdapter\r\n\r\n// logger.info(\"✅ Adapters ready\");\r\n// }\r\n\r\n// private setupManagers(): void {\r\n// this.hashManager = new HashManager(\r\n// this.config.hashing,\r\n// this.hashingPrimary,\r\n// this.hashingFallback\r\n// );\r\n\r\n// this.rateLimitManager = new RateLimitManager(\r\n// this.config.rateLimiter,\r\n// this.rateLimiterPrimary,\r\n// this.rateLimiterFallback\r\n// );\r\n\r\n// this.validatorManager = new ValidatorManager(\r\n// this.config.validation,\r\n// this.validatorPrimary,\r\n// this.validatorFallback\r\n// );\r\n\r\n// this.sanitizerManager = new SanitizerManager(\r\n// this.sanitizerPrimary,\r\n// this.sanitizerFallback\r\n// );\r\n// }\r\n\r\n// private setupDynamicManagers(): void {\r\n// this.jsonManager = new JsonManager();\r\n// this.corsManager = new CorsManager();\r\n\r\n// // Auth manager (only if enabled)\r\n// if (this.config.auth.enabled) {\r\n// const jwtSecret = process.env.JWT_SECRET || this.config.auth.jwtSecret;\r\n// if (!jwtSecret) {\r\n// throw new Error(\"JWT_SECRET environment variable or jwtSecret in config is required when auth.enabled=true\");\r\n// }\r\n\r\n// this.authManager = new AuthManager({\r\n// jwtSecret,\r\n// jwtExpiresIn: this.config.auth.jwtExpiresIn,\r\n// googleClientId: process.env.GOOGLE_CLIENT_ID || this.config.auth.googleClientId,\r\n// // ✅ Add algorithm option for JWT security\r\n// algorithm: 'HS256'\r\n// });\r\n// }\r\n// }\r\n\r\n// private createMiddlewareChain(options: SecureOptions): any[] {\r\n// const chain: any[] = [];\r\n \r\n// // JSON parsing\r\n// chain.push(this.jsonManager.middleware(this.config.json));\r\n// chain.push(this.jsonManager.urlencoded(this.config.urlencoded));\r\n \r\n// // Security headers\r\n// if (this.config.enableHelmet) chain.push(helmet());\r\n// if (this.config.enableHPP) chain.push(hpp());\r\n \r\n// // Compression (check if compression config exists)\r\n// if (this.config.enableCompression && this.config.compression) {\r\n// chain.push(compression(this.config.compression));\r\n// } else if (this.config.enableCompression) {\r\n// chain.push(compression()); // Use defaults\r\n// }\r\n \r\n// // CORS\r\n// if (this.config.enableCORS || options.cors) {\r\n// const corsOptions = options.cors === true ? this.config.cors : \r\n// (typeof options.cors === 'object' ? options.cors : this.config.cors);\r\n// chain.push(this.corsManager.middleware(corsOptions));\r\n// }\r\n \r\n// // Sanitization\r\n// if (this.config.enableSanitizer || options.sanitize) {\r\n// const sanitizeOptions = options.sanitize === true ? undefined : \r\n// (typeof options.sanitize === 'object' ? options.sanitize : undefined);\r\n// chain.push(this.sanitizerManager.middleware(sanitizeOptions));\r\n// }\r\n \r\n// // Rate limiting\r\n// if (this.config.enableRateLimiter || options.rateLimit) {\r\n// const rateLimitOpts = typeof options.rateLimit === 'object' ? \r\n// { options: options.rateLimit } : {};\r\n// chain.push(this.rateLimitManager.middleware(rateLimitOpts));\r\n// }\r\n \r\n// // Authentication\r\n// if (options.auth && this.authManager) {\r\n// const authOpts = options.auth === true ? undefined : \r\n// (typeof options.auth === 'object' ? options.auth : undefined);\r\n// chain.push(this.authManager.protect(authOpts));\r\n// }\r\n \r\n// // Error handler (always last)\r\n// chain.push(errorHandler);\r\n \r\n// return chain;\r\n// }\r\n// }\r\n\r\n\r\n// =================\r\n\r\n// // src/core/HiSecure.ts - COMPLETELY FIXED\r\n// import { HiSecureConfig } from \"./types/HiSecureConfig.js\";\r\n// import { defaultConfig } from \"./config.js\";\r\n// import { LIB_NAME, LIB_VERSION } from \"./constants.js\";\r\n// import { deepMerge } from \"../utils/deepMerge.js\";\r\n// import { deepFreeze } from \"../utils/deepFreeze.js\";\r\n// import { logger } from \"../logging/index.js\";\r\n\r\n// // Adapters\r\n// import { ArgonAdapter } from \"../adapters/ArgonAdapter.js\";\r\n// import { BcryptAdapter } from \"../adapters/BcryptAdapter.js\";\r\n// import { RLFlexibleAdapter } from \"../adapters/RLFlexibleAdapter.js\";\r\n// import { ExpressRLAdapter } from \"../adapters/ExpressRLAdapter.js\";\r\n// import { ZodAdapter } from \"../adapters/ZodAdapter.js\";\r\n// import { ExpressValidatorAdapter } from \"../adapters/ExpressValidatorAdapter.js\";\r\n// import { SanitizeHtmlAdapter } from \"../adapters/SanitizeHtmlAdapter.js\";\r\n// import { XSSAdapter } from \"../adapters/XSSAdapter.js\";\r\n\r\n// // Managers\r\n// import { HashManager } from \"../managers/HashManager.js\";\r\n// import { RateLimitManager } from \"../managers/RateLimitManager.js\";\r\n// import { ValidatorManager } from \"../managers/ValidatorManager.js\";\r\n// import { SanitizerManager } from \"../managers/SanitizerManager.js\";\r\n// import { JsonManager } from \"../managers/JsonManager.js\";\r\n// import { CorsManager } from \"../managers/CorsManager.js\";\r\n// import { AuthManager } from \"../managers/AuthManager.js\";\r\n\r\n// // Middlewares\r\n// import helmet from \"helmet\";\r\n// import hpp from \"hpp\";\r\n// import compression from \"compression\";\r\n// import { errorHandler } from \"../middlewares/errorHandler.js\";\r\n\r\n// // Types\r\n// import { SecureOptions, ValidationSchema, RateLimitOptions } from \"./types/SecureOptions.js\";\r\n\r\n// export class HiSecure {\r\n// private static instance: HiSecure | null = null;\r\n// private config: HiSecureConfig;\r\n// private initialized = false;\r\n\r\n// // Managers\r\n// public hashManager!: HashManager;\r\n// public rateLimitManager!: RateLimitManager;\r\n// public validatorManager!: ValidatorManager;\r\n// public sanitizerManager!: SanitizerManager;\r\n// public jsonManager!: JsonManager;\r\n// public corsManager!: CorsManager;\r\n// public authManager?: AuthManager;\r\n\r\n// // Internal adapters\r\n// private hashingPrimary: any;\r\n// private hashingFallback: any;\r\n// private rateLimiterPrimary: any;\r\n// private rateLimiterFallback: any;\r\n// private validatorPrimary: any;\r\n// private validatorFallback: any;\r\n// private sanitizerPrimary: any;\r\n// private sanitizerFallback: any;\r\n\r\n// // Private constructor for singleton\r\n// private constructor(userConfig: Partial<HiSecureConfig> = {}) {\r\n// this.config = deepMerge(defaultConfig, userConfig);\r\n// }\r\n\r\n// // =====================================================\r\n// // SINGLETON & INITIALIZATION\r\n// // =====================================================\r\n \r\n// static getInstance(config?: Partial<HiSecureConfig>): HiSecure {\r\n// if (!HiSecure.instance) {\r\n// HiSecure.instance = new HiSecure(config);\r\n// HiSecure.instance.init();\r\n// }\r\n// return HiSecure.instance;\r\n// }\r\n\r\n// static resetInstance(): void {\r\n// HiSecure.instance = null;\r\n// }\r\n\r\n// init(): void {\r\n// if (this.initialized) {\r\n// logger.warn(\"⚠ HiSecure already initialized\");\r\n// return;\r\n// }\r\n\r\n// logger.info(`🔐 ${LIB_NAME} v${LIB_VERSION} initializing...`);\r\n\r\n// this.setupAdapters();\r\n// this.setupManagers();\r\n// this.setupDynamicManagers();\r\n\r\n// // Make everything immutable\r\n// deepFreeze(this.config);\r\n// deepFreeze(this.hashManager);\r\n// deepFreeze(this.rateLimitManager);\r\n// deepFreeze(this.validatorManager);\r\n// deepFreeze(this.sanitizerManager);\r\n// deepFreeze(this.jsonManager);\r\n// deepFreeze(this.corsManager);\r\n// if (this.authManager) deepFreeze(this.authManager);\r\n\r\n// this.initialized = true;\r\n// logger.info(\"✅ HiSecure initialized successfully\");\r\n// }\r\n\r\n// isInitialized(): boolean {\r\n// return this.initialized;\r\n// }\r\n\r\n// // =====================================================\r\n// // FLUENT API METHODS (Route-level security)\r\n// // =====================================================\r\n \r\n// static auth(options?: { required?: boolean; roles?: string[] }) {\r\n// const instance = this.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled. Set auth.enabled=true in config.\");\r\n// }\r\n// return instance.authManager.protect(options);\r\n// }\r\n\r\n// static validate(schema: ValidationSchema) {\r\n// return this.getInstance().validatorManager.validate(schema);\r\n// }\r\n\r\n// static sanitize(options?: any) {\r\n// return this.getInstance().sanitizerManager.middleware(options);\r\n// }\r\n\r\n// static rateLimit(preset: \"strict\" | \"relaxed\" | \"api\" | object) {\r\n// const instance = this.getInstance();\r\n \r\n// if (typeof preset === \"string\") {\r\n// const presets: Record<string, { mode?: \"strict\" | \"relaxed\" | \"api\"; options?: any }> = {\r\n// strict: { mode: \"strict\" },\r\n// relaxed: { mode: \"relaxed\" },\r\n// api: { mode: \"api\", options: { max: 100, windowMs: 60000 } }\r\n// };\r\n// return instance.rateLimitManager.middleware(presets[preset] || {});\r\n// }\r\n \r\n// return instance.rateLimitManager.middleware({ options: preset });\r\n// }\r\n\r\n// static cors(options?: any) {\r\n// return this.getInstance().corsManager.middleware(options);\r\n// }\r\n\r\n// static json(options?: any) {\r\n// const instance = this.getInstance();\r\n// const chain = [];\r\n// chain.push(instance.jsonManager.middleware(options));\r\n// chain.push(instance.jsonManager.urlencoded());\r\n// return chain;\r\n// }\r\n\r\n// // =====================================================\r\n// // UTILITY METHODS (Direct usage)\r\n// // =====================================================\r\n \r\n// static async hash(password: string): Promise<string> {\r\n// const instance = this.getInstance();\r\n// const result = await instance.hashManager.hash(password, { allowFallback: true });\r\n// return result.hash;\r\n// }\r\n\r\n// static async verify(password: string, hash: string): Promise<boolean> {\r\n// return this.getInstance().hashManager.verify(password, hash);\r\n// }\r\n\r\n// static jwt = {\r\n// sign: (payload: object, options?: any) => {\r\n// const instance = HiSecure.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled\");\r\n// }\r\n// return instance.authManager.sign(payload, options);\r\n// },\r\n \r\n// verify: (token: string) => {\r\n// const instance = HiSecure.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled\");\r\n// }\r\n// return instance.authManager.verify(token);\r\n// },\r\n \r\n// google: {\r\n// verifyIdToken: (idToken: string) => {\r\n// const instance = HiSecure.getInstance();\r\n// if (!instance.authManager) {\r\n// throw new Error(\"Auth not enabled\");\r\n// }\r\n// return instance.authManager.verifyGoogleIdToken(idToken);\r\n// }\r\n// }\r\n// };\r\n\r\n// // =====================================================\r\n// // GLOBAL MIDDLEWARE (app.use())\r\n// // =====================================================\r\n \r\n// static middleware(options?: SecureOptions | \"api\" | \"strict\" | \"public\") {\r\n// const instance = this.getInstance();\r\n \r\n// // Handle preset strings\r\n// if (typeof options === \"string\") {\r\n// const presets: Record<string, SecureOptions> = {\r\n// api: { cors: true, rateLimit: \"relaxed\" as any, sanitize: true },\r\n// strict: { cors: true, rateLimit: \"strict\" as any, sanitize: true, auth: true },\r\n// public: { cors: true, rateLimit: true as any, sanitize: false }\r\n// };\r\n// const presetOptions = presets[options];\r\n// if (presetOptions) {\r\n// return instance.createMiddlewareChain(presetOptions);\r\n// }\r\n// return instance.createMiddlewareChain({});\r\n// }\r\n \r\n// return instance.createMiddlewareChain(options || {});\r\n// }\r\n\r\n// // =====================================================\r\n// // INTERNAL METHODS\r\n// // =====================================================\r\n \r\n// private setupAdapters(): void {\r\n// logger.info(\"🧩 Setting up adapters...\");\r\n\r\n// // Hashing\r\n// this.hashingPrimary = this.config.hashing.primary === \"argon2\"\r\n// ? new ArgonAdapter()\r\n// : new BcryptAdapter(this.config.hashing.saltRounds);\r\n\r\n// this.hashingFallback = this.config.hashing.fallback === \"bcrypt\"\r\n// ? new BcryptAdapter(this.config.hashing.saltRounds)\r\n// : null;\r\n\r\n// // Rate limiting\r\n// this.rateLimiterPrimary = this.config.rateLimiter.useAdaptiveMode\r\n// ? new RLFlexibleAdapter()\r\n// : new ExpressRLAdapter();\r\n// this.rateLimiterFallback = new ExpressRLAdapter();\r\n\r\n// // Validation\r\n// this.validatorPrimary = this.config.validation.mode === \"zod\"\r\n// ? new ZodAdapter()\r\n// : new ExpressValidatorAdapter();\r\n// this.validatorFallback = this.config.validation.fallback === \"express-validator\"\r\n// ? new ExpressValidatorAdapter()\r\n// : null;\r\n\r\n// // Sanitization\r\n// this.sanitizerPrimary = new SanitizeHtmlAdapter(this.config.sanitizer);\r\n// this.sanitizerFallback = new XSSAdapter(this.config.sanitizer);\r\n\r\n// logger.info(\"✅ Adapters ready\");\r\n// }\r\n\r\n// private setupManagers(): void {\r\n// this.hashManager = new HashManager(\r\n// this.config.hashing,\r\n// this.hashingPrimary,\r\n// this.hashingFallback\r\n// );\r\n\r\n// this.rateLimitManager = new RateLimitManager(\r\n// this.config.rateLimiter,\r\n// this.rateLimiterPrimary,\r\n// this.rateLimiterFallback\r\n// );\r\n\r\n// this.validatorManager = new ValidatorManager(\r\n// // this.config.validation,\r\n// // this.validatorPrimary,\r\n// // this.validatorFallback\r\n// new ZodAdapter(),\r\n// new ExpressValidatorAdapter()\r\n// );\r\n\r\n// this.sanitizerManager = new SanitizerManager(\r\n// this.sanitizerPrimary,\r\n// this.sanitizerFallback\r\n// );\r\n// }\r\n\r\n// private setupDynamicManagers(): void {\r\n// this.jsonManager = new JsonManager();\r\n// this.corsManager = new CorsManager();\r\n\r\n// // Auth manager (only if enabled)\r\n// if (this.config.auth.enabled) {\r\n// const jwtSecret = process.env.JWT_SECRET || this.config.auth.jwtSecret;\r\n// if (!jwtSecret) {\r\n// throw new Error(\"JWT_SECRET environment variable or jwtSecret in config is required when auth.enabled=true\");\r\n// }\r\n\r\n// this.authManager = new AuthManager({\r\n// jwtSecret,\r\n// jwtExpiresIn: this.config.auth.jwtExpiresIn,\r\n// googleClientId: process.env.GOOGLE_CLIENT_ID || this.config.auth.googleClientId\r\n// // Removed algorithm - handled in AuthManager\r\n// });\r\n// }\r\n// }\r\n\r\n// private createMiddlewareChain(options: SecureOptions): any[] {\r\n// const chain: any[] = [];\r\n \r\n// // JSON parsing\r\n// chain.push(this.jsonManager.middleware(this.config.json));\r\n// chain.push(this.jsonManager.urlencoded(this.config.urlencoded));\r\n \r\n// // Security headers\r\n// if (this.config.enableHelmet) chain.push(helmet());\r\n// if (this.config.enableHPP) chain.push(hpp());\r\n \r\n// // Compression (check if compression config exists)\r\n// if (this.config.enableCompression && this.config.compression) {\r\n// chain.push(compression(this.config.compression));\r\n// } else if (this.config.enableCompression) {\r\n// chain.push(compression()); // Use defaults\r\n// }\r\n \r\n// // CORS\r\n// if (this.config.enableCORS || options.cors) {\r\n// const corsOptions = options.cors === true ? this.config.cors : \r\n// (typeof options.cors === 'object' ? options.cors : this.config.cors);\r\n// chain.push(this.corsManager.middleware(corsOptions));\r\n// }\r\n \r\n// // Sanitization\r\n// if (this.config.enableSanitizer || options.sanitize) {\r\n// const sanitizeOptions = options.sanitize === true ? undefined : \r\n// (typeof options.sanitize === 'object' ? options.sanitize : undefined);\r\n// chain.push(this.sanitizerManager.middleware(sanitizeOptions));\r\n// }\r\n \r\n// // Rate limiting\r\n// if (this.config.enableRateLimiter || options.rateLimit) {\r\n// const rateLimitOpts = typeof options.rateLimit === 'object' ? \r\n// { options: options.rateLimit } : {};\r\n// chain.push(this.rateLimitManager.middleware(rateLimitOpts));\r\n// }\r\n \r\n// // Authentication\r\n// if (options.auth && this.authManager) {\r\n// const authOpts = options.auth === true ? undefined : \r\n// (typeof options.auth === 'object' ? options.auth : undefined);\r\n// chain.push(this.authManager.protect(authOpts));\r\n// }\r\n \r\n// // Error handler (always last)\r\n// chain.push(errorHandler);\r\n \r\n// return chain;\r\n// }\r\n// }\r\n\r\n\r\n// ===================\r\n\r\n// src/core/HiSecure.ts - FINAL VERSION\r\nimport { HiSecureConfig } from \"./types/HiSecureConfig.js\";\r\nimport { defaultConfig } from \"./config.js\";\r\nimport { LIB_NAME, LIB_VERSION } from \"./constants.js\";\r\nimport { deepMerge } from \"../utils/deepMerge.js\";\r\nimport { deepFreeze } from \"../utils/deepFreeze.js\";\r\nimport { logger } from \"../logging/index.js\";\r\n\r\n// Adapters\r\nimport { ArgonAdapter } from \"../adapters/ArgonAdapter.js\";\r\nimport { BcryptAdapter } from \"../adapters/BcryptAdapter.js\";\r\nimport { RLFlexibleAdapter } from \"../adapters/RLFlexibleAdapter.js\";\r\nimport { ExpressRLAdapter } from \"../adapters/ExpressRLAdapter.js\";\r\nimport { ZodAdapter } from \"../adapters/ZodAdapter.js\";\r\nimport { ExpressValidatorAdapter } from \"../adapters/ExpressValidatorAdapter.js\";\r\nimport { SanitizeHtmlAdapter } from \"../adapters/SanitizeHtmlAdapter.js\";\r\nimport { XSSAdapter } from \"../adapters/XSSAdapter.js\";\r\n\r\n// Managers\r\nimport { HashManager } from \"../managers/HashManager.js\";\r\nimport { RateLimitManager } from \"../managers/RateLimitManager.js\";\r\nimport { ValidatorManager } from \"../managers/ValidatorManager.js\";\r\nimport { SanitizerManager } from \"../managers/SanitizerManager.js\";\r\nimport { JsonManager } from \"../managers/JsonManager.js\";\r\nimport { CorsManager } from \"../managers/CorsManager.js\";\r\nimport { AuthManager } from \"../managers/AuthManager.js\";\r\n\r\n// Middlewares\r\nimport helmet from \"helmet\";\r\nimport hpp from \"hpp\";\r\nimport compression from \"compression\";\r\nimport { errorHandler } from \"../middlewares/errorHandler.js\";\r\n\r\n// Types\r\nimport { SecureOptions, ValidationSchema } from \"./types/SecureOptions.js\";\r\n\r\nexport class HiSecure {\r\n private static instance: HiSecure | null = null;\r\n private config: HiSecureConfig;\r\n private initialized = false;\r\n\r\n // Managers\r\n public hashManager!: HashManager;\r\n public rateLimitManager!: RateLimitManager;\r\n public validatorManager!: ValidatorManager;\r\n public sanitizerManager!: SanitizerManager;\r\n public jsonManager!: JsonManager;\r\n public corsManager!: CorsManager;\r\n public authManager?: AuthManager;\r\n\r\n // Internal adapters\r\n private hashingPrimary: any;\r\n private hashingFallback: any;\r\n private rateLimiterPrimary: any;\r\n private rateLimiterFallback: any;\r\n\r\n private constructor(userConfig: Partial<HiSecureConfig> = {}) {\r\n this.config = deepMerge(defaultConfig, userConfig);\r\n }\r\n\r\n // =====================================================\r\n // SINGLETON\r\n // =====================================================\r\n static getInstance(config?: Partial<HiSecureConfig>): HiSecure {\r\n if (!HiSecure.instance) {\r\n HiSecure.instance = new HiSecure(config);\r\n HiSecure.instance.init();\r\n }\r\n return HiSecure.instance;\r\n }\r\n\r\n static resetInstance(): void {\r\n HiSecure.instance = null;\r\n }\r\n\r\n init(): void {\r\n if (this.initialized) return;\r\n\r\n logger.info(`🔐 ${LIB_NAME} v${LIB_VERSION} initializing...`);\r\n\r\n this.setupAdapters();\r\n this.setupManagers();\r\n this.setupDynamicManagers();\r\n\r\n // ❌ DO NOT FREEZE MANAGERS\r\n // ✔ Only freeze config\r\n deepFreeze(this.config);\r\n\r\n this.initialized = true;\r\n logger.info(\"✅ HiSecure initialized successfully\");\r\n }\r\n\r\n // =====================================================\r\n // FLUENT API (Route-level)\r\n // =====================================================\r\n\r\n static auth(options?: { required?: boolean; roles?: string[] }) {\r\n return this.getInstance().authManager!.protect(options);\r\n }\r\n\r\n static validate(schema: ValidationSchema) {\r\n return this.getInstance().validatorManager.validate(schema);\r\n }\r\n\r\n static sanitize(options?: any) {\r\n return this.getInstance().sanitizerManager.middleware(options);\r\n }\r\n\r\n static cors(options?: any) {\r\n return this.getInstance().corsManager.middleware(options);\r\n }\r\n\r\n static rateLimit(preset: \"strict\" | \"relaxed\" | \"api\" | object) {\r\n const instance = this.getInstance();\r\n\r\n if (typeof preset === \"string\") {\r\n const presets: any = {\r\n strict: { mode: \"strict\" },\r\n relaxed: { mode: \"relaxed\" },\r\n api: { mode: \"api\", options: { max: 100, windowMs: 60000 } }\r\n };\r\n return instance.rateLimitManager.middleware(presets[preset] || {});\r\n }\r\n return instance.rateLimitManager.middleware({ options: preset });\r\n }\r\n\r\n static json(options?: any) {\r\n const instance = this.getInstance();\r\n return [\r\n instance.jsonManager.middleware(options),\r\n instance.jsonManager.urlencoded()\r\n ];\r\n }\r\n\r\n // =====================================================\r\n // INTERNAL SETUP\r\n // =====================================================\r\n\r\n private setupAdapters(): void {\r\n logger.info(\"🧩 Setting up adapters...\");\r\n\r\n this.hashingPrimary = this.config.hashing.primary === \"argon2\"\r\n ? new ArgonAdapter()\r\n : new BcryptAdapter(this.config.hashing.saltRounds);\r\n\r\n this.hashingFallback = this.config.hashing.fallback === \"bcrypt\"\r\n ? new BcryptAdapter(this.config.hashing.saltRounds)\r\n : null;\r\n\r\n this.rateLimiterPrimary = this.config.rateLimiter.useAdaptiveMode\r\n ? new RLFlexibleAdapter()\r\n : new ExpressRLAdapter();\r\n\r\n this.rateLimiterFallback = new ExpressRLAdapter();\r\n\r\n logger.info(\"✅ Adapters ready\");\r\n }\r\n\r\n private setupManagers(): void {\r\n this.hashManager = new HashManager(this.config.hashing, this.hashingPrimary, this.hashingFallback);\r\n\r\n this.rateLimitManager = new RateLimitManager(\r\n this.config.rateLimiter,\r\n this.rateLimiterPrimary,\r\n this.rateLimiterFallback\r\n );\r\n\r\n // ✔ AUTO-DETECT VALIDATION (ZOD + EXPRESS-VALIDATOR)\r\n this.validatorManager = new ValidatorManager(\r\n new ZodAdapter(),\r\n new ExpressValidatorAdapter()\r\n );\r\n\r\n this.sanitizerManager = new SanitizerManager(\r\n new SanitizeHtmlAdapter(this.config.sanitizer),\r\n new XSSAdapter(this.config.sanitizer)\r\n );\r\n }\r\n\r\n private setupDynamicManagers(): void {\r\n this.jsonManager = new JsonManager();\r\n this.corsManager = new CorsManager();\r\n\r\n if (this.config.auth.enabled) {\r\n const jwtSecret = process.env.JWT_SECRET || this.config.auth.jwtSecret;\r\n if (!jwtSecret) throw new Error(\"JWT_SECRET is required when auth.enabled=true\");\r\n\r\n this.authManager = new AuthManager({\r\n jwtSecret,\r\n jwtExpiresIn: this.config.auth.jwtExpiresIn,\r\n googleClientId: this.config.auth.googleClientId\r\n });\r\n }\r\n }\r\n\r\n private createMiddlewareChain(options: SecureOptions): any[] {\r\n const chain: any[] = [];\r\n\r\n chain.push(this.jsonManager.middleware(this.config.json));\r\n chain.push(this.jsonManager.urlencoded(this.config.urlencoded));\r\n\r\n if (this.config.enableHelmet) chain.push(helmet());\r\n if (this.config.enableHPP) chain.push(hpp());\r\n\r\n if (this.config.enableCompression) chain.push(compression(this.config.compression));\r\n\r\n if (this.config.enableCORS || options.cors) {\r\n const opts = typeof options.cors === \"object\" ? options.cors : this.config.cors;\r\n chain.push(this.corsManager.middleware(opts));\r\n }\r\n\r\n if (this.config.enableSanitizer || options.sanitize) {\r\n const opts = typeof options.sanitize === \"object\" ? options.sanitize : undefined;\r\n chain.push(this.sanitizerManager.middleware(opts));\r\n }\r\n\r\n if (this.config.enableRateLimiter || options.rateLimit) {\r\n const opts = typeof options.rateLimit === \"object\" ? { options: options.rateLimit } : {};\r\n chain.push(this.rateLimitManager.middleware(opts));\r\n }\r\n\r\n if (options.auth && this.authManager) {\r\n const opts = typeof options.auth === \"object\" ? options.auth : undefined;\r\n chain.push(this.authManager.protect(opts));\r\n }\r\n\r\n chain.push(errorHandler);\r\n\r\n return chain;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"HiSecure.js","sourceRoot":"","sources":["../../src/core/HiSecure.ts"],"names":[],"mappings":"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","sourcesContent":["// src/core/HiSecure.ts - COMPLETELY FIXED\r\nimport { HiSecureConfig } from \"./types/HiSecureConfig.js\";\r\nimport { defaultConfig } from \"./config.js\";\r\nimport { LIB_NAME, LIB_VERSION } from \"./constants.js\";\r\nimport { deepMerge } from \"../utils/deepMerge.js\";\r\nimport { deepFreeze } from \"../utils/deepFreeze.js\";\r\nimport { logger } from \"../logging/index.js\";\r\n\r\n// Adapters\r\nimport { ArgonAdapter } from \"../adapters/ArgonAdapter.js\";\r\nimport { BcryptAdapter } from \"../adapters/BcryptAdapter.js\";\r\nimport { RLFlexibleAdapter } from \"../adapters/RLFlexibleAdapter.js\";\r\nimport { ExpressRLAdapter } from \"../adapters/ExpressRLAdapter.js\";\r\nimport { ZodAdapter } from \"../adapters/ZodAdapter.js\";\r\nimport { ExpressValidatorAdapter } from \"../adapters/ExpressValidatorAdapter.js\";\r\nimport { SanitizeHtmlAdapter } from \"../adapters/SanitizeHtmlAdapter.js\";\r\nimport { XSSAdapter } from \"../adapters/XSSAdapter.js\";\r\n\r\n// Managers\r\nimport { HashManager } from \"../managers/HashManager.js\";\r\nimport { RateLimitManager } from \"../managers/RateLimitManager.js\";\r\nimport { ValidatorManager } from \"../managers/ValidatorManager.js\";\r\nimport { SanitizerManager } from \"../managers/SanitizerManager.js\";\r\nimport { JsonManager } from \"../managers/JsonManager.js\";\r\nimport { CorsManager } from \"../managers/CorsManager.js\";\r\nimport { AuthManager } from \"../managers/AuthManager.js\";\r\n\r\n// Middlewares\r\nimport helmet from \"helmet\";\r\nimport hpp from \"hpp\";\r\nimport compression from \"compression\";\r\nimport { errorHandler } from \"../middlewares/errorHandler.js\";\r\n\r\n// Types\r\nimport { SecureOptions, ValidationSchema, RateLimitOptions } from \"./types/SecureOptions.js\";\r\n\r\nexport class HiSecure {\r\n private static instance: HiSecure | null = null;\r\n private config: HiSecureConfig;\r\n private initialized = false;\r\n\r\n // Managers\r\n public hashManager!: HashManager;\r\n public rateLimitManager!: RateLimitManager;\r\n public validatorManager!: ValidatorManager;\r\n public sanitizerManager!: SanitizerManager;\r\n public jsonManager!: JsonManager;\r\n public corsManager!: CorsManager;\r\n public authManager?: AuthManager;\r\n\r\n // Internal adapters\r\n private hashingPrimary: any;\r\n private hashingFallback: any;\r\n private rateLimiterPrimary: any;\r\n private rateLimiterFallback: any;\r\n private validatorPrimary: any;\r\n private validatorFallback: any;\r\n private sanitizerPrimary: any;\r\n private sanitizerFallback: any;\r\n\r\n // Private constructor for singleton\r\n private constructor(userConfig: Partial<HiSecureConfig> = {}) {\r\n this.config = deepMerge(defaultConfig, userConfig);\r\n }\r\n\r\n // =====================================================\r\n // SINGLETON & INITIALIZATION\r\n // =====================================================\r\n \r\n static getInstance(config?: Partial<HiSecureConfig>): HiSecure {\r\n if (!HiSecure.instance) {\r\n HiSecure.instance = new HiSecure(config);\r\n HiSecure.instance.init();\r\n }\r\n return HiSecure.instance;\r\n }\r\n\r\n static resetInstance(): void {\r\n HiSecure.instance = null;\r\n }\r\n\r\n init(): void {\r\n if (this.initialized) {\r\n logger.warn(\"⚠ HiSecure already initialized\");\r\n return;\r\n }\r\n\r\n logger.info(`🔐 ${LIB_NAME} v${LIB_VERSION} initializing...`);\r\n\r\n this.setupAdapters();\r\n this.setupManagers();\r\n this.setupDynamicManagers();\r\n\r\n // Make everything immutable\r\n deepFreeze(this.config);\r\n // deepFreeze(this.hashManager);\r\n // deepFreeze(this.rateLimitManager);\r\n // deepFreeze(this.validatorManager);\r\n // deepFreeze(this.sanitizerManager);\r\n // deepFreeze(this.jsonManager);\r\n // deepFreeze(this.corsManager);\r\n // if (this.authManager) deepFreeze(this.authManager);\r\n\r\n this.initialized = true;\r\n logger.info(\"✅ HiSecure initialized successfully\");\r\n }\r\n\r\n isInitialized(): boolean {\r\n return this.initialized;\r\n }\r\n\r\n // =====================================================\r\n // FLUENT API METHODS (Route-level security)\r\n // =====================================================\r\n \r\n static auth(options?: { required?: boolean; roles?: string[] }) {\r\n const instance = this.getInstance();\r\n if (!instance.authManager) {\r\n throw new Error(\"Auth not enabled. Set auth.enabled=true in config.\");\r\n }\r\n return instance.authManager.protect(options);\r\n }\r\n\r\n static validate(schema: ValidationSchema) {\r\n return this.getInstance().validatorManager.validate(schema);\r\n }\r\n\r\n static sanitize(options?: any) {\r\n return this.getInstance().sanitizerManager.middleware(options);\r\n }\r\n\r\n static rateLimit(preset: \"strict\" | \"relaxed\" | \"api\" | object) {\r\n const instance = this.getInstance();\r\n \r\n if (typeof preset === \"string\") {\r\n const presets: Record<string, { mode?: \"strict\" | \"relaxed\" | \"api\"; options?: any }> = {\r\n strict: { mode: \"strict\" },\r\n relaxed: { mode: \"relaxed\" },\r\n api: { mode: \"api\", options: { max: 100, windowMs: 60000 } }\r\n };\r\n return instance.rateLimitManager.middleware(presets[preset] || {});\r\n }\r\n \r\n return instance.rateLimitManager.middleware({ options: preset });\r\n }\r\n\r\n static cors(options?: any) {\r\n return this.getInstance().corsManager.middleware(options);\r\n }\r\n\r\n static json(options?: any) {\r\n const instance = this.getInstance();\r\n const chain = [];\r\n chain.push(instance.jsonManager.middleware(options));\r\n chain.push(instance.jsonManager.urlencoded());\r\n return chain;\r\n }\r\n\r\n // =====================================================\r\n // UTILITY METHODS (Direct usage)\r\n // =====================================================\r\n \r\n static async hash(password: string): Promise<string> {\r\n const instance = this.getInstance();\r\n const result = await instance.hashManager.hash(password, { allowFallback: true });\r\n return result.hash;\r\n }\r\n\r\n static async verify(password: string, hash: string): Promise<boolean> {\r\n return this.getInstance().hashManager.verify(password, hash);\r\n }\r\n\r\n static jwt = {\r\n sign: (payload: object, options?: any) => {\r\n const instance = HiSecure.getInstance();\r\n if (!instance.authManager) {\r\n throw new Error(\"Auth not enabled\");\r\n }\r\n return instance.authManager.sign(payload, options);\r\n },\r\n \r\n verify: (token: string) => {\r\n const instance = HiSecure.getInstance();\r\n if (!instance.authManager) {\r\n throw new Error(\"Auth not enabled\");\r\n }\r\n return instance.authManager.verify(token);\r\n },\r\n \r\n google: {\r\n verifyIdToken: (idToken: string) => {\r\n const instance = HiSecure.getInstance();\r\n if (!instance.authManager) {\r\n throw new Error(\"Auth not enabled\");\r\n }\r\n return instance.authManager.verifyGoogleIdToken(idToken);\r\n }\r\n }\r\n };\r\n\r\n // =====================================================\r\n // GLOBAL MIDDLEWARE (app.use())\r\n // =====================================================\r\n \r\n static middleware(options?: SecureOptions | \"api\" | \"strict\" | \"public\") {\r\n const instance = this.getInstance();\r\n \r\n // Handle preset strings\r\n if (typeof options === \"string\") {\r\n const presets: Record<string, SecureOptions> = {\r\n api: { cors: true, rateLimit: \"relaxed\" as any, sanitize: true },\r\n strict: { cors: true, rateLimit: \"strict\" as any, sanitize: true, auth: true },\r\n public: { cors: true, rateLimit: true as any, sanitize: false }\r\n };\r\n const presetOptions = presets[options];\r\n if (presetOptions) {\r\n return instance.createMiddlewareChain(presetOptions);\r\n }\r\n return instance.createMiddlewareChain({});\r\n }\r\n \r\n return instance.createMiddlewareChain(options || {});\r\n }\r\n\r\n // =====================================================\r\n // INTERNAL METHODS\r\n // =====================================================\r\n \r\n private setupAdapters(): void {\r\n logger.info(\"🧩 Setting up adapters...\");\r\n\r\n // Hashing\r\n this.hashingPrimary = this.config.hashing.primary === \"argon2\"\r\n ? new ArgonAdapter()\r\n : new BcryptAdapter(this.config.hashing.saltRounds);\r\n\r\n this.hashingFallback = this.config.hashing.fallback === \"bcrypt\"\r\n ? new BcryptAdapter(this.config.hashing.saltRounds)\r\n : null;\r\n\r\n // Rate limiting\r\n this.rateLimiterPrimary = this.config.rateLimiter.useAdaptiveMode\r\n ? new RLFlexibleAdapter()\r\n : new ExpressRLAdapter();\r\n this.rateLimiterFallback = new ExpressRLAdapter();\r\n\r\n // Validation\r\n this.validatorPrimary = this.config.validation.mode === \"zod\"\r\n ? new ZodAdapter()\r\n : new ExpressValidatorAdapter();\r\n this.validatorFallback = this.config.validation.fallback === \"express-validator\"\r\n ? new ExpressValidatorAdapter()\r\n : null;\r\n\r\n // Sanitization\r\n this.sanitizerPrimary = new SanitizeHtmlAdapter(this.config.sanitizer);\r\n this.sanitizerFallback = new XSSAdapter(this.config.sanitizer);\r\n\r\n logger.info(\"✅ Adapters ready\");\r\n }\r\n\r\n private setupManagers(): void {\r\n this.hashManager = new HashManager(\r\n this.config.hashing,\r\n this.hashingPrimary,\r\n this.hashingFallback\r\n );\r\n\r\n this.rateLimitManager = new RateLimitManager(\r\n this.config.rateLimiter,\r\n this.rateLimiterPrimary,\r\n this.rateLimiterFallback\r\n );\r\n\r\n this.validatorManager = new ValidatorManager(\r\n // this.config.validation,\r\n // this.validatorPrimary,\r\n // this.validatorFallback\r\n new ZodAdapter(),\r\n new ExpressValidatorAdapter()\r\n );\r\n\r\n this.sanitizerManager = new SanitizerManager(\r\n this.sanitizerPrimary,\r\n this.sanitizerFallback\r\n );\r\n }\r\n\r\n private setupDynamicManagers(): void {\r\n this.jsonManager = new JsonManager();\r\n this.corsManager = new CorsManager();\r\n\r\n // Auth manager (only if enabled)\r\n if (this.config.auth.enabled) {\r\n const jwtSecret = process.env.JWT_SECRET || this.config.auth.jwtSecret;\r\n if (!jwtSecret) {\r\n throw new Error(\"JWT_SECRET environment variable or jwtSecret in config is required when auth.enabled=true\");\r\n }\r\n\r\n this.authManager = new AuthManager({\r\n jwtSecret,\r\n jwtExpiresIn: this.config.auth.jwtExpiresIn,\r\n googleClientId: process.env.GOOGLE_CLIENT_ID || this.config.auth.googleClientId\r\n // Removed algorithm - handled in AuthManager\r\n });\r\n }\r\n }\r\n\r\n private createMiddlewareChain(options: SecureOptions): any[] {\r\n const chain: any[] = [];\r\n \r\n // JSON parsing\r\n chain.push(this.jsonManager.middleware(this.config.json));\r\n chain.push(this.jsonManager.urlencoded(this.config.urlencoded));\r\n \r\n // Security headers\r\n if (this.config.enableHelmet) chain.push(helmet());\r\n if (this.config.enableHPP) chain.push(hpp());\r\n \r\n // Compression (check if compression config exists)\r\n if (this.config.enableCompression && this.config.compression) {\r\n chain.push(compression(this.config.compression));\r\n } else if (this.config.enableCompression) {\r\n chain.push(compression()); // Use defaults\r\n }\r\n \r\n // CORS\r\n if (this.config.enableCORS || options.cors) {\r\n const corsOptions = options.cors === true ? this.config.cors : \r\n (typeof options.cors === 'object' ? options.cors : this.config.cors);\r\n chain.push(this.corsManager.middleware(corsOptions));\r\n }\r\n \r\n // Sanitization\r\n if (this.config.enableSanitizer || options.sanitize) {\r\n const sanitizeOptions = options.sanitize === true ? undefined : \r\n (typeof options.sanitize === 'object' ? options.sanitize : undefined);\r\n chain.push(this.sanitizerManager.middleware(sanitizeOptions));\r\n }\r\n \r\n // Rate limiting\r\n if (this.config.enableRateLimiter || options.rateLimit) {\r\n const rateLimitOpts = typeof options.rateLimit === 'object' ? \r\n { options: options.rateLimit } : {};\r\n chain.push(this.rateLimitManager.middleware(rateLimitOpts));\r\n }\r\n \r\n // Authentication\r\n if (options.auth && this.authManager) {\r\n const authOpts = options.auth === true ? undefined : \r\n (typeof options.auth === 'object' ? options.auth : undefined);\r\n chain.push(this.authManager.protect(authOpts));\r\n }\r\n \r\n // Error handler (always last)\r\n chain.push(errorHandler);\r\n \r\n return chain;\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"]}
@@ -1,3 +1,10 @@
1
1
  import { SecureOptions } from "./types/SecureOptions.js";
2
+ /**
3
+ * @deprecated Use HiSecure.middleware() or fluent API instead
4
+ */
5
+ export declare function useSecure(options?: SecureOptions | "api" | "strict" | "public"): any[];
6
+ /**
7
+ * Legacy support - route-level security
8
+ */
2
9
  export declare function secureRoute(options?: SecureOptions): any[];
3
10
  //# sourceMappingURL=useSecure.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSecure.d.ts","sourceRoot":"","sources":["../../src/core/useSecure.ts"],"names":[],"mappings":"AAqHA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,aAAa,SA8ClD"}
1
+ {"version":3,"file":"useSecure.d.ts","sourceRoot":"","sources":["../../src/core/useSecure.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,SAG9E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,aAAa,SAiClD"}