hi-secure 1.0.2 → 1.0.4
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/ExpressRLAdapter.d.ts.map +1 -1
- package/dist/adapters/ExpressRLAdapter.js +0 -29
- package/dist/adapters/ExpressRLAdapter.js.map +1 -1
- package/dist/adapters/GoogleAdapter.d.ts.map +1 -1
- package/dist/adapters/GoogleAdapter.js +4 -3
- package/dist/adapters/GoogleAdapter.js.map +1 -1
- package/dist/adapters/JWTAdapter.d.ts.map +1 -1
- package/dist/adapters/JWTAdapter.js +3 -1
- package/dist/adapters/JWTAdapter.js.map +1 -1
- package/dist/core/HiSecure.d.ts +3 -18
- package/dist/core/HiSecure.d.ts.map +1 -1
- package/dist/core/HiSecure.js +29 -132
- package/dist/core/HiSecure.js.map +1 -1
- package/dist/core/errors/HttpError.d.ts +17 -0
- package/dist/core/errors/HttpError.d.ts.map +1 -0
- package/dist/core/errors/HttpError.js +36 -0
- package/dist/core/errors/HttpError.js.map +1 -0
- package/dist/core/useSecure.d.ts +0 -7
- package/dist/core/useSecure.d.ts.map +1 -1
- package/dist/core/useSecure.js +65 -21
- package/dist/core/useSecure.js.map +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -9
- package/dist/index.js.map +1 -1
- package/dist/managers/AuthManager.d.ts.map +1 -1
- package/dist/managers/AuthManager.js +18 -17
- package/dist/managers/AuthManager.js.map +1 -1
- package/dist/managers/ValidatorManager.d.ts +4 -6
- package/dist/managers/ValidatorManager.d.ts.map +1 -1
- package/dist/managers/ValidatorManager.js +97 -144
- package/dist/managers/ValidatorManager.js.map +1 -1
- package/dist/middlewares/errorHandler.js +2 -2
- package/dist/middlewares/errorHandler.js.map +1 -1
- package/dist/utils/normalizeOptions.d.ts.map +1 -1
- package/dist/utils/normalizeOptions.js +14 -4
- package/dist/utils/normalizeOptions.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +38 -73
- package/src/adapters/GoogleAdapter.ts +5 -3
- package/src/adapters/JWTAdapter.ts +3 -1
- package/src/core/HiSecure.ts +262 -12
- package/src/core/useSecure.ts +91 -36
- package/src/index.ts +28 -12
- package/src/managers/AuthManager.ts +15 -13
- package/src/managers/ValidatorManager.ts +120 -182
- package/src/middlewares/errorHandler.ts +1 -1
- package/src/utils/normalizeOptions.ts +24 -9
- /package/src/core/errors/{HttpErrror.ts → HttpError.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpressRLAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ExpressRLAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExpressRLAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ExpressRLAdapter.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,qBAAa,gBAAgB;IACzB,aAAa,CAAC,OAAO,GAAE,gBAAqB;CA6B/C"}
|
|
@@ -1,38 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// import rateLimit from "express-rate-limit";
|
|
3
|
-
// import { logger } from "../logging";
|
|
4
|
-
// import { AdapterError } from "../core/errors/AdapterError";
|
|
5
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
4
|
};
|
|
8
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
6
|
exports.ExpressRLAdapter = void 0;
|
|
10
|
-
// export class ExpressRLAdapter {
|
|
11
|
-
// /**
|
|
12
|
-
// * Create express rate-limit middleware dynamically
|
|
13
|
-
// */
|
|
14
|
-
// getMiddleware(options: {
|
|
15
|
-
// windowMs?: number;
|
|
16
|
-
// max?: number;
|
|
17
|
-
// message?: any;
|
|
18
|
-
// } = {}) {
|
|
19
|
-
// try {
|
|
20
|
-
// const limiter = rateLimit({
|
|
21
|
-
// windowMs: options.windowMs ?? 15 * 60 * 1000, // default
|
|
22
|
-
// max: options.max ?? 100,
|
|
23
|
-
// message: options.message ?? { error: "Too many requests" },
|
|
24
|
-
// standardHeaders: true,
|
|
25
|
-
// legacyHeaders: false,
|
|
26
|
-
// });
|
|
27
|
-
// return limiter;
|
|
28
|
-
// } catch (err: any) {
|
|
29
|
-
// logger.error("❌ ExpressRLAdapter: failed to create limiter", {
|
|
30
|
-
// error: err?.message || err
|
|
31
|
-
// });
|
|
32
|
-
// throw new AdapterError("Express rate limiter creation failed.");
|
|
33
|
-
// }
|
|
34
|
-
// }
|
|
35
|
-
// }
|
|
36
7
|
// src/adapters/ExpressRLAdapter.ts - IMPROVED
|
|
37
8
|
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
38
9
|
const index_js_1 = require("../logging/index.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpressRLAdapter.js","sourceRoot":"","sources":["../../src/adapters/ExpressRLAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExpressRLAdapter.js","sourceRoot":"","sources":["../../src/adapters/ExpressRLAdapter.ts"],"names":[],"mappings":";;;;;;AAAA,8CAA8C;AAC9C,4EAA2C;AAC3C,kDAA6C;AAC7C,oEAA8D;AAY9D,MAAa,gBAAgB;IACzB,aAAa,CAAC,UAA4B,EAAE;QACxC,IAAI,CAAC;YACD,MAAM,cAAc,GAAG;gBACnB,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,aAAa;gBACvC,GAAG,EAAE,GAAG;gBACR,OAAO,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE;gBACvC,eAAe,EAAE,IAAI;gBACrB,aAAa,EAAE,KAAK;gBACpB,kBAAkB,EAAE,KAAK;aAC5B,CAAC;YAEF,MAAM,YAAY,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC;YAEvD,MAAM,OAAO,GAAG,IAAA,4BAAS,EAAC,YAAY,CAAC,CAAC;YAExC,iBAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE;gBAC/C,QAAQ,EAAE,YAAY,CAAC,QAAQ;gBAC/B,GAAG,EAAE,YAAY,CAAC,GAAG;aACxB,CAAC,CAAC;YAEH,OAAO,OAAO,CAAC;QAEnB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,iBAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE;gBACzD,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG;aAC7B,CAAC,CAAC;YACH,MAAM,IAAI,8BAAY,CAAC,uCAAuC,CAAC,CAAC;QACpE,CAAC;IACL,CAAC;CACJ;AA9BD,4CA8BC","sourcesContent":["// src/adapters/ExpressRLAdapter.ts - IMPROVED\r\nimport rateLimit from \"express-rate-limit\";\r\nimport { logger } from \"../logging/index.js\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\n\r\nexport interface RateLimitOptions {\r\n windowMs?: number;\r\n max?: number;\r\n message?: any;\r\n skipFailedRequests?: boolean;\r\n standardHeaders?: boolean;\r\n legacyHeaders?: boolean;\r\n [key: string]: any;\r\n}\r\n\r\nexport class ExpressRLAdapter {\r\n getMiddleware(options: RateLimitOptions = {}) {\r\n try {\r\n const defaultOptions = {\r\n windowMs: 15 * 60 * 1000, // 15 minutes\r\n max: 100,\r\n message: { error: \"Too many requests\" },\r\n standardHeaders: true,\r\n legacyHeaders: false,\r\n skipFailedRequests: false\r\n };\r\n\r\n const finalOptions = { ...defaultOptions, ...options };\r\n \r\n const limiter = rateLimit(finalOptions);\r\n \r\n logger.debug(\"📌 Express rate limiter configured\", {\r\n windowMs: finalOptions.windowMs,\r\n max: finalOptions.max\r\n });\r\n\r\n return limiter;\r\n\r\n } catch (err: any) {\r\n logger.error(\"❌ ExpressRLAdapter: failed to create limiter\", {\r\n error: err?.message || err\r\n });\r\n throw new AdapterError(\"Express rate limiter creation failed.\");\r\n }\r\n }\r\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/GoogleAdapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GoogleAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/GoogleAdapter.ts"],"names":[],"mappings":"AAsIA,MAAM,WAAW,kBAAkB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAC,CAAS;gBAEd,QAAQ,CAAC,EAAE,MAAM;IASvB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAmDpE"}
|
|
@@ -103,7 +103,8 @@ exports.GoogleAdapter = void 0;
|
|
|
103
103
|
// src/adapters/GoogleAdapter.ts - FIXED
|
|
104
104
|
const google_auth_library_1 = require("google-auth-library");
|
|
105
105
|
const AdapterError_js_1 = require("../core/errors/AdapterError.js");
|
|
106
|
-
|
|
106
|
+
// import { logWarn, logError } from "../logging/index.js";
|
|
107
|
+
const logging_1 = require("../logging");
|
|
107
108
|
class GoogleAdapter {
|
|
108
109
|
constructor(clientId) {
|
|
109
110
|
if (clientId && clientId.trim().length === 0) {
|
|
@@ -127,7 +128,7 @@ class GoogleAdapter {
|
|
|
127
128
|
const ticket = await this.client.verifyIdToken(options);
|
|
128
129
|
const payload = ticket.getPayload();
|
|
129
130
|
if (!payload) {
|
|
130
|
-
|
|
131
|
+
logging_1.logger.warn("GoogleAdapter: Empty payload");
|
|
131
132
|
throw new AdapterError_js_1.AdapterError("Invalid Google ID token payload.");
|
|
132
133
|
}
|
|
133
134
|
// Create result object
|
|
@@ -144,7 +145,7 @@ class GoogleAdapter {
|
|
|
144
145
|
return result;
|
|
145
146
|
}
|
|
146
147
|
catch (err) {
|
|
147
|
-
|
|
148
|
+
logging_1.logger.error("GoogleAdapter.verifyIdToken failed", {
|
|
148
149
|
error: err?.message,
|
|
149
150
|
hasClientId: !!this.clientId
|
|
150
151
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoogleAdapter.js","sourceRoot":"","sources":["../../src/adapters/GoogleAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["// // import { OAuth2Client, LoginTicket } from \"google-auth-library\";\r\n// // import { AdapterError } from \"../core/errors/AdapterError\";\r\n// // import { logWarn, logError } from \"../logging\";\r\n\r\n// // export class GoogleAdapter {\r\n// // private client: OAuth2Client;\r\n// // private clientId?: string;\r\n\r\n// // constructor(clientId?: string) {\r\n// // this.client = new OAuth2Client(clientId);\r\n// // this.clientId = clientId as any;\r\n// // }\r\n\r\n// // async verifyIdToken(idToken: string) {\r\n// // try {\r\n// // const options: {\r\n// // idToken: string;\r\n// // audience?: string | string[];\r\n// // } = { idToken };\r\n\r\n// // // ADD ONLY IF DEFINED → FIXES TS ERROR\r\n// // if (this.clientId !== undefined) {\r\n// // options.audience = this.clientId;\r\n// // }\r\n\r\n// // const ticket: LoginTicket = await this.client.verifyIdToken(options);\r\n\r\n// // const payload = ticket.getPayload();\r\n// // if (!payload) {\r\n// // logWarn(\"GoogleAdapter: Empty payload\");\r\n// // throw new AdapterError(\"Invalid Google ID token payload.\");\r\n// // }\r\n\r\n// // return {\r\n// // sub: payload.sub,\r\n// // email: payload.email,\r\n// // email_verified: payload.email_verified,\r\n// // name: payload.name,\r\n// // picture: payload.picture,\r\n// // };\r\n\r\n// // } catch (err: any) {\r\n// // logError(\"GoogleAdapter.verifyIdToken failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"Google token verification failed\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n\r\n// // src/adapters/GoogleAdapter.ts - IMPROVED\r\n// import { OAuth2Client, LoginTicket } from \"google-auth-library\";\r\n// import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// import { logWarn, logError } from \"../logging/index.js\";\r\n\r\n// export interface GoogleTokenPayload {\r\n// sub: string;\r\n// email: string;\r\n// email_verified: boolean;\r\n// name?: string;\r\n// picture?: string;\r\n// [key: string]: any;\r\n// }\r\n\r\n// export class GoogleAdapter {\r\n// private client: OAuth2Client;\r\n// private clientId?: string;\r\n\r\n// constructor(clientId?: string) {\r\n// if (clientId && clientId.trim().length === 0) {\r\n// throw new AdapterError(\"Google clientId cannot be empty string\");\r\n// }\r\n \r\n// this.client = new OAuth2Client(clientId);\r\n// this.clientId = clientId;\r\n// }\r\n\r\n// async verifyIdToken(idToken: string): Promise<GoogleTokenPayload> {\r\n// try {\r\n// if (!idToken || typeof idToken !== 'string') {\r\n// throw new AdapterError(\"Invalid ID token provided\");\r\n// }\r\n\r\n// const options: { idToken: string; audience?: string | string[] } = { \r\n// idToken \r\n// };\r\n\r\n// // Add audience only if clientId is provided and not empty\r\n// if (this.clientId && this.clientId.trim().length > 0) {\r\n// options.audience = this.clientId;\r\n// }\r\n\r\n// const ticket: LoginTicket = await this.client.verifyIdToken(options);\r\n// const payload = ticket.getPayload();\r\n \r\n// if (!payload) {\r\n// logWarn(\"GoogleAdapter: Empty payload\");\r\n// throw new AdapterError(\"Invalid Google ID token payload.\");\r\n// }\r\n\r\n// return {\r\n// sub: payload.sub,\r\n// email: payload.email || '',\r\n// email_verified: payload.email_verified || false,\r\n// name: payload.name,\r\n// picture: payload.picture,\r\n// ...payload\r\n// };\r\n\r\n// } catch (err: any) {\r\n// logError(\"GoogleAdapter.verifyIdToken failed\", { \r\n// error: err?.message,\r\n// hasClientId: !!this.clientId \r\n// });\r\n \r\n// if (err.message?.includes('audience')) {\r\n// throw new AdapterError(\"Invalid Google client ID configured.\");\r\n// }\r\n \r\n// throw new AdapterError(err?.message || \"Google token verification failed\");\r\n// }\r\n// }\r\n// }\r\n\r\n\r\n\r\n// src/adapters/GoogleAdapter.ts - FIXED\r\nimport { OAuth2Client, LoginTicket } from \"google-auth-library\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logWarn, logError } from \"../logging/index.js\";\r\n\r\nexport interface GoogleTokenPayload {\r\n sub: string;\r\n email: string;\r\n email_verified: boolean;\r\n name?: string;\r\n picture?: string;\r\n [key: string]: any;\r\n}\r\n\r\nexport class GoogleAdapter {\r\n private client: OAuth2Client;\r\n private clientId?: string;\r\n\r\n constructor(clientId?: string) {\r\n if (clientId && clientId.trim().length === 0) {\r\n throw new AdapterError(\"Google clientId cannot be empty string\");\r\n }\r\n \r\n this.client = new OAuth2Client(clientId);\r\n this.clientId = clientId;\r\n }\r\n\r\n async verifyIdToken(idToken: string): Promise<GoogleTokenPayload> {\r\n try {\r\n if (!idToken || typeof idToken !== 'string') {\r\n throw new AdapterError(\"Invalid ID token provided\");\r\n }\r\n\r\n const options: { idToken: string; audience?: string | string[] } = { \r\n idToken \r\n };\r\n\r\n // Add audience only if clientId is provided and not empty\r\n if (this.clientId && this.clientId.trim().length > 0) {\r\n options.audience = this.clientId;\r\n }\r\n\r\n const ticket: LoginTicket = await this.client.verifyIdToken(options);\r\n const payload = ticket.getPayload();\r\n \r\n if (!payload) {\r\n logWarn(\"GoogleAdapter: Empty payload\");\r\n throw new AdapterError(\"Invalid Google ID token payload.\");\r\n }\r\n\r\n // Create result object\r\n const result: GoogleTokenPayload = {\r\n sub: payload.sub,\r\n email: payload.email || '',\r\n email_verified: payload.email_verified || false,\r\n name: payload.name,\r\n picture: payload.picture\r\n };\r\n\r\n // Add remaining properties from payload (excluding duplicates)\r\n const { sub, email, email_verified, name, picture, ...rest } = payload;\r\n Object.assign(result, rest);\r\n\r\n return result;\r\n\r\n } catch (err: any) {\r\n logError(\"GoogleAdapter.verifyIdToken failed\", { \r\n error: err?.message,\r\n hasClientId: !!this.clientId \r\n });\r\n \r\n if (err.message?.includes('audience')) {\r\n throw new AdapterError(\"Invalid Google client ID configured.\");\r\n }\r\n \r\n throw new AdapterError(err?.message || \"Google token verification failed\");\r\n }\r\n }\r\n}"]}
|
|
1
|
+
{"version":3,"file":"GoogleAdapter.js","sourceRoot":"","sources":["../../src/adapters/GoogleAdapter.ts"],"names":[],"mappings":";AAAA,sEAAsE;AACtE,iEAAiE;AACjE,qDAAqD;;;AAErD,kCAAkC;AAClC,uCAAuC;AACvC,oCAAoC;AAEpC,0CAA0C;AAC1C,uDAAuD;AACvD,8CAA8C;AAC9C,WAAW;AAEX,gDAAgD;AAChD,mBAAmB;AACnB,kCAAkC;AAClC,sCAAsC;AACtC,mDAAmD;AACnD,kCAAkC;AAElC,yDAAyD;AACzD,oDAAoD;AACpD,uDAAuD;AACvD,mBAAmB;AAEnB,uFAAuF;AAEvF,sDAAsD;AACtD,iCAAiC;AACjC,8DAA8D;AAC9D,iFAAiF;AACjF,mBAAmB;AAEnB,0BAA0B;AAC1B,uCAAuC;AACvC,2CAA2C;AAC3C,6DAA6D;AAC7D,yCAAyC;AACzC,+CAA+C;AAC/C,oBAAoB;AAEpB,kCAAkC;AAClC,0FAA0F;AAC1F,6FAA6F;AAC7F,eAAe;AACf,WAAW;AACX,OAAO;AAKP,8CAA8C;AAC9C,mEAAmE;AACnE,iEAAiE;AACjE,2DAA2D;AAE3D,wCAAwC;AACxC,mBAAmB;AACnB,qBAAqB;AACrB,+BAA+B;AAC/B,qBAAqB;AACrB,wBAAwB;AACxB,0BAA0B;AAC1B,IAAI;AAEJ,+BAA+B;AAC/B,oCAAoC;AACpC,iCAAiC;AAEjC,uCAAuC;AACvC,0DAA0D;AAC1D,gFAAgF;AAChF,YAAY;AAEZ,oDAAoD;AACpD,oCAAoC;AACpC,QAAQ;AAER,0EAA0E;AAC1E,gBAAgB;AAChB,6DAA6D;AAC7D,uEAAuE;AACvE,gBAAgB;AAEhB,oFAAoF;AACpF,2BAA2B;AAC3B,iBAAiB;AAEjB,yEAAyE;AACzE,sEAAsE;AACtE,oDAAoD;AACpD,gBAAgB;AAEhB,oFAAoF;AACpF,mDAAmD;AAEnD,8BAA8B;AAC9B,2DAA2D;AAC3D,8EAA8E;AAC9E,gBAAgB;AAEhB,uBAAuB;AACvB,oCAAoC;AACpC,8CAA8C;AAC9C,mEAAmE;AACnE,sCAAsC;AACtC,4CAA4C;AAC5C,6BAA6B;AAC7B,iBAAiB;AAEjB,+BAA+B;AAC/B,gEAAgE;AAChE,uCAAuC;AACvC,gDAAgD;AAChD,kBAAkB;AAElB,uDAAuD;AACvD,kFAAkF;AAClF,gBAAgB;AAEhB,0FAA0F;AAC1F,YAAY;AACZ,QAAQ;AACR,IAAI;AAIJ,wCAAwC;AACxC,6DAAgE;AAChE,oEAA8D;AAC9D,2DAA2D;AAE3D,wCAAkC;AAWlC,MAAa,aAAa;IAItB,YAAY,QAAiB;QACzB,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,8BAAY,CAAC,wCAAwC,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,kCAAY,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,OAAe;QAC/B,IAAI,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC1C,MAAM,IAAI,8BAAY,CAAC,2BAA2B,CAAC,CAAC;YACxD,CAAC;YAED,MAAM,OAAO,GAAsD;gBAC/D,OAAO;aACV,CAAC;YAEF,0DAA0D;YAC1D,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnD,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YACrC,CAAC;YAED,MAAM,MAAM,GAAgB,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACrE,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YAEpC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,gBAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;gBAC5C,MAAM,IAAI,8BAAY,CAAC,kCAAkC,CAAC,CAAC;YAC/D,CAAC;YAED,uBAAuB;YACvB,MAAM,MAAM,GAAuB;gBAC/B,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;gBAC1B,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,KAAK;gBAC/C,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;aAC3B,CAAC;YAEF,+DAA+D;YAC/D,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;YACvE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAE5B,OAAO,MAAM,CAAC;QAElB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,gBAAM,CAAC,KAAK,CAAC,oCAAoC,EAAE;gBAC/C,KAAK,EAAE,GAAG,EAAE,OAAO;gBACnB,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ;aAC/B,CAAC,CAAC;YAEH,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpC,MAAM,IAAI,8BAAY,CAAC,sCAAsC,CAAC,CAAC;YACnE,CAAC;YAED,MAAM,IAAI,8BAAY,CAAC,GAAG,EAAE,OAAO,IAAI,kCAAkC,CAAC,CAAC;QAC/E,CAAC;IACL,CAAC;CACJ;AAhED,sCAgEC","sourcesContent":["// // import { OAuth2Client, LoginTicket } from \"google-auth-library\";\r\n// // import { AdapterError } from \"../core/errors/AdapterError\";\r\n// // import { logWarn, logError } from \"../logging\";\r\n\r\n// // export class GoogleAdapter {\r\n// // private client: OAuth2Client;\r\n// // private clientId?: string;\r\n\r\n// // constructor(clientId?: string) {\r\n// // this.client = new OAuth2Client(clientId);\r\n// // this.clientId = clientId as any;\r\n// // }\r\n\r\n// // async verifyIdToken(idToken: string) {\r\n// // try {\r\n// // const options: {\r\n// // idToken: string;\r\n// // audience?: string | string[];\r\n// // } = { idToken };\r\n\r\n// // // ADD ONLY IF DEFINED → FIXES TS ERROR\r\n// // if (this.clientId !== undefined) {\r\n// // options.audience = this.clientId;\r\n// // }\r\n\r\n// // const ticket: LoginTicket = await this.client.verifyIdToken(options);\r\n\r\n// // const payload = ticket.getPayload();\r\n// // if (!payload) {\r\n// // logWarn(\"GoogleAdapter: Empty payload\");\r\n// // throw new AdapterError(\"Invalid Google ID token payload.\");\r\n// // }\r\n\r\n// // return {\r\n// // sub: payload.sub,\r\n// // email: payload.email,\r\n// // email_verified: payload.email_verified,\r\n// // name: payload.name,\r\n// // picture: payload.picture,\r\n// // };\r\n\r\n// // } catch (err: any) {\r\n// // logError(\"GoogleAdapter.verifyIdToken failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"Google token verification failed\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n\r\n// // src/adapters/GoogleAdapter.ts - IMPROVED\r\n// import { OAuth2Client, LoginTicket } from \"google-auth-library\";\r\n// import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// import { logWarn, logError } from \"../logging/index.js\";\r\n\r\n// export interface GoogleTokenPayload {\r\n// sub: string;\r\n// email: string;\r\n// email_verified: boolean;\r\n// name?: string;\r\n// picture?: string;\r\n// [key: string]: any;\r\n// }\r\n\r\n// export class GoogleAdapter {\r\n// private client: OAuth2Client;\r\n// private clientId?: string;\r\n\r\n// constructor(clientId?: string) {\r\n// if (clientId && clientId.trim().length === 0) {\r\n// throw new AdapterError(\"Google clientId cannot be empty string\");\r\n// }\r\n \r\n// this.client = new OAuth2Client(clientId);\r\n// this.clientId = clientId;\r\n// }\r\n\r\n// async verifyIdToken(idToken: string): Promise<GoogleTokenPayload> {\r\n// try {\r\n// if (!idToken || typeof idToken !== 'string') {\r\n// throw new AdapterError(\"Invalid ID token provided\");\r\n// }\r\n\r\n// const options: { idToken: string; audience?: string | string[] } = { \r\n// idToken \r\n// };\r\n\r\n// // Add audience only if clientId is provided and not empty\r\n// if (this.clientId && this.clientId.trim().length > 0) {\r\n// options.audience = this.clientId;\r\n// }\r\n\r\n// const ticket: LoginTicket = await this.client.verifyIdToken(options);\r\n// const payload = ticket.getPayload();\r\n \r\n// if (!payload) {\r\n// logWarn(\"GoogleAdapter: Empty payload\");\r\n// throw new AdapterError(\"Invalid Google ID token payload.\");\r\n// }\r\n\r\n// return {\r\n// sub: payload.sub,\r\n// email: payload.email || '',\r\n// email_verified: payload.email_verified || false,\r\n// name: payload.name,\r\n// picture: payload.picture,\r\n// ...payload\r\n// };\r\n\r\n// } catch (err: any) {\r\n// logError(\"GoogleAdapter.verifyIdToken failed\", { \r\n// error: err?.message,\r\n// hasClientId: !!this.clientId \r\n// });\r\n \r\n// if (err.message?.includes('audience')) {\r\n// throw new AdapterError(\"Invalid Google client ID configured.\");\r\n// }\r\n \r\n// throw new AdapterError(err?.message || \"Google token verification failed\");\r\n// }\r\n// }\r\n// }\r\n\r\n\r\n\r\n// src/adapters/GoogleAdapter.ts - FIXED\r\nimport { OAuth2Client, LoginTicket } from \"google-auth-library\";\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// import { logWarn, logError } from \"../logging/index.js\";\r\n\r\nimport {logger} from '../logging';\r\n\r\nexport interface GoogleTokenPayload {\r\n sub: string;\r\n email: string;\r\n email_verified: boolean;\r\n name?: string;\r\n picture?: string;\r\n [key: string]: any;\r\n}\r\n\r\nexport class GoogleAdapter {\r\n private client: OAuth2Client;\r\n private clientId?: string;\r\n\r\n constructor(clientId?: string) {\r\n if (clientId && clientId.trim().length === 0) {\r\n throw new AdapterError(\"Google clientId cannot be empty string\");\r\n }\r\n \r\n this.client = new OAuth2Client(clientId);\r\n this.clientId = clientId;\r\n }\r\n\r\n async verifyIdToken(idToken: string): Promise<GoogleTokenPayload> {\r\n try {\r\n if (!idToken || typeof idToken !== 'string') {\r\n throw new AdapterError(\"Invalid ID token provided\");\r\n }\r\n\r\n const options: { idToken: string; audience?: string | string[] } = { \r\n idToken \r\n };\r\n\r\n // Add audience only if clientId is provided and not empty\r\n if (this.clientId && this.clientId.trim().length > 0) {\r\n options.audience = this.clientId;\r\n }\r\n\r\n const ticket: LoginTicket = await this.client.verifyIdToken(options);\r\n const payload = ticket.getPayload();\r\n \r\n if (!payload) {\r\n logger.warn(\"GoogleAdapter: Empty payload\");\r\n throw new AdapterError(\"Invalid Google ID token payload.\");\r\n }\r\n\r\n // Create result object\r\n const result: GoogleTokenPayload = {\r\n sub: payload.sub,\r\n email: payload.email || '',\r\n email_verified: payload.email_verified || false,\r\n name: payload.name,\r\n picture: payload.picture\r\n };\r\n\r\n // Add remaining properties from payload (excluding duplicates)\r\n const { sub, email, email_verified, name, picture, ...rest } = payload;\r\n Object.assign(result, rest);\r\n\r\n return result;\r\n\r\n } catch (err: any) {\r\n logger.error(\"GoogleAdapter.verifyIdToken failed\", { \r\n error: err?.message,\r\n hasClientId: !!this.clientId \r\n });\r\n \r\n if (err.message?.includes('audience')) {\r\n throw new AdapterError(\"Invalid Google client ID configured.\");\r\n }\r\n \r\n throw new AdapterError(err?.message || \"Google token verification failed\");\r\n }\r\n }\r\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JWTAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/JWTAdapter.ts"],"names":[],"mappings":"AA8PA,OAAO,GAAG,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"JWTAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/JWTAdapter.ts"],"names":[],"mappings":"AA8PA,OAAO,GAAG,MAAM,cAAc,CAAC;AAM/B,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC;AAED,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAC,CAAkB;IACpC,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,CAAoB;gBAEzB,OAAO,EAAE,iBAAiB;IAiBtC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW;IAwB3C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE;CAuBnE"}
|
|
@@ -214,13 +214,15 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
|
214
214
|
const crypto_1 = require("crypto"); // Built-in Node.js
|
|
215
215
|
const AdapterError_js_1 = require("../core/errors/AdapterError.js");
|
|
216
216
|
const index_js_1 = require("../logging/index.js");
|
|
217
|
+
const logging_1 = require("../logging");
|
|
217
218
|
class JWTAdapter {
|
|
218
219
|
constructor(options) {
|
|
219
220
|
if (!options.secret) {
|
|
220
221
|
throw new AdapterError_js_1.AdapterError("JWT secret is required");
|
|
221
222
|
}
|
|
222
223
|
if (options.secret.length < 32) {
|
|
223
|
-
|
|
224
|
+
logging_1.logger.warn("🚨 JWT secret shorter than 32 chars. Consider using stronger secret.");
|
|
225
|
+
// logError("⚠ JWT secret is too short (minimum 32 characters recommended)");
|
|
224
226
|
}
|
|
225
227
|
this.secret = options.secret;
|
|
226
228
|
this.expiresIn = options.expiresIn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JWTAdapter.js","sourceRoot":"","sources":["../../src/adapters/JWTAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["// // import jwt from \"jsonwebtoken\";\r\n// // import { AdapterError } from \"../core/errors/AdapterError\";\r\n// // import { logError } from \"../logging\";\r\n\r\n// // export interface JWTAdapterOptions {\r\n// // secret: string;\r\n// // expiresIn?: string | number | undefined;\r\n// // }\r\n\r\n// // export class JWTAdapter {\r\n// // private secret: string;\r\n// // private expiresIn?: string | number;\r\n\r\n// // constructor(options: JWTAdapterOptions) {\r\n// // if (!options.secret) {\r\n// // throw new AdapterError(\"JWT secret is required\");\r\n// // }\r\n\r\n// // this.secret = options.secret;\r\n\r\n// // // Normalize expiresIn\r\n// // if (options.expiresIn !== undefined) {\r\n// // this.expiresIn = options.expiresIn as string | number;\r\n// // }\r\n// // }\r\n\r\n// // sign(\r\n// // payload: object,\r\n// // options?: { expiresIn?: string | number }\r\n// // ) {\r\n// // try {\r\n// // const finalExpires =\r\n// // options?.expiresIn ?? this.expiresIn;\r\n\r\n// // const jwtOptions: jwt.SignOptions = {};\r\n\r\n// // if (finalExpires !== undefined) {\r\n// // // Force safe cast → matches SignOptions type\r\n// // jwtOptions.expiresIn = finalExpires as number | any;\r\n// // }\r\n\r\n// // return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"JWT sign failed\");\r\n// // }\r\n// // }\r\n\r\n// // verify(token: string) {\r\n// // try {\r\n// // return jwt.verify(token, this.secret);\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"JWT verify failed\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n// // // src/adapters/JWTAdapter.ts - FIXED (Security hardening)\r\n// // import jwt from \"jsonwebtoken\";\r\n// // import { v4 as uuidv4 } from \"uuid\";\r\n// // import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// // import { logError } from \"../logging/index.js\";\r\n\r\n// // export interface JWTAdapterOptions {\r\n// // secret: string;\r\n// // expiresIn?: string | number;\r\n// // algorithm?: jwt.Algorithm;\r\n// // issuer?: string;\r\n// // audience?: string | string[];\r\n// // }\r\n\r\n// // export interface SignOptions {\r\n// // expiresIn?: string | number;\r\n// // jti?: string; // JWT ID for token revocation\r\n// // subject?: string;\r\n// // issuer?: string;\r\n// // audience?: string | string[];\r\n// // }\r\n\r\n// // export class JWTAdapter {\r\n// // private secret: string;\r\n// // private expiresIn?: string | number;\r\n// // private algorithm: jwt.Algorithm;\r\n// // private issuer?: string;\r\n// // private audience?: string | string[];\r\n\r\n// // constructor(options: JWTAdapterOptions) {\r\n// // if (!options.secret) {\r\n// // throw new AdapterError(\"JWT secret is required\");\r\n// // }\r\n\r\n// // if (options.secret.length < 32) {\r\n// // logError(\"⚠ JWT secret is too short (minimum 32 characters recommended)\");\r\n// // }\r\n\r\n// // this.secret = options.secret;\r\n// // this.expiresIn = options.expiresIn;\r\n// // this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm\r\n// // this.issuer = options.issuer;\r\n// // this.audience = options.audience;\r\n// // }\r\n\r\n// // sign(payload: object, options?: SignOptions) {\r\n// // try {\r\n// // const jwtOptions: jwt.SignOptions = {\r\n// // algorithm: this.algorithm,\r\n// // issuer: options?.issuer || this.issuer,\r\n// // audience: options?.audience || this.audience,\r\n// // jwtid: options?.jti || uuidv4(), // Unique token ID\r\n// // subject: options?.subject\r\n// // };\r\n\r\n// // if (options?.expiresIn !== undefined) {\r\n// // jwtOptions.expiresIn = options.expiresIn as number;\r\n// // } else if (this.expiresIn !== undefined) {\r\n// // jwtOptions.expiresIn = this.expiresIn as number;\r\n// // }\r\n\r\n// // return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"JWT sign failed\");\r\n// // }\r\n// // }\r\n\r\n// // verify(token: string, options?: { audience?: string | string[] }) {\r\n// // try {\r\n// // const verifyOptions: jwt.VerifyOptions = {\r\n// // algorithms: [this.algorithm],\r\n// // issuer: this.issuer,\r\n// // audience: options?.audience as string || this.audience as string\r\n// // };\r\n\r\n// // return jwt.verify(token, this.secret, verifyOptions);\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n \r\n// // // Provide better error messages\r\n// // if (err.name === 'TokenExpiredError') {\r\n// // throw new AdapterError(\"JWT token has expired\");\r\n// // }\r\n// // if (err.name === 'JsonWebTokenError') {\r\n// // throw new AdapterError(\"Invalid JWT token\");\r\n// // }\r\n \r\n// // throw new AdapterError(err?.message || \"JWT verification failed\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n\r\n// // src/adapters/JWTAdapter.ts - FIXED (Security hardening)\r\n// import jwt from \"jsonwebtoken\";\r\n// import { nanoid } from \"nanoid\"; // CHANGED: from uuid to nanoid\r\n// import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// import { logError } from \"../logging/index.js\";\r\n\r\n// export interface JWTAdapterOptions {\r\n// secret: string;\r\n// expiresIn?: string | number;\r\n// algorithm?: jwt.Algorithm;\r\n// issuer?: string;\r\n// audience?: string | string[];\r\n// }\r\n\r\n// export interface SignOptions {\r\n// expiresIn?: string | number;\r\n// jti?: string; // JWT ID for token revocation\r\n// subject?: string;\r\n// issuer?: string;\r\n// audience?: string | string[];\r\n// }\r\n\r\n// export class JWTAdapter {\r\n// private secret: string;\r\n// private expiresIn?: string | number;\r\n// private algorithm: jwt.Algorithm;\r\n// private issuer?: string;\r\n// private audience?: string | string[];\r\n\r\n// constructor(options: JWTAdapterOptions) {\r\n// if (!options.secret) {\r\n// throw new AdapterError(\"JWT secret is required\");\r\n// }\r\n\r\n// if (options.secret.length < 32) {\r\n// logError(\"⚠ JWT secret is too short (minimum 32 characters recommended)\");\r\n// }\r\n\r\n// this.secret = options.secret;\r\n// this.expiresIn = options.expiresIn;\r\n// this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm\r\n// this.issuer = options.issuer;\r\n// this.audience = options.audience;\r\n// }\r\n\r\n// sign(payload: object, options?: SignOptions) {\r\n// try {\r\n// const jwtOptions: jwt.SignOptions = {\r\n// algorithm: this.algorithm,\r\n// issuer: options?.issuer || this.issuer,\r\n// audience: options?.audience || this.audience,\r\n// jwtid: options?.jti || nanoid(), // CHANGED: uuidv4() to nanoid()\r\n// subject: options?.subject\r\n// };\r\n\r\n// if (options?.expiresIn !== undefined) {\r\n// jwtOptions.expiresIn = options.expiresIn as number;\r\n// } else if (this.expiresIn !== undefined) {\r\n// jwtOptions.expiresIn = this.expiresIn as number;\r\n// }\r\n\r\n// return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n// } catch (err: any) {\r\n// logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n// throw new AdapterError(err?.message || \"JWT sign failed\");\r\n// }\r\n// }\r\n\r\n// verify(token: string, options?: { audience?: string | string[] }) {\r\n// try {\r\n// const verifyOptions: jwt.VerifyOptions = {\r\n// algorithms: [this.algorithm],\r\n// issuer: this.issuer,\r\n// audience: options?.audience as string || this.audience as string\r\n// };\r\n\r\n// return jwt.verify(token, this.secret, verifyOptions);\r\n// } catch (err: any) {\r\n// logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n \r\n// // Provide better error messages\r\n// if (err.name === 'TokenExpiredError') {\r\n// throw new AdapterError(\"JWT token has expired\");\r\n// }\r\n// if (err.name === 'JsonWebTokenError') {\r\n// throw new AdapterError(\"Invalid JWT token\");\r\n// }\r\n \r\n// throw new AdapterError(err?.message || \"JWT verification failed\");\r\n// }\r\n// }\r\n// }\r\n\r\n\r\n\r\n\r\n// src/adapters/JWTAdapter.ts - FIXED (Using crypto.randomUUID())\r\nimport jwt from \"jsonwebtoken\";\r\nimport { randomUUID } from \"crypto\"; // Built-in Node.js\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logError } from \"../logging/index.js\";\r\n\r\nexport interface JWTAdapterOptions {\r\n secret: string;\r\n expiresIn?: string | number;\r\n algorithm?: jwt.Algorithm;\r\n issuer?: string;\r\n audience?: string | string[];\r\n}\r\n\r\nexport interface SignOptions {\r\n expiresIn?: string | number;\r\n jti?: string; // JWT ID for token revocation\r\n subject?: string;\r\n issuer?: string;\r\n audience?: string | string[];\r\n}\r\n\r\nexport class JWTAdapter {\r\n private secret: string;\r\n private expiresIn?: string | number;\r\n private algorithm: jwt.Algorithm;\r\n private issuer?: string;\r\n private audience?: string | string[];\r\n\r\n constructor(options: JWTAdapterOptions) {\r\n if (!options.secret) {\r\n throw new AdapterError(\"JWT secret is required\");\r\n }\r\n\r\n if (options.secret.length < 32) {\r\n logError(\"⚠ JWT secret is too short (minimum 32 characters recommended)\");\r\n }\r\n\r\n this.secret = options.secret;\r\n this.expiresIn = options.expiresIn;\r\n this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm\r\n this.issuer = options.issuer;\r\n this.audience = options.audience;\r\n }\r\n\r\n sign(payload: object, options?: SignOptions) {\r\n try {\r\n const jwtOptions: jwt.SignOptions = {\r\n algorithm: this.algorithm,\r\n issuer: options?.issuer || this.issuer,\r\n audience: options?.audience || this.audience,\r\n jwtid: options?.jti || randomUUID(), // ✅ Using crypto.randomUUID()\r\n subject: options?.subject\r\n };\r\n\r\n if (options?.expiresIn !== undefined) {\r\n jwtOptions.expiresIn = options.expiresIn as number;\r\n } else if (this.expiresIn !== undefined) {\r\n jwtOptions.expiresIn = this.expiresIn as number;\r\n }\r\n\r\n return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n } catch (err: any) {\r\n logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n throw new AdapterError(err?.message || \"JWT sign failed\");\r\n }\r\n }\r\n\r\n verify(token: string, options?: { audience?: string | string[] }) {\r\n try {\r\n const verifyOptions: jwt.VerifyOptions = {\r\n algorithms: [this.algorithm],\r\n issuer: this.issuer,\r\n audience: options?.audience as string || this.audience as string\r\n };\r\n\r\n return jwt.verify(token, this.secret, verifyOptions);\r\n } catch (err: any) {\r\n logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n \r\n // Provide better error messages\r\n if (err.name === 'TokenExpiredError') {\r\n throw new AdapterError(\"JWT token has expired\");\r\n }\r\n if (err.name === 'JsonWebTokenError') {\r\n throw new AdapterError(\"Invalid JWT token\");\r\n }\r\n \r\n throw new AdapterError(err?.message || \"JWT verification failed\");\r\n }\r\n }\r\n}"]}
|
|
1
|
+
{"version":3,"file":"JWTAdapter.js","sourceRoot":"","sources":["../../src/adapters/JWTAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["// // import jwt from \"jsonwebtoken\";\r\n// // import { AdapterError } from \"../core/errors/AdapterError\";\r\n// // import { logError } from \"../logging\";\r\n\r\n// // export interface JWTAdapterOptions {\r\n// // secret: string;\r\n// // expiresIn?: string | number | undefined;\r\n// // }\r\n\r\n// // export class JWTAdapter {\r\n// // private secret: string;\r\n// // private expiresIn?: string | number;\r\n\r\n// // constructor(options: JWTAdapterOptions) {\r\n// // if (!options.secret) {\r\n// // throw new AdapterError(\"JWT secret is required\");\r\n// // }\r\n\r\n// // this.secret = options.secret;\r\n\r\n// // // Normalize expiresIn\r\n// // if (options.expiresIn !== undefined) {\r\n// // this.expiresIn = options.expiresIn as string | number;\r\n// // }\r\n// // }\r\n\r\n// // sign(\r\n// // payload: object,\r\n// // options?: { expiresIn?: string | number }\r\n// // ) {\r\n// // try {\r\n// // const finalExpires =\r\n// // options?.expiresIn ?? this.expiresIn;\r\n\r\n// // const jwtOptions: jwt.SignOptions = {};\r\n\r\n// // if (finalExpires !== undefined) {\r\n// // // Force safe cast → matches SignOptions type\r\n// // jwtOptions.expiresIn = finalExpires as number | any;\r\n// // }\r\n\r\n// // return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"JWT sign failed\");\r\n// // }\r\n// // }\r\n\r\n// // verify(token: string) {\r\n// // try {\r\n// // return jwt.verify(token, this.secret);\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"JWT verify failed\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n\r\n\r\n// // // src/adapters/JWTAdapter.ts - FIXED (Security hardening)\r\n// // import jwt from \"jsonwebtoken\";\r\n// // import { v4 as uuidv4 } from \"uuid\";\r\n// // import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// // import { logError } from \"../logging/index.js\";\r\n\r\n// // export interface JWTAdapterOptions {\r\n// // secret: string;\r\n// // expiresIn?: string | number;\r\n// // algorithm?: jwt.Algorithm;\r\n// // issuer?: string;\r\n// // audience?: string | string[];\r\n// // }\r\n\r\n// // export interface SignOptions {\r\n// // expiresIn?: string | number;\r\n// // jti?: string; // JWT ID for token revocation\r\n// // subject?: string;\r\n// // issuer?: string;\r\n// // audience?: string | string[];\r\n// // }\r\n\r\n// // export class JWTAdapter {\r\n// // private secret: string;\r\n// // private expiresIn?: string | number;\r\n// // private algorithm: jwt.Algorithm;\r\n// // private issuer?: string;\r\n// // private audience?: string | string[];\r\n\r\n// // constructor(options: JWTAdapterOptions) {\r\n// // if (!options.secret) {\r\n// // throw new AdapterError(\"JWT secret is required\");\r\n// // }\r\n\r\n// // if (options.secret.length < 32) {\r\n// // logError(\"⚠ JWT secret is too short (minimum 32 characters recommended)\");\r\n// // }\r\n\r\n// // this.secret = options.secret;\r\n// // this.expiresIn = options.expiresIn;\r\n// // this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm\r\n// // this.issuer = options.issuer;\r\n// // this.audience = options.audience;\r\n// // }\r\n\r\n// // sign(payload: object, options?: SignOptions) {\r\n// // try {\r\n// // const jwtOptions: jwt.SignOptions = {\r\n// // algorithm: this.algorithm,\r\n// // issuer: options?.issuer || this.issuer,\r\n// // audience: options?.audience || this.audience,\r\n// // jwtid: options?.jti || uuidv4(), // Unique token ID\r\n// // subject: options?.subject\r\n// // };\r\n\r\n// // if (options?.expiresIn !== undefined) {\r\n// // jwtOptions.expiresIn = options.expiresIn as number;\r\n// // } else if (this.expiresIn !== undefined) {\r\n// // jwtOptions.expiresIn = this.expiresIn as number;\r\n// // }\r\n\r\n// // return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n// // throw new AdapterError(err?.message || \"JWT sign failed\");\r\n// // }\r\n// // }\r\n\r\n// // verify(token: string, options?: { audience?: string | string[] }) {\r\n// // try {\r\n// // const verifyOptions: jwt.VerifyOptions = {\r\n// // algorithms: [this.algorithm],\r\n// // issuer: this.issuer,\r\n// // audience: options?.audience as string || this.audience as string\r\n// // };\r\n\r\n// // return jwt.verify(token, this.secret, verifyOptions);\r\n// // } catch (err: any) {\r\n// // logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n \r\n// // // Provide better error messages\r\n// // if (err.name === 'TokenExpiredError') {\r\n// // throw new AdapterError(\"JWT token has expired\");\r\n// // }\r\n// // if (err.name === 'JsonWebTokenError') {\r\n// // throw new AdapterError(\"Invalid JWT token\");\r\n// // }\r\n \r\n// // throw new AdapterError(err?.message || \"JWT verification failed\");\r\n// // }\r\n// // }\r\n// // }\r\n\r\n\r\n// // src/adapters/JWTAdapter.ts - FIXED (Security hardening)\r\n// import jwt from \"jsonwebtoken\";\r\n// import { nanoid } from \"nanoid\"; // CHANGED: from uuid to nanoid\r\n// import { AdapterError } from \"../core/errors/AdapterError.js\";\r\n// import { logError } from \"../logging/index.js\";\r\n\r\n// export interface JWTAdapterOptions {\r\n// secret: string;\r\n// expiresIn?: string | number;\r\n// algorithm?: jwt.Algorithm;\r\n// issuer?: string;\r\n// audience?: string | string[];\r\n// }\r\n\r\n// export interface SignOptions {\r\n// expiresIn?: string | number;\r\n// jti?: string; // JWT ID for token revocation\r\n// subject?: string;\r\n// issuer?: string;\r\n// audience?: string | string[];\r\n// }\r\n\r\n// export class JWTAdapter {\r\n// private secret: string;\r\n// private expiresIn?: string | number;\r\n// private algorithm: jwt.Algorithm;\r\n// private issuer?: string;\r\n// private audience?: string | string[];\r\n\r\n// constructor(options: JWTAdapterOptions) {\r\n// if (!options.secret) {\r\n// throw new AdapterError(\"JWT secret is required\");\r\n// }\r\n\r\n// if (options.secret.length < 32) {\r\n// logError(\"⚠ JWT secret is too short (minimum 32 characters recommended)\");\r\n// }\r\n\r\n// this.secret = options.secret;\r\n// this.expiresIn = options.expiresIn;\r\n// this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm\r\n// this.issuer = options.issuer;\r\n// this.audience = options.audience;\r\n// }\r\n\r\n// sign(payload: object, options?: SignOptions) {\r\n// try {\r\n// const jwtOptions: jwt.SignOptions = {\r\n// algorithm: this.algorithm,\r\n// issuer: options?.issuer || this.issuer,\r\n// audience: options?.audience || this.audience,\r\n// jwtid: options?.jti || nanoid(), // CHANGED: uuidv4() to nanoid()\r\n// subject: options?.subject\r\n// };\r\n\r\n// if (options?.expiresIn !== undefined) {\r\n// jwtOptions.expiresIn = options.expiresIn as number;\r\n// } else if (this.expiresIn !== undefined) {\r\n// jwtOptions.expiresIn = this.expiresIn as number;\r\n// }\r\n\r\n// return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n// } catch (err: any) {\r\n// logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n// throw new AdapterError(err?.message || \"JWT sign failed\");\r\n// }\r\n// }\r\n\r\n// verify(token: string, options?: { audience?: string | string[] }) {\r\n// try {\r\n// const verifyOptions: jwt.VerifyOptions = {\r\n// algorithms: [this.algorithm],\r\n// issuer: this.issuer,\r\n// audience: options?.audience as string || this.audience as string\r\n// };\r\n\r\n// return jwt.verify(token, this.secret, verifyOptions);\r\n// } catch (err: any) {\r\n// logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n \r\n// // Provide better error messages\r\n// if (err.name === 'TokenExpiredError') {\r\n// throw new AdapterError(\"JWT token has expired\");\r\n// }\r\n// if (err.name === 'JsonWebTokenError') {\r\n// throw new AdapterError(\"Invalid JWT token\");\r\n// }\r\n \r\n// throw new AdapterError(err?.message || \"JWT verification failed\");\r\n// }\r\n// }\r\n// }\r\n\r\n\r\n\r\n\r\n// src/adapters/JWTAdapter.ts - FIXED (Using crypto.randomUUID())\r\nimport jwt from \"jsonwebtoken\";\r\nimport { randomUUID } from \"crypto\"; // Built-in Node.js\r\nimport { AdapterError } from \"../core/errors/AdapterError.js\";\r\nimport { logError } from \"../logging/index.js\";\r\nimport { logger } from \"../logging\";\r\n\r\nexport interface JWTAdapterOptions {\r\n secret: string;\r\n expiresIn?: string | number;\r\n algorithm?: jwt.Algorithm;\r\n issuer?: string;\r\n audience?: string | string[];\r\n}\r\n\r\nexport interface SignOptions {\r\n expiresIn?: string | number;\r\n jti?: string; // JWT ID for token revocation\r\n subject?: string;\r\n issuer?: string;\r\n audience?: string | string[];\r\n}\r\n\r\nexport class JWTAdapter {\r\n private secret: string;\r\n private expiresIn?: string | number;\r\n private algorithm: jwt.Algorithm;\r\n private issuer?: string;\r\n private audience?: string | string[];\r\n\r\n constructor(options: JWTAdapterOptions) {\r\n if (!options.secret) {\r\n throw new AdapterError(\"JWT secret is required\");\r\n }\r\n\r\n if (options.secret.length < 32) {\r\n logger.warn(\"🚨 JWT secret shorter than 32 chars. Consider using stronger secret.\");\r\n // logError(\"⚠ JWT secret is too short (minimum 32 characters recommended)\");\r\n }\r\n\r\n this.secret = options.secret;\r\n this.expiresIn = options.expiresIn;\r\n this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm\r\n this.issuer = options.issuer;\r\n this.audience = options.audience;\r\n }\r\n\r\n sign(payload: object, options?: SignOptions) {\r\n try {\r\n const jwtOptions: jwt.SignOptions = {\r\n algorithm: this.algorithm,\r\n issuer: options?.issuer || this.issuer,\r\n audience: options?.audience || this.audience,\r\n jwtid: options?.jti || randomUUID(), // ✅ Using crypto.randomUUID()\r\n subject: options?.subject\r\n };\r\n\r\n if (options?.expiresIn !== undefined) {\r\n jwtOptions.expiresIn = options.expiresIn as number;\r\n } else if (this.expiresIn !== undefined) {\r\n jwtOptions.expiresIn = this.expiresIn as number;\r\n }\r\n\r\n return jwt.sign(payload, this.secret, jwtOptions);\r\n\r\n } catch (err: any) {\r\n logError(\"JWTAdapter.sign failed\", { error: err?.message });\r\n throw new AdapterError(err?.message || \"JWT sign failed\");\r\n }\r\n }\r\n\r\n verify(token: string, options?: { audience?: string | string[] }) {\r\n try {\r\n const verifyOptions: jwt.VerifyOptions = {\r\n algorithms: [this.algorithm],\r\n issuer: this.issuer,\r\n audience: options?.audience as string || this.audience as string\r\n };\r\n\r\n return jwt.verify(token, this.secret, verifyOptions);\r\n } catch (err: any) {\r\n logError(\"JWTAdapter.verify failed\", { error: err?.message });\r\n \r\n // Provide better error messages\r\n if (err.name === 'TokenExpiredError') {\r\n throw new AdapterError(\"JWT token has expired\");\r\n }\r\n if (err.name === 'JsonWebTokenError') {\r\n throw new AdapterError(\"Invalid JWT token\");\r\n }\r\n \r\n throw new AdapterError(err?.message || \"JWT verification failed\");\r\n }\r\n }\r\n}"]}
|
package/dist/core/HiSecure.d.ts
CHANGED
|
@@ -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 {
|
|
9
|
+
import { ValidationSchema } from "./types/SecureOptions.js";
|
|
10
10
|
export declare class HiSecure {
|
|
11
11
|
private static instance;
|
|
12
12
|
private config;
|
|
@@ -22,38 +22,23 @@ 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;
|
|
29
25
|
private constructor();
|
|
30
26
|
static getInstance(config?: Partial<HiSecureConfig>): HiSecure;
|
|
31
27
|
static resetInstance(): void;
|
|
32
28
|
init(): void;
|
|
33
|
-
isInitialized(): boolean;
|
|
34
29
|
static auth(options?: {
|
|
35
30
|
required?: boolean;
|
|
36
31
|
roles?: string[];
|
|
37
32
|
}): (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => void;
|
|
38
|
-
static validate(schema: ValidationSchema): (req: any, res: any, next: any) =>
|
|
33
|
+
static validate(schema: ValidationSchema): (req: any, res: any, next: any) => any;
|
|
39
34
|
static sanitize(options?: any): (req: any, _res: any, next: any) => void;
|
|
40
|
-
static rateLimit(preset: "strict" | "relaxed" | "api" | object): any;
|
|
41
35
|
static cors(options?: any): (req: import("cors").CorsRequest, res: {
|
|
42
36
|
statusCode?: number | undefined;
|
|
43
37
|
setHeader(key: string, value: string): any;
|
|
44
38
|
end(): any;
|
|
45
39
|
}, next: (err?: any) => any) => void;
|
|
40
|
+
static rateLimit(preset: "strict" | "relaxed" | "api" | object): any;
|
|
46
41
|
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[];
|
|
57
42
|
private setupAdapters;
|
|
58
43
|
private setupManagers;
|
|
59
44
|
private setupDynamicManagers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HiSecure.d.ts","sourceRoot":"","sources":["../../src/core/HiSecure.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/core/HiSecure.js
CHANGED
|
@@ -33,13 +33,12 @@ const hpp_1 = __importDefault(require("hpp"));
|
|
|
33
33
|
const compression_1 = __importDefault(require("compression"));
|
|
34
34
|
const errorHandler_js_1 = require("../middlewares/errorHandler.js");
|
|
35
35
|
class HiSecure {
|
|
36
|
-
// Private constructor for singleton
|
|
37
36
|
constructor(userConfig = {}) {
|
|
38
37
|
this.initialized = false;
|
|
39
38
|
this.config = (0, deepMerge_js_1.deepMerge)(config_js_1.defaultConfig, userConfig);
|
|
40
39
|
}
|
|
41
40
|
// =====================================================
|
|
42
|
-
// SINGLETON
|
|
41
|
+
// SINGLETON
|
|
43
42
|
// =====================================================
|
|
44
43
|
static getInstance(config) {
|
|
45
44
|
if (!HiSecure.instance) {
|
|
@@ -52,39 +51,23 @@ class HiSecure {
|
|
|
52
51
|
HiSecure.instance = null;
|
|
53
52
|
}
|
|
54
53
|
init() {
|
|
55
|
-
if (this.initialized)
|
|
56
|
-
index_js_1.logger.warn("⚠ HiSecure already initialized");
|
|
54
|
+
if (this.initialized)
|
|
57
55
|
return;
|
|
58
|
-
}
|
|
59
56
|
index_js_1.logger.info(`🔐 ${constants_js_1.LIB_NAME} v${constants_js_1.LIB_VERSION} initializing...`);
|
|
60
57
|
this.setupAdapters();
|
|
61
58
|
this.setupManagers();
|
|
62
59
|
this.setupDynamicManagers();
|
|
63
|
-
//
|
|
60
|
+
// ❌ DO NOT FREEZE MANAGERS
|
|
61
|
+
// ✔ Only freeze config
|
|
64
62
|
(0, deepFreeze_js_1.deepFreeze)(this.config);
|
|
65
|
-
(0, deepFreeze_js_1.deepFreeze)(this.hashManager);
|
|
66
|
-
(0, deepFreeze_js_1.deepFreeze)(this.rateLimitManager);
|
|
67
|
-
(0, deepFreeze_js_1.deepFreeze)(this.validatorManager);
|
|
68
|
-
(0, deepFreeze_js_1.deepFreeze)(this.sanitizerManager);
|
|
69
|
-
(0, deepFreeze_js_1.deepFreeze)(this.jsonManager);
|
|
70
|
-
(0, deepFreeze_js_1.deepFreeze)(this.corsManager);
|
|
71
|
-
if (this.authManager)
|
|
72
|
-
(0, deepFreeze_js_1.deepFreeze)(this.authManager);
|
|
73
63
|
this.initialized = true;
|
|
74
64
|
index_js_1.logger.info("✅ HiSecure initialized successfully");
|
|
75
65
|
}
|
|
76
|
-
isInitialized() {
|
|
77
|
-
return this.initialized;
|
|
78
|
-
}
|
|
79
66
|
// =====================================================
|
|
80
|
-
// FLUENT API
|
|
67
|
+
// FLUENT API (Route-level)
|
|
81
68
|
// =====================================================
|
|
82
69
|
static auth(options) {
|
|
83
|
-
|
|
84
|
-
if (!instance.authManager) {
|
|
85
|
-
throw new Error("Auth not enabled. Set auth.enabled=true in config.");
|
|
86
|
-
}
|
|
87
|
-
return instance.authManager.protect(options);
|
|
70
|
+
return this.getInstance().authManager.protect(options);
|
|
88
71
|
}
|
|
89
72
|
static validate(schema) {
|
|
90
73
|
return this.getInstance().validatorManager.validate(schema);
|
|
@@ -92,6 +75,9 @@ class HiSecure {
|
|
|
92
75
|
static sanitize(options) {
|
|
93
76
|
return this.getInstance().sanitizerManager.middleware(options);
|
|
94
77
|
}
|
|
78
|
+
static cors(options) {
|
|
79
|
+
return this.getInstance().corsManager.middleware(options);
|
|
80
|
+
}
|
|
95
81
|
static rateLimit(preset) {
|
|
96
82
|
const instance = this.getInstance();
|
|
97
83
|
if (typeof preset === "string") {
|
|
@@ -104,170 +90,81 @@ class HiSecure {
|
|
|
104
90
|
}
|
|
105
91
|
return instance.rateLimitManager.middleware({ options: preset });
|
|
106
92
|
}
|
|
107
|
-
static cors(options) {
|
|
108
|
-
return this.getInstance().corsManager.middleware(options);
|
|
109
|
-
}
|
|
110
93
|
static json(options) {
|
|
111
94
|
const instance = this.getInstance();
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
// =====================================================
|
|
118
|
-
// UTILITY METHODS (Direct usage)
|
|
119
|
-
// =====================================================
|
|
120
|
-
static async hash(password) {
|
|
121
|
-
const instance = this.getInstance();
|
|
122
|
-
const result = await instance.hashManager.hash(password, { allowFallback: true });
|
|
123
|
-
return result.hash;
|
|
124
|
-
}
|
|
125
|
-
static async verify(password, hash) {
|
|
126
|
-
return this.getInstance().hashManager.verify(password, hash);
|
|
127
|
-
}
|
|
128
|
-
// =====================================================
|
|
129
|
-
// GLOBAL MIDDLEWARE (app.use())
|
|
130
|
-
// =====================================================
|
|
131
|
-
static middleware(options) {
|
|
132
|
-
const instance = this.getInstance();
|
|
133
|
-
// Handle preset strings
|
|
134
|
-
if (typeof options === "string") {
|
|
135
|
-
const presets = {
|
|
136
|
-
api: { cors: true, rateLimit: "relaxed", sanitize: true },
|
|
137
|
-
strict: { cors: true, rateLimit: "strict", sanitize: true, auth: true },
|
|
138
|
-
public: { cors: true, rateLimit: true, sanitize: false }
|
|
139
|
-
};
|
|
140
|
-
const presetOptions = presets[options];
|
|
141
|
-
if (presetOptions) {
|
|
142
|
-
return instance.createMiddlewareChain(presetOptions);
|
|
143
|
-
}
|
|
144
|
-
return instance.createMiddlewareChain({});
|
|
145
|
-
}
|
|
146
|
-
return instance.createMiddlewareChain(options || {});
|
|
95
|
+
return [
|
|
96
|
+
instance.jsonManager.middleware(options),
|
|
97
|
+
instance.jsonManager.urlencoded()
|
|
98
|
+
];
|
|
147
99
|
}
|
|
148
100
|
// =====================================================
|
|
149
|
-
// INTERNAL
|
|
101
|
+
// INTERNAL SETUP
|
|
150
102
|
// =====================================================
|
|
151
103
|
setupAdapters() {
|
|
152
104
|
index_js_1.logger.info("🧩 Setting up adapters...");
|
|
153
|
-
// Hashing
|
|
154
105
|
this.hashingPrimary = this.config.hashing.primary === "argon2"
|
|
155
106
|
? new ArgonAdapter_js_1.ArgonAdapter()
|
|
156
107
|
: new BcryptAdapter_js_1.BcryptAdapter(this.config.hashing.saltRounds);
|
|
157
108
|
this.hashingFallback = this.config.hashing.fallback === "bcrypt"
|
|
158
109
|
? new BcryptAdapter_js_1.BcryptAdapter(this.config.hashing.saltRounds)
|
|
159
110
|
: null;
|
|
160
|
-
// Rate limiting
|
|
161
111
|
this.rateLimiterPrimary = this.config.rateLimiter.useAdaptiveMode
|
|
162
112
|
? new RLFlexibleAdapter_js_1.RLFlexibleAdapter()
|
|
163
113
|
: new ExpressRLAdapter_js_1.ExpressRLAdapter();
|
|
164
114
|
this.rateLimiterFallback = new ExpressRLAdapter_js_1.ExpressRLAdapter();
|
|
165
|
-
// Validation
|
|
166
|
-
this.validatorPrimary = this.config.validation.mode === "zod"
|
|
167
|
-
? new ZodAdapter_js_1.ZodAdapter()
|
|
168
|
-
: new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter();
|
|
169
|
-
this.validatorFallback = this.config.validation.fallback === "express-validator"
|
|
170
|
-
? new ExpressValidatorAdapter_js_1.ExpressValidatorAdapter()
|
|
171
|
-
: null;
|
|
172
|
-
// Sanitization
|
|
173
|
-
this.sanitizerPrimary = new SanitizeHtmlAdapter_js_1.SanitizeHtmlAdapter(this.config.sanitizer);
|
|
174
|
-
this.sanitizerFallback = new XSSAdapter_js_1.XSSAdapter(this.config.sanitizer);
|
|
175
115
|
index_js_1.logger.info("✅ Adapters ready");
|
|
176
116
|
}
|
|
177
117
|
setupManagers() {
|
|
178
118
|
this.hashManager = new HashManager_js_1.HashManager(this.config.hashing, this.hashingPrimary, this.hashingFallback);
|
|
179
119
|
this.rateLimitManager = new RateLimitManager_js_1.RateLimitManager(this.config.rateLimiter, this.rateLimiterPrimary, this.rateLimiterFallback);
|
|
180
|
-
|
|
181
|
-
this.
|
|
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));
|
|
182
123
|
}
|
|
183
124
|
setupDynamicManagers() {
|
|
184
125
|
this.jsonManager = new JsonManager_js_1.JsonManager();
|
|
185
126
|
this.corsManager = new CorsManager_js_1.CorsManager();
|
|
186
|
-
// Auth manager (only if enabled)
|
|
187
127
|
if (this.config.auth.enabled) {
|
|
188
128
|
const jwtSecret = process.env.JWT_SECRET || this.config.auth.jwtSecret;
|
|
189
|
-
if (!jwtSecret)
|
|
190
|
-
throw new Error("JWT_SECRET
|
|
191
|
-
}
|
|
129
|
+
if (!jwtSecret)
|
|
130
|
+
throw new Error("JWT_SECRET is required when auth.enabled=true");
|
|
192
131
|
this.authManager = new AuthManager_js_1.AuthManager({
|
|
193
132
|
jwtSecret,
|
|
194
133
|
jwtExpiresIn: this.config.auth.jwtExpiresIn,
|
|
195
|
-
googleClientId:
|
|
196
|
-
// Removed algorithm - handled in AuthManager
|
|
134
|
+
googleClientId: this.config.auth.googleClientId
|
|
197
135
|
});
|
|
198
136
|
}
|
|
199
137
|
}
|
|
200
138
|
createMiddlewareChain(options) {
|
|
201
139
|
const chain = [];
|
|
202
|
-
// JSON parsing
|
|
203
140
|
chain.push(this.jsonManager.middleware(this.config.json));
|
|
204
141
|
chain.push(this.jsonManager.urlencoded(this.config.urlencoded));
|
|
205
|
-
// Security headers
|
|
206
142
|
if (this.config.enableHelmet)
|
|
207
143
|
chain.push((0, helmet_1.default)());
|
|
208
144
|
if (this.config.enableHPP)
|
|
209
145
|
chain.push((0, hpp_1.default)());
|
|
210
|
-
|
|
211
|
-
if (this.config.enableCompression && this.config.compression) {
|
|
146
|
+
if (this.config.enableCompression)
|
|
212
147
|
chain.push((0, compression_1.default)(this.config.compression));
|
|
213
|
-
}
|
|
214
|
-
else if (this.config.enableCompression) {
|
|
215
|
-
chain.push((0, compression_1.default)()); // Use defaults
|
|
216
|
-
}
|
|
217
|
-
// CORS
|
|
218
148
|
if (this.config.enableCORS || options.cors) {
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
chain.push(this.corsManager.middleware(corsOptions));
|
|
149
|
+
const opts = typeof options.cors === "object" ? options.cors : this.config.cors;
|
|
150
|
+
chain.push(this.corsManager.middleware(opts));
|
|
222
151
|
}
|
|
223
|
-
// Sanitization
|
|
224
152
|
if (this.config.enableSanitizer || options.sanitize) {
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
chain.push(this.sanitizerManager.middleware(sanitizeOptions));
|
|
153
|
+
const opts = typeof options.sanitize === "object" ? options.sanitize : undefined;
|
|
154
|
+
chain.push(this.sanitizerManager.middleware(opts));
|
|
228
155
|
}
|
|
229
|
-
// Rate limiting
|
|
230
156
|
if (this.config.enableRateLimiter || options.rateLimit) {
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
chain.push(this.rateLimitManager.middleware(rateLimitOpts));
|
|
157
|
+
const opts = typeof options.rateLimit === "object" ? { options: options.rateLimit } : {};
|
|
158
|
+
chain.push(this.rateLimitManager.middleware(opts));
|
|
234
159
|
}
|
|
235
|
-
// Authentication
|
|
236
160
|
if (options.auth && this.authManager) {
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
chain.push(this.authManager.protect(authOpts));
|
|
161
|
+
const opts = typeof options.auth === "object" ? options.auth : undefined;
|
|
162
|
+
chain.push(this.authManager.protect(opts));
|
|
240
163
|
}
|
|
241
|
-
// Error handler (always last)
|
|
242
164
|
chain.push(errorHandler_js_1.errorHandler);
|
|
243
165
|
return chain;
|
|
244
166
|
}
|
|
245
167
|
}
|
|
246
168
|
exports.HiSecure = HiSecure;
|
|
247
169
|
HiSecure.instance = null;
|
|
248
|
-
HiSecure.jwt = {
|
|
249
|
-
sign: (payload, options) => {
|
|
250
|
-
const instance = HiSecure.getInstance();
|
|
251
|
-
if (!instance.authManager) {
|
|
252
|
-
throw new Error("Auth not enabled");
|
|
253
|
-
}
|
|
254
|
-
return instance.authManager.sign(payload, options);
|
|
255
|
-
},
|
|
256
|
-
verify: (token) => {
|
|
257
|
-
const instance = HiSecure.getInstance();
|
|
258
|
-
if (!instance.authManager) {
|
|
259
|
-
throw new Error("Auth not enabled");
|
|
260
|
-
}
|
|
261
|
-
return instance.authManager.verify(token);
|
|
262
|
-
},
|
|
263
|
-
google: {
|
|
264
|
-
verifyIdToken: (idToken) => {
|
|
265
|
-
const instance = HiSecure.getInstance();
|
|
266
|
-
if (!instance.authManager) {
|
|
267
|
-
throw new Error("Auth not enabled");
|
|
268
|
-
}
|
|
269
|
-
return instance.authManager.verifyGoogleIdToken(idToken);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
170
|
//# sourceMappingURL=HiSecure.js.map
|