hi-secure 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/ArgonAdapter.d.ts +8 -0
- package/dist/adapters/ArgonAdapter.d.ts.map +1 -0
- package/dist/adapters/ArgonAdapter.js +45 -0
- package/dist/adapters/ArgonAdapter.js.map +1 -0
- package/dist/adapters/BcryptAdapter.d.ts +7 -0
- package/dist/adapters/BcryptAdapter.d.ts.map +1 -0
- package/dist/adapters/BcryptAdapter.js +48 -0
- package/dist/adapters/BcryptAdapter.js.map +1 -0
- package/dist/adapters/DomPurifyAdapter.d.ts +13 -0
- package/dist/adapters/DomPurifyAdapter.d.ts.map +1 -0
- package/dist/adapters/DomPurifyAdapter.js +61 -0
- package/dist/adapters/DomPurifyAdapter.js.map +1 -0
- package/dist/adapters/ExpressRLAdapter.d.ts +13 -0
- package/dist/adapters/ExpressRLAdapter.d.ts.map +1 -0
- package/dist/adapters/ExpressRLAdapter.js +68 -0
- package/dist/adapters/ExpressRLAdapter.js.map +1 -0
- package/dist/adapters/ExpressValidatorAdapter.d.ts +6 -0
- package/dist/adapters/ExpressValidatorAdapter.d.ts.map +1 -0
- package/dist/adapters/ExpressValidatorAdapter.js +78 -0
- package/dist/adapters/ExpressValidatorAdapter.js.map +1 -0
- package/dist/adapters/GoggleAdapter.d.ts +15 -0
- package/dist/adapters/GoggleAdapter.d.ts.map +1 -0
- package/dist/adapters/GoggleAdapter.js +91 -0
- package/dist/adapters/GoggleAdapter.js.map +1 -0
- package/dist/adapters/GoogleAdapter.d.ts +15 -0
- package/dist/adapters/GoogleAdapter.d.ts.map +1 -0
- package/dist/adapters/GoogleAdapter.js +159 -0
- package/dist/adapters/GoogleAdapter.js.map +1 -0
- package/dist/adapters/JWTAdapter.d.ts +28 -0
- package/dist/adapters/JWTAdapter.d.ts.map +1 -0
- package/dist/adapters/JWTAdapter.js +276 -0
- package/dist/adapters/JWTAdapter.js.map +1 -0
- package/dist/adapters/RLFlexibleAdapter.d.ts +11 -0
- package/dist/adapters/RLFlexibleAdapter.d.ts.map +1 -0
- package/dist/adapters/RLFlexibleAdapter.js +115 -0
- package/dist/adapters/RLFlexibleAdapter.js.map +1 -0
- package/dist/adapters/SanitizeHtmlAdapter.d.ts +12 -0
- package/dist/adapters/SanitizeHtmlAdapter.d.ts.map +1 -0
- package/dist/adapters/SanitizeHtmlAdapter.js +141 -0
- package/dist/adapters/SanitizeHtmlAdapter.js.map +1 -0
- package/dist/adapters/XSSAdapter.d.ts +33 -0
- package/dist/adapters/XSSAdapter.d.ts.map +1 -0
- package/dist/adapters/XSSAdapter.js +127 -0
- package/dist/adapters/XSSAdapter.js.map +1 -0
- package/dist/adapters/ZodAdapter.d.ts +7 -0
- package/dist/adapters/ZodAdapter.d.ts.map +1 -0
- package/dist/adapters/ZodAdapter.js +39 -0
- package/dist/adapters/ZodAdapter.js.map +1 -0
- package/dist/core/HiSecure.d.ts +62 -0
- package/dist/core/HiSecure.d.ts.map +1 -0
- package/dist/core/HiSecure.js +273 -0
- package/dist/core/HiSecure.js.map +1 -0
- package/dist/core/config.d.ts +3 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +53 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.d.ts +37 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +67 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/errors/AdapterError.d.ts +5 -0
- package/dist/core/errors/AdapterError.d.ts.map +1 -0
- package/dist/core/errors/AdapterError.js +15 -0
- package/dist/core/errors/AdapterError.js.map +1 -0
- package/dist/core/errors/HttpErrror.d.ts +17 -0
- package/dist/core/errors/HttpErrror.d.ts.map +1 -0
- package/dist/core/errors/HttpErrror.js +36 -0
- package/dist/core/errors/HttpErrror.js.map +1 -0
- package/dist/core/errors/SanitizerError.d.ts +5 -0
- package/dist/core/errors/SanitizerError.d.ts.map +1 -0
- package/dist/core/errors/SanitizerError.js +14 -0
- package/dist/core/errors/SanitizerError.js.map +1 -0
- package/dist/core/errors/SecurityError.d.ts +5 -0
- package/dist/core/errors/SecurityError.d.ts.map +1 -0
- package/dist/core/errors/SecurityError.js +14 -0
- package/dist/core/errors/SecurityError.js.map +1 -0
- package/dist/core/errors/ValidationError.d.ts +5 -0
- package/dist/core/errors/ValidationError.d.ts.map +1 -0
- package/dist/core/errors/ValidationError.js +14 -0
- package/dist/core/errors/ValidationError.js.map +1 -0
- package/dist/core/types/HiSecureConfig.d.ts +47 -0
- package/dist/core/types/HiSecureConfig.d.ts.map +1 -0
- package/dist/core/types/HiSecureConfig.js +3 -0
- package/dist/core/types/HiSecureConfig.js.map +1 -0
- package/dist/core/types/SecureOptions.d.ts +30 -0
- package/dist/core/types/SecureOptions.d.ts.map +1 -0
- package/dist/core/types/SecureOptions.js +4 -0
- package/dist/core/types/SecureOptions.js.map +1 -0
- package/dist/core/useSecure.d.ts +10 -0
- package/dist/core/useSecure.d.ts.map +1 -0
- package/dist/core/useSecure.js +85 -0
- package/dist/core/useSecure.js.map +1 -0
- package/dist/examples/e1.d.ts +1 -0
- package/dist/examples/e1.d.ts.map +1 -0
- package/dist/examples/e1.js +3 -0
- package/dist/examples/e1.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/index.d.ts +3 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +19 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/morganSetup.d.ts +2 -0
- package/dist/logging/morganSetup.d.ts.map +1 -0
- package/dist/logging/morganSetup.js +9 -0
- package/dist/logging/morganSetup.js.map +1 -0
- package/dist/logging/winstonSetup.d.ts +6 -0
- package/dist/logging/winstonSetup.d.ts.map +1 -0
- package/dist/logging/winstonSetup.js +22 -0
- package/dist/logging/winstonSetup.js.map +1 -0
- package/dist/managers/AuthManager.d.ts +23 -0
- package/dist/managers/AuthManager.d.ts.map +1 -0
- package/dist/managers/AuthManager.js +190 -0
- package/dist/managers/AuthManager.js.map +1 -0
- package/dist/managers/CorsManager.d.ts +9 -0
- package/dist/managers/CorsManager.d.ts.map +1 -0
- package/dist/managers/CorsManager.js +55 -0
- package/dist/managers/CorsManager.js.map +1 -0
- package/dist/managers/HashManager.d.ts +22 -0
- package/dist/managers/HashManager.d.ts.map +1 -0
- package/dist/managers/HashManager.js +319 -0
- package/dist/managers/HashManager.js.map +1 -0
- package/dist/managers/JsonManager.d.ts +6 -0
- package/dist/managers/JsonManager.d.ts.map +1 -0
- package/dist/managers/JsonManager.js +142 -0
- package/dist/managers/JsonManager.js.map +1 -0
- package/dist/managers/RateLimitManager.d.ts +16 -0
- package/dist/managers/RateLimitManager.d.ts.map +1 -0
- package/dist/managers/RateLimitManager.js +108 -0
- package/dist/managers/RateLimitManager.js.map +1 -0
- package/dist/managers/SanitizerManager.d.ts +18 -0
- package/dist/managers/SanitizerManager.d.ts.map +1 -0
- package/dist/managers/SanitizerManager.js +296 -0
- package/dist/managers/SanitizerManager.js.map +1 -0
- package/dist/managers/ValidatorManager.d.ts +13 -0
- package/dist/managers/ValidatorManager.d.ts.map +1 -0
- package/dist/managers/ValidatorManager.js +218 -0
- package/dist/managers/ValidatorManager.js.map +1 -0
- package/dist/middlewares/errorHandler.d.ts +3 -0
- package/dist/middlewares/errorHandler.d.ts.map +1 -0
- package/dist/middlewares/errorHandler.js +94 -0
- package/dist/middlewares/errorHandler.js.map +1 -0
- package/dist/middlewares/index.d.ts +3 -0
- package/dist/middlewares/index.d.ts.map +1 -0
- package/dist/middlewares/index.js +19 -0
- package/dist/middlewares/index.js.map +1 -0
- package/dist/middlewares/requestLogger.d.ts +2 -0
- package/dist/middlewares/requestLogger.d.ts.map +1 -0
- package/dist/middlewares/requestLogger.js +8 -0
- package/dist/middlewares/requestLogger.js.map +1 -0
- package/dist/test/t1.d.ts +1 -0
- package/dist/test/t1.d.ts.map +1 -0
- package/dist/test/t1.js +3 -0
- package/dist/test/t1.js.map +1 -0
- package/dist/utils/deepFreeze.d.ts +2 -0
- package/dist/utils/deepFreeze.d.ts.map +1 -0
- package/dist/utils/deepFreeze.js +69 -0
- package/dist/utils/deepFreeze.js.map +1 -0
- package/dist/utils/deepMerge.d.ts +5 -0
- package/dist/utils/deepMerge.d.ts.map +1 -0
- package/dist/utils/deepMerge.js +68 -0
- package/dist/utils/deepMerge.js.map +1 -0
- package/dist/utils/normalizeOptions.d.ts +38 -0
- package/dist/utils/normalizeOptions.d.ts.map +1 -0
- package/dist/utils/normalizeOptions.js +119 -0
- package/dist/utils/normalizeOptions.js.map +1 -0
- package/package.json +50 -0
- package/src/adapters/ArgonAdapter.ts +41 -0
- package/src/adapters/BcryptAdapter.ts +49 -0
- package/src/adapters/ExpressRLAdapter.ts +84 -0
- package/src/adapters/ExpressValidatorAdapter.ts +99 -0
- package/src/adapters/GoogleAdapter.ts +206 -0
- package/src/adapters/JWTAdapter.ts +346 -0
- package/src/adapters/RLFlexibleAdapter.ts +139 -0
- package/src/adapters/SanitizeHtmlAdapter.ts +162 -0
- package/src/adapters/XSSAdapter.ts +153 -0
- package/src/adapters/ZodAdapter.ts +91 -0
- package/src/core/HiSecure.ts +955 -0
- package/src/core/config.ts +156 -0
- package/src/core/constants.ts +73 -0
- package/src/core/errors/AdapterError.ts +14 -0
- package/src/core/errors/HttpErrror.ts +46 -0
- package/src/core/errors/SanitizerError.ts +13 -0
- package/src/core/errors/SecurityError.ts +13 -0
- package/src/core/errors/ValidationError.ts +13 -0
- package/src/core/types/HiSecureConfig.ts +62 -0
- package/src/core/types/SecureOptions.ts +61 -0
- package/src/core/useSecure.ts +111 -0
- package/src/examples/e1.ts +1 -0
- package/src/index.ts +17 -0
- package/src/logging/index.ts +2 -0
- package/src/logging/morganSetup.ts +3 -0
- package/src/logging/winstonSetup.ts +17 -0
- package/src/managers/AuthManager.ts +237 -0
- package/src/managers/CorsManager.ts +58 -0
- package/src/managers/HashManager.ts +390 -0
- package/src/managers/JsonManager.ts +149 -0
- package/src/managers/RateLimitManager.ts +368 -0
- package/src/managers/SanitizerManager.ts +359 -0
- package/src/managers/ValidatorManager.ts +269 -0
- package/src/middlewares/errorHandler.ts +265 -0
- package/src/middlewares/index.ts +2 -0
- package/src/middlewares/requestLogger.ts +5 -0
- package/src/test/t1.ts +1 -0
- package/src/utils/deepFreeze.ts +76 -0
- package/src/utils/deepMerge.ts +87 -0
- package/src/utils/normalizeOptions.ts +265 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import argon2 from "argon2";
|
|
2
|
+
export declare class ArgonAdapter {
|
|
3
|
+
private options;
|
|
4
|
+
constructor(options?: argon2.Options);
|
|
5
|
+
hash(value: string): Promise<string>;
|
|
6
|
+
verify(value: string, hashed: string): Promise<boolean>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=ArgonAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArgonAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ArgonAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAI5B,qBAAa,YAAY;IACrB,OAAO,CAAC,OAAO,CAA6B;gBAEhC,OAAO,CAAC,EAAE,MAAM,CAAC,OAAO;IAM9B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAapC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAchE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ArgonAdapter = void 0;
|
|
7
|
+
const argon2_1 = __importDefault(require("argon2"));
|
|
8
|
+
const AdapterError_1 = require("../core/errors/AdapterError");
|
|
9
|
+
const logging_1 = require("../logging");
|
|
10
|
+
class ArgonAdapter {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
if (options) {
|
|
13
|
+
this.options = options;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async hash(value) {
|
|
17
|
+
try {
|
|
18
|
+
return this.options
|
|
19
|
+
? await argon2_1.default.hash(value, this.options)
|
|
20
|
+
: await argon2_1.default.hash(value); // avoid passing undefined
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
logging_1.logger.error("❌ Argon2 hashing failed", {
|
|
24
|
+
error: err?.message || err
|
|
25
|
+
});
|
|
26
|
+
throw new AdapterError_1.AdapterError("Argon2 hashing failed.");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async verify(value, hashed) {
|
|
30
|
+
try {
|
|
31
|
+
if (!hashed || typeof hashed !== "string") {
|
|
32
|
+
throw new AdapterError_1.AdapterError("Invalid hash provided for verification.");
|
|
33
|
+
}
|
|
34
|
+
return await argon2_1.default.verify(hashed, value);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
logging_1.logger.error("❌ Argon2 verify failed", {
|
|
38
|
+
error: err?.message || err
|
|
39
|
+
});
|
|
40
|
+
throw new AdapterError_1.AdapterError("Argon2 verify failed.");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.ArgonAdapter = ArgonAdapter;
|
|
45
|
+
//# sourceMappingURL=ArgonAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArgonAdapter.js","sourceRoot":"","sources":["../../src/adapters/ArgonAdapter.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,8DAA2D;AAC3D,wCAAoC;AAEpC,MAAa,YAAY;IAGrB,YAAY,OAAwB;QAChC,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAC3B,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACpB,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,OAAO;gBACf,CAAC,CAAC,MAAM,gBAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC;gBACxC,CAAC,CAAC,MAAM,gBAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,0BAA0B;QAC9D,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,gBAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE;gBACpC,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG;aAC7B,CAAC,CAAC;YACH,MAAM,IAAI,2BAAY,CAAC,wBAAwB,CAAC,CAAC;QACrD,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,MAAc;QACtC,IAAI,CAAC;YACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,2BAAY,CAAC,yCAAyC,CAAC,CAAC;YACtE,CAAC;YAED,OAAO,MAAM,gBAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,gBAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;gBACnC,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG;aAC7B,CAAC,CAAC;YACH,MAAM,IAAI,2BAAY,CAAC,uBAAuB,CAAC,CAAC;QACpD,CAAC;IACL,CAAC;CACJ;AApCD,oCAoCC","sourcesContent":["import argon2 from \"argon2\";\r\nimport { AdapterError } from \"../core/errors/AdapterError\";\r\nimport { logger } from \"../logging\";\r\n\r\nexport class ArgonAdapter {\r\n private options: argon2.Options | undefined;\r\n\r\n constructor(options?: argon2.Options) {\r\n if (options) {\r\n this.options = options;\r\n }\r\n }\r\n\r\n async hash(value: string): Promise<string> {\r\n try {\r\n return this.options\r\n ? await argon2.hash(value, this.options)\r\n : await argon2.hash(value); // avoid passing undefined\r\n } catch (err: any) {\r\n logger.error(\"❌ Argon2 hashing failed\", {\r\n error: err?.message || err\r\n });\r\n throw new AdapterError(\"Argon2 hashing failed.\");\r\n }\r\n }\r\n\r\n async verify(value: string, hashed: string): Promise<boolean> {\r\n try {\r\n if (!hashed || typeof hashed !== \"string\") {\r\n throw new AdapterError(\"Invalid hash provided for verification.\");\r\n }\r\n\r\n return await argon2.verify(hashed, value);\r\n } catch (err: any) {\r\n logger.error(\"❌ Argon2 verify failed\", {\r\n error: err?.message || err\r\n });\r\n throw new AdapterError(\"Argon2 verify failed.\");\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BcryptAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/BcryptAdapter.ts"],"names":[],"mappings":"AAIA,qBAAa,aAAa;IACV,OAAO,CAAC,UAAU;gBAAV,UAAU,GAAE,MAAW;IAErC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBpC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAmBhE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BcryptAdapter = void 0;
|
|
7
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
8
|
+
const AdapterError_1 = require("../core/errors/AdapterError");
|
|
9
|
+
const logging_1 = require("../logging");
|
|
10
|
+
class BcryptAdapter {
|
|
11
|
+
constructor(saltRounds = 10) {
|
|
12
|
+
this.saltRounds = saltRounds;
|
|
13
|
+
}
|
|
14
|
+
async hash(value) {
|
|
15
|
+
try {
|
|
16
|
+
if (typeof value !== "string") {
|
|
17
|
+
throw new AdapterError_1.AdapterError("Value to hash must be a string.");
|
|
18
|
+
}
|
|
19
|
+
return await bcryptjs_1.default.hash(value, this.saltRounds);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
logging_1.logger.error("❌ Bcrypt hashing failed", {
|
|
23
|
+
error: err?.message || err,
|
|
24
|
+
saltRounds: this.saltRounds
|
|
25
|
+
});
|
|
26
|
+
throw new AdapterError_1.AdapterError("Bcrypt hashing failed.");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async verify(value, hashed) {
|
|
30
|
+
try {
|
|
31
|
+
if (typeof value !== "string") {
|
|
32
|
+
throw new AdapterError_1.AdapterError("Value to verify must be a string.");
|
|
33
|
+
}
|
|
34
|
+
if (!hashed || typeof hashed !== "string") {
|
|
35
|
+
throw new AdapterError_1.AdapterError("Invalid hashed string provided.");
|
|
36
|
+
}
|
|
37
|
+
return await bcryptjs_1.default.compare(value, hashed);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
logging_1.logger.error("❌ Bcrypt verify failed", {
|
|
41
|
+
error: err?.message || err
|
|
42
|
+
});
|
|
43
|
+
throw new AdapterError_1.AdapterError("Bcrypt verify failed.");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.BcryptAdapter = BcryptAdapter;
|
|
48
|
+
//# sourceMappingURL=BcryptAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BcryptAdapter.js","sourceRoot":"","sources":["../../src/adapters/BcryptAdapter.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA8B;AAC9B,8DAA2D;AAC3D,wCAAoC;AAEpC,MAAa,aAAa;IACtB,YAAoB,aAAqB,EAAE;QAAvB,eAAU,GAAV,UAAU,CAAa;IAAG,CAAC;IAE/C,KAAK,CAAC,IAAI,CAAC,KAAa;QACpB,IAAI,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5B,MAAM,IAAI,2BAAY,CAAC,iCAAiC,CAAC,CAAC;YAC9D,CAAC;YAED,OAAO,MAAM,kBAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,gBAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE;gBACpC,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG;gBAC1B,UAAU,EAAE,IAAI,CAAC,UAAU;aAC9B,CAAC,CAAC;YAEH,MAAM,IAAI,2BAAY,CAAC,wBAAwB,CAAC,CAAC;QACrD,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,MAAc;QACtC,IAAI,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5B,MAAM,IAAI,2BAAY,CAAC,mCAAmC,CAAC,CAAC;YAChE,CAAC;YAED,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,IAAI,2BAAY,CAAC,iCAAiC,CAAC,CAAC;YAC9D,CAAC;YAED,OAAO,MAAM,kBAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,gBAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;gBACnC,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG;aAC7B,CAAC,CAAC;YAEH,MAAM,IAAI,2BAAY,CAAC,uBAAuB,CAAC,CAAC;QACpD,CAAC;IACL,CAAC;CACJ;AAvCD,sCAuCC","sourcesContent":["import bcrypt from \"bcryptjs\";\r\nimport { AdapterError } from \"../core/errors/AdapterError\";\r\nimport { logger } from \"../logging\";\r\n\r\nexport class BcryptAdapter {\r\n constructor(private saltRounds: number = 10) {}\r\n\r\n async hash(value: string): Promise<string> {\r\n try {\r\n if (typeof value !== \"string\") {\r\n throw new AdapterError(\"Value to hash must be a string.\");\r\n }\r\n\r\n return await bcrypt.hash(value, this.saltRounds);\r\n } catch (err: any) {\r\n logger.error(\"❌ Bcrypt hashing failed\", {\r\n error: err?.message || err,\r\n saltRounds: this.saltRounds\r\n });\r\n\r\n throw new AdapterError(\"Bcrypt hashing failed.\");\r\n }\r\n }\r\n\r\n async verify(value: string, hashed: string): Promise<boolean> {\r\n try {\r\n if (typeof value !== \"string\") {\r\n throw new AdapterError(\"Value to verify must be a string.\");\r\n }\r\n\r\n if (!hashed || typeof hashed !== \"string\") {\r\n throw new AdapterError(\"Invalid hashed string provided.\");\r\n }\r\n\r\n return await bcrypt.compare(value, hashed);\r\n } catch (err: any) {\r\n logger.error(\"❌ Bcrypt verify failed\", {\r\n error: err?.message || err\r\n });\r\n\r\n throw new AdapterError(\"Bcrypt verify failed.\");\r\n }\r\n }\r\n}\r\n\r\n\r\n\r\n\r\n\r\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class DomPurifyAdapter {
|
|
2
|
+
private globalOptions;
|
|
3
|
+
constructor(options?: any);
|
|
4
|
+
/**
|
|
5
|
+
* Sanitize a string with global + dynamic merged options
|
|
6
|
+
*/
|
|
7
|
+
sanitize(input: string, dynamicOptions?: any): string;
|
|
8
|
+
/**
|
|
9
|
+
* Middleware wrapper WITH dynamic options
|
|
10
|
+
*/
|
|
11
|
+
middleware(dynamicOptions?: any): (req: any, _res: any, next: any) => void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=DomPurifyAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomPurifyAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/DomPurifyAdapter.ts"],"names":[],"mappings":"AAQA,qBAAa,gBAAgB;IACzB,OAAO,CAAC,aAAa,CAAM;gBAEf,OAAO,GAAE,GAAQ;IAI7B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,GAAG,GAAG,MAAM;IAmBrD;;OAEG;IACH,UAAU,CAAC,cAAc,CAAC,EAAE,GAAG,IACnB,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG;CA+B7C"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import createDOMPurify from "dompurify";
|
|
2
|
+
import { JSDOM } from "jsdom";
|
|
3
|
+
import { AdapterError } from "../core/errors/AdapterError";
|
|
4
|
+
import { logger } from "../logging";
|
|
5
|
+
const window = new JSDOM("").window;
|
|
6
|
+
const DOMPurify = createDOMPurify(window);
|
|
7
|
+
export class DomPurifyAdapter {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.globalOptions = options;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Sanitize a string with global + dynamic merged options
|
|
13
|
+
*/
|
|
14
|
+
sanitize(input, dynamicOptions) {
|
|
15
|
+
try {
|
|
16
|
+
if (typeof input !== "string")
|
|
17
|
+
return input;
|
|
18
|
+
const merged = { ...this.globalOptions, ...(dynamicOptions || {}) };
|
|
19
|
+
const clean = DOMPurify.sanitize(input, merged);
|
|
20
|
+
return clean.toString();
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
logger.error("❌ DomPurify sanitize failed", {
|
|
24
|
+
error: err?.message,
|
|
25
|
+
preview: input?.slice?.(0, 80)
|
|
26
|
+
});
|
|
27
|
+
throw new AdapterError("DomPurify sanitizer failed.");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Middleware wrapper WITH dynamic options
|
|
32
|
+
*/
|
|
33
|
+
middleware(dynamicOptions) {
|
|
34
|
+
return (req, _res, next) => {
|
|
35
|
+
try {
|
|
36
|
+
const body = req.body;
|
|
37
|
+
if (body && typeof body === "object") {
|
|
38
|
+
for (const key of Object.keys(body)) {
|
|
39
|
+
const val = body[key];
|
|
40
|
+
if (typeof val === "string") {
|
|
41
|
+
body[key] = this.sanitize(val, dynamicOptions);
|
|
42
|
+
}
|
|
43
|
+
if (Array.isArray(val)) {
|
|
44
|
+
body[key] = val.map((v) => typeof v === "string"
|
|
45
|
+
? this.sanitize(v, dynamicOptions)
|
|
46
|
+
: v);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
next();
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
logger.error("❌ DomPurify middleware failed", {
|
|
54
|
+
error: err?.message || err
|
|
55
|
+
});
|
|
56
|
+
next(err);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=DomPurifyAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomPurifyAdapter.js","sourceRoot":"","sources":["../../src/adapters/DomPurifyAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AACpC,MAAM,SAAS,GAAG,eAAe,CAAC,MAAa,CAAC,CAAC;AAEjD,MAAM,OAAO,gBAAgB;IAGzB,YAAY,UAAe,EAAE;QACzB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,KAAa,EAAE,cAAoB;QACxC,IAAI,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,OAAO,KAAY,CAAC;YAEnD,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,EAAE,CAAC;YAEpE,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAEhD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QAE5B,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE;gBACxC,KAAK,EAAE,GAAG,EAAE,OAAO;gBACnB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;aACjC,CAAC,CAAC;YACH,MAAM,IAAI,YAAY,CAAC,6BAA6B,CAAC,CAAC;QAC1D,CAAC;IACL,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,cAAoB;QAC3B,OAAO,CAAC,GAAQ,EAAE,IAAS,EAAE,IAAS,EAAE,EAAE;YACtC,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBAEtB,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACnC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;wBAEtB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;4BAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;wBACnD,CAAC;wBAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;4BACrB,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACtB,OAAO,CAAC,KAAK,QAAQ;gCACjB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,cAAc,CAAC;gCAClC,CAAC,CAAC,CAAC,CACV,CAAC;wBACN,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,IAAI,EAAE,CAAC;YACX,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE;oBAC1C,KAAK,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG;iBAC7B,CAAC,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;QACL,CAAC,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface RateLimitOptions {
|
|
2
|
+
windowMs?: number;
|
|
3
|
+
max?: number;
|
|
4
|
+
message?: any;
|
|
5
|
+
skipFailedRequests?: boolean;
|
|
6
|
+
standardHeaders?: boolean;
|
|
7
|
+
legacyHeaders?: boolean;
|
|
8
|
+
[key: string]: any;
|
|
9
|
+
}
|
|
10
|
+
export declare class ExpressRLAdapter {
|
|
11
|
+
getMiddleware(options?: RateLimitOptions): import("express-rate-limit").RateLimitRequestHandler;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ExpressRLAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpressRLAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ExpressRLAdapter.ts"],"names":[],"mappings":"AA2CA,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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import rateLimit from "express-rate-limit";
|
|
3
|
+
// import { logger } from "../logging";
|
|
4
|
+
// import { AdapterError } from "../core/errors/AdapterError";
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
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
|
+
// src/adapters/ExpressRLAdapter.ts - IMPROVED
|
|
37
|
+
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
38
|
+
const index_js_1 = require("../logging/index.js");
|
|
39
|
+
const AdapterError_js_1 = require("../core/errors/AdapterError.js");
|
|
40
|
+
class ExpressRLAdapter {
|
|
41
|
+
getMiddleware(options = {}) {
|
|
42
|
+
try {
|
|
43
|
+
const defaultOptions = {
|
|
44
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
45
|
+
max: 100,
|
|
46
|
+
message: { error: "Too many requests" },
|
|
47
|
+
standardHeaders: true,
|
|
48
|
+
legacyHeaders: false,
|
|
49
|
+
skipFailedRequests: false
|
|
50
|
+
};
|
|
51
|
+
const finalOptions = { ...defaultOptions, ...options };
|
|
52
|
+
const limiter = (0, express_rate_limit_1.default)(finalOptions);
|
|
53
|
+
index_js_1.logger.debug("📌 Express rate limiter configured", {
|
|
54
|
+
windowMs: finalOptions.windowMs,
|
|
55
|
+
max: finalOptions.max
|
|
56
|
+
});
|
|
57
|
+
return limiter;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
index_js_1.logger.error("❌ ExpressRLAdapter: failed to create limiter", {
|
|
61
|
+
error: err?.message || err
|
|
62
|
+
});
|
|
63
|
+
throw new AdapterError_js_1.AdapterError("Express rate limiter creation failed.");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.ExpressRLAdapter = ExpressRLAdapter;
|
|
68
|
+
//# sourceMappingURL=ExpressRLAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpressRLAdapter.js","sourceRoot":"","sources":["../../src/adapters/ExpressRLAdapter.ts"],"names":[],"mappings":";AAAA,8CAA8C;AAC9C,uCAAuC;AACvC,8DAA8D;;;;;;AAE9D,kCAAkC;AAElC,UAAU;AACV,0DAA0D;AAC1D,UAAU;AACV,+BAA+B;AAC/B,6BAA6B;AAC7B,wBAAwB;AACxB,yBAAyB;AACzB,gBAAgB;AAEhB,gBAAgB;AAChB,0CAA0C;AAC1C,2EAA2E;AAC3E,2CAA2C;AAC3C,8EAA8E;AAC9E,yCAAyC;AACzC,wCAAwC;AACxC,kBAAkB;AAElB,8BAA8B;AAE9B,+BAA+B;AAC/B,6EAA6E;AAC7E,6CAA6C;AAC7C,kBAAkB;AAClB,+EAA+E;AAC/E,YAAY;AACZ,QAAQ;AACR,IAAI;AAKJ,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":["// import rateLimit from \"express-rate-limit\";\r\n// import { logger } from \"../logging\";\r\n// import { AdapterError } from \"../core/errors/AdapterError\";\r\n\r\n// export class ExpressRLAdapter {\r\n\r\n// /**\r\n// * Create express rate-limit middleware dynamically\r\n// */\r\n// getMiddleware(options: {\r\n// windowMs?: number;\r\n// max?: number;\r\n// message?: any;\r\n// } = {}) {\r\n\r\n// try {\r\n// const limiter = rateLimit({\r\n// windowMs: options.windowMs ?? 15 * 60 * 1000, // default\r\n// max: options.max ?? 100,\r\n// message: options.message ?? { error: \"Too many requests\" },\r\n// standardHeaders: true,\r\n// legacyHeaders: false,\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// }\r\n\r\n\r\n\r\n\r\n// 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}"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpressValidatorAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ExpressValidatorAdapter.ts"],"names":[],"mappings":"AAyDA,qBAAa,uBAAuB;IAChC,OAAO,CAAC,YAAY,CAAC,CAAQ;gBAEjB,YAAY,CAAC,EAAE,GAAG,EAAE;IAIhC,QAAQ,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,kBAIT,GAAG,OAAO,GAAG,QAAQ,GAAG;CA8BhD"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { validationResult } from "express-validator";
|
|
3
|
+
// import { ValidationError } from "../core/errors/ValidationError";
|
|
4
|
+
// import { logger } from "../logging";
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ExpressValidatorAdapter = void 0;
|
|
7
|
+
// export class ExpressValidatorAdapter {
|
|
8
|
+
// private globalSchema?: any[];
|
|
9
|
+
// constructor(globalSchema?: any[]) {
|
|
10
|
+
// this.globalSchema = globalSchema as any;;
|
|
11
|
+
// }
|
|
12
|
+
// /**
|
|
13
|
+
// * Dynamic schema override
|
|
14
|
+
// */
|
|
15
|
+
// validate(dynamicSchema?: any[]) {
|
|
16
|
+
// const schema = dynamicSchema || this.globalSchema;
|
|
17
|
+
// if (!schema || !Array.isArray(schema)) {
|
|
18
|
+
// return (req: any, res: any, next: any) => next();
|
|
19
|
+
// }
|
|
20
|
+
// return [
|
|
21
|
+
// ...schema,
|
|
22
|
+
// (req: any, res: any, next: any) => {
|
|
23
|
+
// const errors = validationResult(req);
|
|
24
|
+
// if (!errors.isEmpty()) {
|
|
25
|
+
// const formatted = errors.array().map(err => ({
|
|
26
|
+
// message: err.msg,
|
|
27
|
+
// }));
|
|
28
|
+
// logger.warn("⚠ express-validator failed", {
|
|
29
|
+
// path: req.path,
|
|
30
|
+
// method: req.method,
|
|
31
|
+
// errors: formatted,
|
|
32
|
+
// preview: JSON.stringify(req.body).slice(0, 200)
|
|
33
|
+
// });
|
|
34
|
+
// return next(new ValidationError("Validation failed."));
|
|
35
|
+
// }
|
|
36
|
+
// next();
|
|
37
|
+
// }
|
|
38
|
+
// ];
|
|
39
|
+
// }
|
|
40
|
+
// }
|
|
41
|
+
// src/adapters/ExpressValidatorAdapter.ts - FIXED
|
|
42
|
+
const express_validator_1 = require("express-validator");
|
|
43
|
+
const ValidationError_js_1 = require("../core/errors/ValidationError.js"); // ✅ Add .js
|
|
44
|
+
const index_js_1 = require("../logging/index.js");
|
|
45
|
+
class ExpressValidatorAdapter {
|
|
46
|
+
constructor(globalSchema) {
|
|
47
|
+
this.globalSchema = globalSchema;
|
|
48
|
+
}
|
|
49
|
+
validate(dynamicSchema) {
|
|
50
|
+
const schema = dynamicSchema || this.globalSchema;
|
|
51
|
+
if (!schema || !Array.isArray(schema)) {
|
|
52
|
+
return (req, res, next) => next();
|
|
53
|
+
}
|
|
54
|
+
return [
|
|
55
|
+
...schema,
|
|
56
|
+
(req, res, next) => {
|
|
57
|
+
const errors = (0, express_validator_1.validationResult)(req);
|
|
58
|
+
if (!errors.isEmpty()) {
|
|
59
|
+
const formatted = errors.array().map(err => ({
|
|
60
|
+
message: err.msg,
|
|
61
|
+
// param: err.param ,
|
|
62
|
+
// location: err.location
|
|
63
|
+
}));
|
|
64
|
+
index_js_1.logger.warn("⚠ express-validator failed", {
|
|
65
|
+
path: req.path,
|
|
66
|
+
method: req.method,
|
|
67
|
+
errors: formatted,
|
|
68
|
+
preview: JSON.stringify(req.body).slice(0, 200)
|
|
69
|
+
});
|
|
70
|
+
return next(new ValidationError_js_1.ValidationError("Validation failed.", formatted));
|
|
71
|
+
}
|
|
72
|
+
next();
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.ExpressValidatorAdapter = ExpressValidatorAdapter;
|
|
78
|
+
//# sourceMappingURL=ExpressValidatorAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpressValidatorAdapter.js","sourceRoot":"","sources":["../../src/adapters/ExpressValidatorAdapter.ts"],"names":[],"mappings":";AAAA,wDAAwD;AACxD,oEAAoE;AACpE,uCAAuC;;;AAEvC,yCAAyC;AACzC,oCAAoC;AAEpC,0CAA0C;AAC1C,oDAAoD;AACpD,QAAQ;AAER,UAAU;AACV,iCAAiC;AACjC,UAAU;AACV,wCAAwC;AACxC,6DAA6D;AAE7D,mDAAmD;AACnD,gEAAgE;AAChE,YAAY;AAEZ,mBAAmB;AACnB,yBAAyB;AAEzB,mDAAmD;AACnD,wDAAwD;AAExD,2CAA2C;AAC3C,qEAAqE;AACrE,4CAA4C;AAC5C,2BAA2B;AAE3B,kEAAkE;AAClE,0CAA0C;AAC1C,8CAA8C;AAC9C,6CAA6C;AAC7C,0EAA0E;AAC1E,0BAA0B;AAE1B,8EAA8E;AAC9E,oBAAoB;AAEpB,0BAA0B;AAC1B,gBAAgB;AAChB,aAAa;AACb,QAAQ;AACR,IAAI;AAMJ,kDAAkD;AAClD,yDAAqD;AACrD,0EAAoE,CAAC,YAAY;AACjF,kDAA6C;AAE7C,MAAa,uBAAuB;IAGhC,YAAY,YAAoB;QAC5B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAED,QAAQ,CAAC,aAAqB;QAC1B,MAAM,MAAM,GAAG,aAAa,IAAI,IAAI,CAAC,YAAY,CAAC;QAElD,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QACrD,CAAC;QAED,OAAO;YACH,GAAG,MAAM;YAET,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAS,EAAE,EAAE;gBAC9B,MAAM,MAAM,GAAG,IAAA,oCAAgB,EAAC,GAAG,CAAC,CAAC;gBAErC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;oBACpB,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACzC,OAAO,EAAE,GAAG,CAAC,GAAG;wBAChB,qBAAqB;wBACrB,yBAAyB;qBAC5B,CAAC,CAAC,CAAC;oBAEJ,iBAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;wBACtC,IAAI,EAAE,GAAG,CAAC,IAAI;wBACd,MAAM,EAAE,GAAG,CAAC,MAAM;wBAClB,MAAM,EAAE,SAAS;wBACjB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;qBAClD,CAAC,CAAC;oBAEH,OAAO,IAAI,CAAC,IAAI,oCAAe,CAAC,oBAAoB,EAAE,SAAgB,CAAC,CAAC,CAAC;gBAC7E,CAAC;gBAED,IAAI,EAAE,CAAC;YACX,CAAC;SACJ,CAAC;IACN,CAAC;CACJ;AAzCD,0DAyCC","sourcesContent":["// import { validationResult } from \"express-validator\";\r\n// import { ValidationError } from \"../core/errors/ValidationError\";\r\n// import { logger } from \"../logging\";\r\n\r\n// export class ExpressValidatorAdapter {\r\n// private globalSchema?: any[];\r\n\r\n// constructor(globalSchema?: any[]) {\r\n// this.globalSchema = globalSchema as any;;\r\n// }\r\n\r\n// /**\r\n// * Dynamic schema override\r\n// */\r\n// validate(dynamicSchema?: any[]) {\r\n// const schema = dynamicSchema || this.globalSchema;\r\n\r\n// if (!schema || !Array.isArray(schema)) {\r\n// return (req: any, res: any, next: any) => next();\r\n// }\r\n\r\n// return [\r\n// ...schema,\r\n\r\n// (req: any, res: any, next: any) => {\r\n// const errors = validationResult(req);\r\n\r\n// if (!errors.isEmpty()) {\r\n// const formatted = errors.array().map(err => ({\r\n// message: err.msg,\r\n// }));\r\n\r\n// logger.warn(\"⚠ express-validator failed\", {\r\n// path: req.path,\r\n// method: req.method,\r\n// errors: formatted,\r\n// preview: JSON.stringify(req.body).slice(0, 200)\r\n// });\r\n\r\n// return next(new ValidationError(\"Validation failed.\"));\r\n// }\r\n\r\n// next();\r\n// }\r\n// ];\r\n// }\r\n// }\r\n\r\n\r\n\r\n\r\n\r\n// src/adapters/ExpressValidatorAdapter.ts - FIXED\r\nimport { validationResult } from \"express-validator\";\r\nimport { ValidationError } from \"../core/errors/ValidationError.js\"; // ✅ Add .js\r\nimport { logger } from \"../logging/index.js\";\r\n\r\nexport class ExpressValidatorAdapter {\r\n private globalSchema?: any[];\r\n\r\n constructor(globalSchema?: any[]) {\r\n this.globalSchema = globalSchema;\r\n }\r\n\r\n validate(dynamicSchema?: any[]) {\r\n const schema = dynamicSchema || this.globalSchema;\r\n\r\n if (!schema || !Array.isArray(schema)) {\r\n return (req: any, res: any, next: any) => next();\r\n }\r\n\r\n return [\r\n ...schema,\r\n\r\n (req: any, res: any, next: any) => {\r\n const errors = validationResult(req);\r\n\r\n if (!errors.isEmpty()) {\r\n const formatted = errors.array().map(err => ({\r\n message: err.msg,\r\n // param: err.param ,\r\n // location: err.location\r\n }));\r\n\r\n logger.warn(\"⚠ express-validator failed\", {\r\n path: req.path,\r\n method: req.method,\r\n errors: formatted,\r\n preview: JSON.stringify(req.body).slice(0, 200)\r\n });\r\n\r\n return next(new ValidationError(\"Validation failed.\", formatted as any));\r\n }\r\n\r\n next();\r\n }\r\n ];\r\n }\r\n}"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface GoogleTokenPayload {
|
|
2
|
+
sub: string;
|
|
3
|
+
email: string;
|
|
4
|
+
email_verified: boolean;
|
|
5
|
+
name?: string;
|
|
6
|
+
picture?: string;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
9
|
+
export declare class GoogleAdapter {
|
|
10
|
+
private client;
|
|
11
|
+
private clientId?;
|
|
12
|
+
constructor(clientId?: string);
|
|
13
|
+
verifyIdToken(idToken: string): Promise<GoogleTokenPayload>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=GoggleAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoggleAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/GoggleAdapter.ts"],"names":[],"mappings":"AAwDA,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;CA6CpE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// import { OAuth2Client, LoginTicket } from "google-auth-library";
|
|
2
|
+
// import { AdapterError } from "../core/errors/AdapterError";
|
|
3
|
+
// import { logWarn, logError } from "../logging";
|
|
4
|
+
// export class GoogleAdapter {
|
|
5
|
+
// private client: OAuth2Client;
|
|
6
|
+
// private clientId?: string;
|
|
7
|
+
// constructor(clientId?: string) {
|
|
8
|
+
// this.client = new OAuth2Client(clientId);
|
|
9
|
+
// this.clientId = clientId as any;
|
|
10
|
+
// }
|
|
11
|
+
// async verifyIdToken(idToken: string) {
|
|
12
|
+
// try {
|
|
13
|
+
// const options: {
|
|
14
|
+
// idToken: string;
|
|
15
|
+
// audience?: string | string[];
|
|
16
|
+
// } = { idToken };
|
|
17
|
+
// // ADD ONLY IF DEFINED → FIXES TS ERROR
|
|
18
|
+
// if (this.clientId !== undefined) {
|
|
19
|
+
// options.audience = this.clientId;
|
|
20
|
+
// }
|
|
21
|
+
// const ticket: LoginTicket = await this.client.verifyIdToken(options);
|
|
22
|
+
// const payload = ticket.getPayload();
|
|
23
|
+
// if (!payload) {
|
|
24
|
+
// logWarn("GoogleAdapter: Empty payload");
|
|
25
|
+
// throw new AdapterError("Invalid Google ID token payload.");
|
|
26
|
+
// }
|
|
27
|
+
// return {
|
|
28
|
+
// sub: payload.sub,
|
|
29
|
+
// email: payload.email,
|
|
30
|
+
// email_verified: payload.email_verified,
|
|
31
|
+
// name: payload.name,
|
|
32
|
+
// picture: payload.picture,
|
|
33
|
+
// };
|
|
34
|
+
// } catch (err: any) {
|
|
35
|
+
// logError("GoogleAdapter.verifyIdToken failed", { error: err?.message });
|
|
36
|
+
// throw new AdapterError(err?.message || "Google token verification failed");
|
|
37
|
+
// }
|
|
38
|
+
// }
|
|
39
|
+
// }
|
|
40
|
+
// src/adapters/GoogleAdapter.ts - IMPROVED
|
|
41
|
+
import { OAuth2Client } from "google-auth-library";
|
|
42
|
+
import { AdapterError } from "../core/errors/AdapterError.js";
|
|
43
|
+
import { logWarn, logError } from "../logging/index.js";
|
|
44
|
+
export class GoogleAdapter {
|
|
45
|
+
constructor(clientId) {
|
|
46
|
+
if (clientId && clientId.trim().length === 0) {
|
|
47
|
+
throw new AdapterError("Google clientId cannot be empty string");
|
|
48
|
+
}
|
|
49
|
+
this.client = new OAuth2Client(clientId);
|
|
50
|
+
this.clientId = clientId;
|
|
51
|
+
}
|
|
52
|
+
async verifyIdToken(idToken) {
|
|
53
|
+
try {
|
|
54
|
+
if (!idToken || typeof idToken !== 'string') {
|
|
55
|
+
throw new AdapterError("Invalid ID token provided");
|
|
56
|
+
}
|
|
57
|
+
const options = {
|
|
58
|
+
idToken
|
|
59
|
+
};
|
|
60
|
+
// Add audience only if clientId is provided and not empty
|
|
61
|
+
if (this.clientId && this.clientId.trim().length > 0) {
|
|
62
|
+
options.audience = this.clientId;
|
|
63
|
+
}
|
|
64
|
+
const ticket = await this.client.verifyIdToken(options);
|
|
65
|
+
const payload = ticket.getPayload();
|
|
66
|
+
if (!payload) {
|
|
67
|
+
logWarn("GoogleAdapter: Empty payload");
|
|
68
|
+
throw new AdapterError("Invalid Google ID token payload.");
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
sub: payload.sub,
|
|
72
|
+
email: payload.email || '',
|
|
73
|
+
email_verified: payload.email_verified || false,
|
|
74
|
+
name: payload.name,
|
|
75
|
+
picture: payload.picture,
|
|
76
|
+
...payload
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
logError("GoogleAdapter.verifyIdToken failed", {
|
|
81
|
+
error: err?.message,
|
|
82
|
+
hasClientId: !!this.clientId
|
|
83
|
+
});
|
|
84
|
+
if (err.message?.includes('audience')) {
|
|
85
|
+
throw new AdapterError("Invalid Google client ID configured.");
|
|
86
|
+
}
|
|
87
|
+
throw new AdapterError(err?.message || "Google token verification failed");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=GoggleAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoggleAdapter.js","sourceRoot":"","sources":["../../src/adapters/GoggleAdapter.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,8DAA8D;AAC9D,kDAAkD;AAElD,+BAA+B;AAC/B,oCAAoC;AACpC,iCAAiC;AAEjC,uCAAuC;AACvC,oDAAoD;AACpD,2CAA2C;AAC3C,QAAQ;AAER,6CAA6C;AAC7C,gBAAgB;AAChB,+BAA+B;AAC/B,mCAAmC;AACnC,gDAAgD;AAChD,+BAA+B;AAE/B,sDAAsD;AACtD,iDAAiD;AACjD,oDAAoD;AACpD,gBAAgB;AAEhB,oFAAoF;AAEpF,mDAAmD;AACnD,8BAA8B;AAC9B,2DAA2D;AAC3D,8EAA8E;AAC9E,gBAAgB;AAEhB,uBAAuB;AACvB,oCAAoC;AACpC,wCAAwC;AACxC,0DAA0D;AAC1D,sCAAsC;AACtC,4CAA4C;AAC5C,iBAAiB;AAEjB,+BAA+B;AAC/B,uFAAuF;AACvF,0FAA0F;AAC1F,YAAY;AACZ,QAAQ;AACR,IAAI;AAKJ,2CAA2C;AAC3C,OAAO,EAAE,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAWxD,MAAM,OAAO,aAAa;IAItB,YAAY,QAAiB;QACzB,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,YAAY,CAAC,wCAAwC,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,YAAY,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,YAAY,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,OAAO,CAAC,8BAA8B,CAAC,CAAC;gBACxC,MAAM,IAAI,YAAY,CAAC,kCAAkC,CAAC,CAAC;YAC/D,CAAC;YAED,OAAO;gBACH,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;gBACxB,GAAG,OAAO;aACb,CAAC;QAEN,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,QAAQ,CAAC,oCAAoC,EAAE;gBAC3C,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,YAAY,CAAC,sCAAsC,CAAC,CAAC;YACnE,CAAC;YAED,MAAM,IAAI,YAAY,CAAC,GAAG,EAAE,OAAO,IAAI,kCAAkC,CAAC,CAAC;QAC/E,CAAC;IACL,CAAC;CACJ","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\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 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}"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface GoogleTokenPayload {
|
|
2
|
+
sub: string;
|
|
3
|
+
email: string;
|
|
4
|
+
email_verified: boolean;
|
|
5
|
+
name?: string;
|
|
6
|
+
picture?: string;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
9
|
+
export declare class GoogleAdapter {
|
|
10
|
+
private client;
|
|
11
|
+
private clientId?;
|
|
12
|
+
constructor(clientId?: string);
|
|
13
|
+
verifyIdToken(idToken: string): Promise<GoogleTokenPayload>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=GoogleAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoogleAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/GoogleAdapter.ts"],"names":[],"mappings":"AAoIA,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"}
|