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,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// // import { OAuth2Client, LoginTicket } from "google-auth-library";
|
|
3
|
+
// // import { AdapterError } from "../core/errors/AdapterError";
|
|
4
|
+
// // import { logWarn, logError } from "../logging";
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GoogleAdapter = void 0;
|
|
7
|
+
// // export class GoogleAdapter {
|
|
8
|
+
// // private client: OAuth2Client;
|
|
9
|
+
// // private clientId?: string;
|
|
10
|
+
// // constructor(clientId?: string) {
|
|
11
|
+
// // this.client = new OAuth2Client(clientId);
|
|
12
|
+
// // this.clientId = clientId as any;
|
|
13
|
+
// // }
|
|
14
|
+
// // async verifyIdToken(idToken: string) {
|
|
15
|
+
// // try {
|
|
16
|
+
// // const options: {
|
|
17
|
+
// // idToken: string;
|
|
18
|
+
// // audience?: string | string[];
|
|
19
|
+
// // } = { idToken };
|
|
20
|
+
// // // ADD ONLY IF DEFINED → FIXES TS ERROR
|
|
21
|
+
// // if (this.clientId !== undefined) {
|
|
22
|
+
// // options.audience = this.clientId;
|
|
23
|
+
// // }
|
|
24
|
+
// // const ticket: LoginTicket = await this.client.verifyIdToken(options);
|
|
25
|
+
// // const payload = ticket.getPayload();
|
|
26
|
+
// // if (!payload) {
|
|
27
|
+
// // logWarn("GoogleAdapter: Empty payload");
|
|
28
|
+
// // throw new AdapterError("Invalid Google ID token payload.");
|
|
29
|
+
// // }
|
|
30
|
+
// // return {
|
|
31
|
+
// // sub: payload.sub,
|
|
32
|
+
// // email: payload.email,
|
|
33
|
+
// // email_verified: payload.email_verified,
|
|
34
|
+
// // name: payload.name,
|
|
35
|
+
// // picture: payload.picture,
|
|
36
|
+
// // };
|
|
37
|
+
// // } catch (err: any) {
|
|
38
|
+
// // logError("GoogleAdapter.verifyIdToken failed", { error: err?.message });
|
|
39
|
+
// // throw new AdapterError(err?.message || "Google token verification failed");
|
|
40
|
+
// // }
|
|
41
|
+
// // }
|
|
42
|
+
// // }
|
|
43
|
+
// // src/adapters/GoogleAdapter.ts - IMPROVED
|
|
44
|
+
// import { OAuth2Client, LoginTicket } from "google-auth-library";
|
|
45
|
+
// import { AdapterError } from "../core/errors/AdapterError.js";
|
|
46
|
+
// import { logWarn, logError } from "../logging/index.js";
|
|
47
|
+
// export interface GoogleTokenPayload {
|
|
48
|
+
// sub: string;
|
|
49
|
+
// email: string;
|
|
50
|
+
// email_verified: boolean;
|
|
51
|
+
// name?: string;
|
|
52
|
+
// picture?: string;
|
|
53
|
+
// [key: string]: any;
|
|
54
|
+
// }
|
|
55
|
+
// export class GoogleAdapter {
|
|
56
|
+
// private client: OAuth2Client;
|
|
57
|
+
// private clientId?: string;
|
|
58
|
+
// constructor(clientId?: string) {
|
|
59
|
+
// if (clientId && clientId.trim().length === 0) {
|
|
60
|
+
// throw new AdapterError("Google clientId cannot be empty string");
|
|
61
|
+
// }
|
|
62
|
+
// this.client = new OAuth2Client(clientId);
|
|
63
|
+
// this.clientId = clientId;
|
|
64
|
+
// }
|
|
65
|
+
// async verifyIdToken(idToken: string): Promise<GoogleTokenPayload> {
|
|
66
|
+
// try {
|
|
67
|
+
// if (!idToken || typeof idToken !== 'string') {
|
|
68
|
+
// throw new AdapterError("Invalid ID token provided");
|
|
69
|
+
// }
|
|
70
|
+
// const options: { idToken: string; audience?: string | string[] } = {
|
|
71
|
+
// idToken
|
|
72
|
+
// };
|
|
73
|
+
// // Add audience only if clientId is provided and not empty
|
|
74
|
+
// if (this.clientId && this.clientId.trim().length > 0) {
|
|
75
|
+
// options.audience = this.clientId;
|
|
76
|
+
// }
|
|
77
|
+
// const ticket: LoginTicket = await this.client.verifyIdToken(options);
|
|
78
|
+
// const payload = ticket.getPayload();
|
|
79
|
+
// if (!payload) {
|
|
80
|
+
// logWarn("GoogleAdapter: Empty payload");
|
|
81
|
+
// throw new AdapterError("Invalid Google ID token payload.");
|
|
82
|
+
// }
|
|
83
|
+
// return {
|
|
84
|
+
// sub: payload.sub,
|
|
85
|
+
// email: payload.email || '',
|
|
86
|
+
// email_verified: payload.email_verified || false,
|
|
87
|
+
// name: payload.name,
|
|
88
|
+
// picture: payload.picture,
|
|
89
|
+
// ...payload
|
|
90
|
+
// };
|
|
91
|
+
// } catch (err: any) {
|
|
92
|
+
// logError("GoogleAdapter.verifyIdToken failed", {
|
|
93
|
+
// error: err?.message,
|
|
94
|
+
// hasClientId: !!this.clientId
|
|
95
|
+
// });
|
|
96
|
+
// if (err.message?.includes('audience')) {
|
|
97
|
+
// throw new AdapterError("Invalid Google client ID configured.");
|
|
98
|
+
// }
|
|
99
|
+
// throw new AdapterError(err?.message || "Google token verification failed");
|
|
100
|
+
// }
|
|
101
|
+
// }
|
|
102
|
+
// }
|
|
103
|
+
// src/adapters/GoogleAdapter.ts - FIXED
|
|
104
|
+
const google_auth_library_1 = require("google-auth-library");
|
|
105
|
+
const AdapterError_js_1 = require("../core/errors/AdapterError.js");
|
|
106
|
+
const index_js_1 = require("../logging/index.js");
|
|
107
|
+
class GoogleAdapter {
|
|
108
|
+
constructor(clientId) {
|
|
109
|
+
if (clientId && clientId.trim().length === 0) {
|
|
110
|
+
throw new AdapterError_js_1.AdapterError("Google clientId cannot be empty string");
|
|
111
|
+
}
|
|
112
|
+
this.client = new google_auth_library_1.OAuth2Client(clientId);
|
|
113
|
+
this.clientId = clientId;
|
|
114
|
+
}
|
|
115
|
+
async verifyIdToken(idToken) {
|
|
116
|
+
try {
|
|
117
|
+
if (!idToken || typeof idToken !== 'string') {
|
|
118
|
+
throw new AdapterError_js_1.AdapterError("Invalid ID token provided");
|
|
119
|
+
}
|
|
120
|
+
const options = {
|
|
121
|
+
idToken
|
|
122
|
+
};
|
|
123
|
+
// Add audience only if clientId is provided and not empty
|
|
124
|
+
if (this.clientId && this.clientId.trim().length > 0) {
|
|
125
|
+
options.audience = this.clientId;
|
|
126
|
+
}
|
|
127
|
+
const ticket = await this.client.verifyIdToken(options);
|
|
128
|
+
const payload = ticket.getPayload();
|
|
129
|
+
if (!payload) {
|
|
130
|
+
(0, index_js_1.logWarn)("GoogleAdapter: Empty payload");
|
|
131
|
+
throw new AdapterError_js_1.AdapterError("Invalid Google ID token payload.");
|
|
132
|
+
}
|
|
133
|
+
// Create result object
|
|
134
|
+
const result = {
|
|
135
|
+
sub: payload.sub,
|
|
136
|
+
email: payload.email || '',
|
|
137
|
+
email_verified: payload.email_verified || false,
|
|
138
|
+
name: payload.name,
|
|
139
|
+
picture: payload.picture
|
|
140
|
+
};
|
|
141
|
+
// Add remaining properties from payload (excluding duplicates)
|
|
142
|
+
const { sub, email, email_verified, name, picture, ...rest } = payload;
|
|
143
|
+
Object.assign(result, rest);
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
(0, index_js_1.logError)("GoogleAdapter.verifyIdToken failed", {
|
|
148
|
+
error: err?.message,
|
|
149
|
+
hasClientId: !!this.clientId
|
|
150
|
+
});
|
|
151
|
+
if (err.message?.includes('audience')) {
|
|
152
|
+
throw new AdapterError_js_1.AdapterError("Invalid Google client ID configured.");
|
|
153
|
+
}
|
|
154
|
+
throw new AdapterError_js_1.AdapterError(err?.message || "Google token verification failed");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.GoogleAdapter = GoogleAdapter;
|
|
159
|
+
//# sourceMappingURL=GoogleAdapter.js.map
|
|
@@ -0,0 +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}"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
export interface JWTAdapterOptions {
|
|
3
|
+
secret: string;
|
|
4
|
+
expiresIn?: string | number;
|
|
5
|
+
algorithm?: jwt.Algorithm;
|
|
6
|
+
issuer?: string;
|
|
7
|
+
audience?: string | string[];
|
|
8
|
+
}
|
|
9
|
+
export interface SignOptions {
|
|
10
|
+
expiresIn?: string | number;
|
|
11
|
+
jti?: string;
|
|
12
|
+
subject?: string;
|
|
13
|
+
issuer?: string;
|
|
14
|
+
audience?: string | string[];
|
|
15
|
+
}
|
|
16
|
+
export declare class JWTAdapter {
|
|
17
|
+
private secret;
|
|
18
|
+
private expiresIn?;
|
|
19
|
+
private algorithm;
|
|
20
|
+
private issuer?;
|
|
21
|
+
private audience?;
|
|
22
|
+
constructor(options: JWTAdapterOptions);
|
|
23
|
+
sign(payload: object, options?: SignOptions): string;
|
|
24
|
+
verify(token: string, options?: {
|
|
25
|
+
audience?: string | string[];
|
|
26
|
+
}): string | jwt.Jwt | jwt.JwtPayload;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=JWTAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JWTAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/JWTAdapter.ts"],"names":[],"mappings":"AA8PA,OAAO,GAAG,MAAM,cAAc,CAAC;AAK/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;IAgBtC,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"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// // import jwt from "jsonwebtoken";
|
|
3
|
+
// // import { AdapterError } from "../core/errors/AdapterError";
|
|
4
|
+
// // import { logError } from "../logging";
|
|
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.JWTAdapter = void 0;
|
|
10
|
+
// // export interface JWTAdapterOptions {
|
|
11
|
+
// // secret: string;
|
|
12
|
+
// // expiresIn?: string | number | undefined;
|
|
13
|
+
// // }
|
|
14
|
+
// // export class JWTAdapter {
|
|
15
|
+
// // private secret: string;
|
|
16
|
+
// // private expiresIn?: string | number;
|
|
17
|
+
// // constructor(options: JWTAdapterOptions) {
|
|
18
|
+
// // if (!options.secret) {
|
|
19
|
+
// // throw new AdapterError("JWT secret is required");
|
|
20
|
+
// // }
|
|
21
|
+
// // this.secret = options.secret;
|
|
22
|
+
// // // Normalize expiresIn
|
|
23
|
+
// // if (options.expiresIn !== undefined) {
|
|
24
|
+
// // this.expiresIn = options.expiresIn as string | number;
|
|
25
|
+
// // }
|
|
26
|
+
// // }
|
|
27
|
+
// // sign(
|
|
28
|
+
// // payload: object,
|
|
29
|
+
// // options?: { expiresIn?: string | number }
|
|
30
|
+
// // ) {
|
|
31
|
+
// // try {
|
|
32
|
+
// // const finalExpires =
|
|
33
|
+
// // options?.expiresIn ?? this.expiresIn;
|
|
34
|
+
// // const jwtOptions: jwt.SignOptions = {};
|
|
35
|
+
// // if (finalExpires !== undefined) {
|
|
36
|
+
// // // Force safe cast → matches SignOptions type
|
|
37
|
+
// // jwtOptions.expiresIn = finalExpires as number | any;
|
|
38
|
+
// // }
|
|
39
|
+
// // return jwt.sign(payload, this.secret, jwtOptions);
|
|
40
|
+
// // } catch (err: any) {
|
|
41
|
+
// // logError("JWTAdapter.sign failed", { error: err?.message });
|
|
42
|
+
// // throw new AdapterError(err?.message || "JWT sign failed");
|
|
43
|
+
// // }
|
|
44
|
+
// // }
|
|
45
|
+
// // verify(token: string) {
|
|
46
|
+
// // try {
|
|
47
|
+
// // return jwt.verify(token, this.secret);
|
|
48
|
+
// // } catch (err: any) {
|
|
49
|
+
// // logError("JWTAdapter.verify failed", { error: err?.message });
|
|
50
|
+
// // throw new AdapterError(err?.message || "JWT verify failed");
|
|
51
|
+
// // }
|
|
52
|
+
// // }
|
|
53
|
+
// // }
|
|
54
|
+
// // // src/adapters/JWTAdapter.ts - FIXED (Security hardening)
|
|
55
|
+
// // import jwt from "jsonwebtoken";
|
|
56
|
+
// // import { v4 as uuidv4 } from "uuid";
|
|
57
|
+
// // import { AdapterError } from "../core/errors/AdapterError.js";
|
|
58
|
+
// // import { logError } from "../logging/index.js";
|
|
59
|
+
// // export interface JWTAdapterOptions {
|
|
60
|
+
// // secret: string;
|
|
61
|
+
// // expiresIn?: string | number;
|
|
62
|
+
// // algorithm?: jwt.Algorithm;
|
|
63
|
+
// // issuer?: string;
|
|
64
|
+
// // audience?: string | string[];
|
|
65
|
+
// // }
|
|
66
|
+
// // export interface SignOptions {
|
|
67
|
+
// // expiresIn?: string | number;
|
|
68
|
+
// // jti?: string; // JWT ID for token revocation
|
|
69
|
+
// // subject?: string;
|
|
70
|
+
// // issuer?: string;
|
|
71
|
+
// // audience?: string | string[];
|
|
72
|
+
// // }
|
|
73
|
+
// // export class JWTAdapter {
|
|
74
|
+
// // private secret: string;
|
|
75
|
+
// // private expiresIn?: string | number;
|
|
76
|
+
// // private algorithm: jwt.Algorithm;
|
|
77
|
+
// // private issuer?: string;
|
|
78
|
+
// // private audience?: string | string[];
|
|
79
|
+
// // constructor(options: JWTAdapterOptions) {
|
|
80
|
+
// // if (!options.secret) {
|
|
81
|
+
// // throw new AdapterError("JWT secret is required");
|
|
82
|
+
// // }
|
|
83
|
+
// // if (options.secret.length < 32) {
|
|
84
|
+
// // logError("⚠ JWT secret is too short (minimum 32 characters recommended)");
|
|
85
|
+
// // }
|
|
86
|
+
// // this.secret = options.secret;
|
|
87
|
+
// // this.expiresIn = options.expiresIn;
|
|
88
|
+
// // this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm
|
|
89
|
+
// // this.issuer = options.issuer;
|
|
90
|
+
// // this.audience = options.audience;
|
|
91
|
+
// // }
|
|
92
|
+
// // sign(payload: object, options?: SignOptions) {
|
|
93
|
+
// // try {
|
|
94
|
+
// // const jwtOptions: jwt.SignOptions = {
|
|
95
|
+
// // algorithm: this.algorithm,
|
|
96
|
+
// // issuer: options?.issuer || this.issuer,
|
|
97
|
+
// // audience: options?.audience || this.audience,
|
|
98
|
+
// // jwtid: options?.jti || uuidv4(), // Unique token ID
|
|
99
|
+
// // subject: options?.subject
|
|
100
|
+
// // };
|
|
101
|
+
// // if (options?.expiresIn !== undefined) {
|
|
102
|
+
// // jwtOptions.expiresIn = options.expiresIn as number;
|
|
103
|
+
// // } else if (this.expiresIn !== undefined) {
|
|
104
|
+
// // jwtOptions.expiresIn = this.expiresIn as number;
|
|
105
|
+
// // }
|
|
106
|
+
// // return jwt.sign(payload, this.secret, jwtOptions);
|
|
107
|
+
// // } catch (err: any) {
|
|
108
|
+
// // logError("JWTAdapter.sign failed", { error: err?.message });
|
|
109
|
+
// // throw new AdapterError(err?.message || "JWT sign failed");
|
|
110
|
+
// // }
|
|
111
|
+
// // }
|
|
112
|
+
// // verify(token: string, options?: { audience?: string | string[] }) {
|
|
113
|
+
// // try {
|
|
114
|
+
// // const verifyOptions: jwt.VerifyOptions = {
|
|
115
|
+
// // algorithms: [this.algorithm],
|
|
116
|
+
// // issuer: this.issuer,
|
|
117
|
+
// // audience: options?.audience as string || this.audience as string
|
|
118
|
+
// // };
|
|
119
|
+
// // return jwt.verify(token, this.secret, verifyOptions);
|
|
120
|
+
// // } catch (err: any) {
|
|
121
|
+
// // logError("JWTAdapter.verify failed", { error: err?.message });
|
|
122
|
+
// // // Provide better error messages
|
|
123
|
+
// // if (err.name === 'TokenExpiredError') {
|
|
124
|
+
// // throw new AdapterError("JWT token has expired");
|
|
125
|
+
// // }
|
|
126
|
+
// // if (err.name === 'JsonWebTokenError') {
|
|
127
|
+
// // throw new AdapterError("Invalid JWT token");
|
|
128
|
+
// // }
|
|
129
|
+
// // throw new AdapterError(err?.message || "JWT verification failed");
|
|
130
|
+
// // }
|
|
131
|
+
// // }
|
|
132
|
+
// // }
|
|
133
|
+
// // src/adapters/JWTAdapter.ts - FIXED (Security hardening)
|
|
134
|
+
// import jwt from "jsonwebtoken";
|
|
135
|
+
// import { nanoid } from "nanoid"; // CHANGED: from uuid to nanoid
|
|
136
|
+
// import { AdapterError } from "../core/errors/AdapterError.js";
|
|
137
|
+
// import { logError } from "../logging/index.js";
|
|
138
|
+
// export interface JWTAdapterOptions {
|
|
139
|
+
// secret: string;
|
|
140
|
+
// expiresIn?: string | number;
|
|
141
|
+
// algorithm?: jwt.Algorithm;
|
|
142
|
+
// issuer?: string;
|
|
143
|
+
// audience?: string | string[];
|
|
144
|
+
// }
|
|
145
|
+
// export interface SignOptions {
|
|
146
|
+
// expiresIn?: string | number;
|
|
147
|
+
// jti?: string; // JWT ID for token revocation
|
|
148
|
+
// subject?: string;
|
|
149
|
+
// issuer?: string;
|
|
150
|
+
// audience?: string | string[];
|
|
151
|
+
// }
|
|
152
|
+
// export class JWTAdapter {
|
|
153
|
+
// private secret: string;
|
|
154
|
+
// private expiresIn?: string | number;
|
|
155
|
+
// private algorithm: jwt.Algorithm;
|
|
156
|
+
// private issuer?: string;
|
|
157
|
+
// private audience?: string | string[];
|
|
158
|
+
// constructor(options: JWTAdapterOptions) {
|
|
159
|
+
// if (!options.secret) {
|
|
160
|
+
// throw new AdapterError("JWT secret is required");
|
|
161
|
+
// }
|
|
162
|
+
// if (options.secret.length < 32) {
|
|
163
|
+
// logError("⚠ JWT secret is too short (minimum 32 characters recommended)");
|
|
164
|
+
// }
|
|
165
|
+
// this.secret = options.secret;
|
|
166
|
+
// this.expiresIn = options.expiresIn;
|
|
167
|
+
// this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm
|
|
168
|
+
// this.issuer = options.issuer;
|
|
169
|
+
// this.audience = options.audience;
|
|
170
|
+
// }
|
|
171
|
+
// sign(payload: object, options?: SignOptions) {
|
|
172
|
+
// try {
|
|
173
|
+
// const jwtOptions: jwt.SignOptions = {
|
|
174
|
+
// algorithm: this.algorithm,
|
|
175
|
+
// issuer: options?.issuer || this.issuer,
|
|
176
|
+
// audience: options?.audience || this.audience,
|
|
177
|
+
// jwtid: options?.jti || nanoid(), // CHANGED: uuidv4() to nanoid()
|
|
178
|
+
// subject: options?.subject
|
|
179
|
+
// };
|
|
180
|
+
// if (options?.expiresIn !== undefined) {
|
|
181
|
+
// jwtOptions.expiresIn = options.expiresIn as number;
|
|
182
|
+
// } else if (this.expiresIn !== undefined) {
|
|
183
|
+
// jwtOptions.expiresIn = this.expiresIn as number;
|
|
184
|
+
// }
|
|
185
|
+
// return jwt.sign(payload, this.secret, jwtOptions);
|
|
186
|
+
// } catch (err: any) {
|
|
187
|
+
// logError("JWTAdapter.sign failed", { error: err?.message });
|
|
188
|
+
// throw new AdapterError(err?.message || "JWT sign failed");
|
|
189
|
+
// }
|
|
190
|
+
// }
|
|
191
|
+
// verify(token: string, options?: { audience?: string | string[] }) {
|
|
192
|
+
// try {
|
|
193
|
+
// const verifyOptions: jwt.VerifyOptions = {
|
|
194
|
+
// algorithms: [this.algorithm],
|
|
195
|
+
// issuer: this.issuer,
|
|
196
|
+
// audience: options?.audience as string || this.audience as string
|
|
197
|
+
// };
|
|
198
|
+
// return jwt.verify(token, this.secret, verifyOptions);
|
|
199
|
+
// } catch (err: any) {
|
|
200
|
+
// logError("JWTAdapter.verify failed", { error: err?.message });
|
|
201
|
+
// // Provide better error messages
|
|
202
|
+
// if (err.name === 'TokenExpiredError') {
|
|
203
|
+
// throw new AdapterError("JWT token has expired");
|
|
204
|
+
// }
|
|
205
|
+
// if (err.name === 'JsonWebTokenError') {
|
|
206
|
+
// throw new AdapterError("Invalid JWT token");
|
|
207
|
+
// }
|
|
208
|
+
// throw new AdapterError(err?.message || "JWT verification failed");
|
|
209
|
+
// }
|
|
210
|
+
// }
|
|
211
|
+
// }
|
|
212
|
+
// src/adapters/JWTAdapter.ts - FIXED (Using crypto.randomUUID())
|
|
213
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
214
|
+
const crypto_1 = require("crypto"); // Built-in Node.js
|
|
215
|
+
const AdapterError_js_1 = require("../core/errors/AdapterError.js");
|
|
216
|
+
const index_js_1 = require("../logging/index.js");
|
|
217
|
+
class JWTAdapter {
|
|
218
|
+
constructor(options) {
|
|
219
|
+
if (!options.secret) {
|
|
220
|
+
throw new AdapterError_js_1.AdapterError("JWT secret is required");
|
|
221
|
+
}
|
|
222
|
+
if (options.secret.length < 32) {
|
|
223
|
+
(0, index_js_1.logError)("⚠ JWT secret is too short (minimum 32 characters recommended)");
|
|
224
|
+
}
|
|
225
|
+
this.secret = options.secret;
|
|
226
|
+
this.expiresIn = options.expiresIn;
|
|
227
|
+
this.algorithm = options.algorithm || 'HS256'; // ⚠️ Default algorithm
|
|
228
|
+
this.issuer = options.issuer;
|
|
229
|
+
this.audience = options.audience;
|
|
230
|
+
}
|
|
231
|
+
sign(payload, options) {
|
|
232
|
+
try {
|
|
233
|
+
const jwtOptions = {
|
|
234
|
+
algorithm: this.algorithm,
|
|
235
|
+
issuer: options?.issuer || this.issuer,
|
|
236
|
+
audience: options?.audience || this.audience,
|
|
237
|
+
jwtid: options?.jti || (0, crypto_1.randomUUID)(), // ✅ Using crypto.randomUUID()
|
|
238
|
+
subject: options?.subject
|
|
239
|
+
};
|
|
240
|
+
if (options?.expiresIn !== undefined) {
|
|
241
|
+
jwtOptions.expiresIn = options.expiresIn;
|
|
242
|
+
}
|
|
243
|
+
else if (this.expiresIn !== undefined) {
|
|
244
|
+
jwtOptions.expiresIn = this.expiresIn;
|
|
245
|
+
}
|
|
246
|
+
return jsonwebtoken_1.default.sign(payload, this.secret, jwtOptions);
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
(0, index_js_1.logError)("JWTAdapter.sign failed", { error: err?.message });
|
|
250
|
+
throw new AdapterError_js_1.AdapterError(err?.message || "JWT sign failed");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
verify(token, options) {
|
|
254
|
+
try {
|
|
255
|
+
const verifyOptions = {
|
|
256
|
+
algorithms: [this.algorithm],
|
|
257
|
+
issuer: this.issuer,
|
|
258
|
+
audience: options?.audience || this.audience
|
|
259
|
+
};
|
|
260
|
+
return jsonwebtoken_1.default.verify(token, this.secret, verifyOptions);
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
(0, index_js_1.logError)("JWTAdapter.verify failed", { error: err?.message });
|
|
264
|
+
// Provide better error messages
|
|
265
|
+
if (err.name === 'TokenExpiredError') {
|
|
266
|
+
throw new AdapterError_js_1.AdapterError("JWT token has expired");
|
|
267
|
+
}
|
|
268
|
+
if (err.name === 'JsonWebTokenError') {
|
|
269
|
+
throw new AdapterError_js_1.AdapterError("Invalid JWT token");
|
|
270
|
+
}
|
|
271
|
+
throw new AdapterError_js_1.AdapterError(err?.message || "JWT verification failed");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
exports.JWTAdapter = JWTAdapter;
|
|
276
|
+
//# sourceMappingURL=JWTAdapter.js.map
|
|
@@ -0,0 +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}"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface RLOptions {
|
|
2
|
+
points?: number;
|
|
3
|
+
duration?: number;
|
|
4
|
+
message?: any;
|
|
5
|
+
blockDuration?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class RLFlexibleAdapter {
|
|
8
|
+
getMiddleware(options?: RLOptions): (req: any, res: any, next: any) => Promise<any>;
|
|
9
|
+
private extractIP;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=RLFlexibleAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RLFlexibleAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/RLFlexibleAdapter.ts"],"names":[],"mappings":"AAkEA,MAAM,WAAW,SAAS;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,iBAAiB;IAC1B,aAAa,CAAC,OAAO,GAAE,SAAc,SAiBV,GAAG,OAAO,GAAG,QAAQ,GAAG;IAoCnD,OAAO,CAAC,SAAS;CAWpB"}
|