@noony-serverless/core 0.1.1 → 0.2.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/build/core/core.d.ts +16 -48
- package/build/core/core.js +2 -61
- package/build/core/handler.d.ts +37 -16
- package/build/core/handler.js +131 -42
- package/build/core/index.d.ts +0 -1
- package/build/core/index.js +0 -1
- package/build/middlewares/ConsolidatedValidationMiddleware.d.ts +126 -0
- package/build/middlewares/ConsolidatedValidationMiddleware.js +330 -0
- package/build/middlewares/ProcessingMiddleware.d.ts +138 -0
- package/build/middlewares/ProcessingMiddleware.js +425 -0
- package/build/middlewares/SecurityMiddleware.d.ts +157 -0
- package/build/middlewares/SecurityMiddleware.js +307 -0
- package/build/middlewares/authenticationMiddleware.d.ts +379 -0
- package/build/middlewares/authenticationMiddleware.js +216 -0
- package/build/middlewares/bodyParserMiddleware.d.ts +99 -0
- package/build/middlewares/bodyParserMiddleware.js +99 -0
- package/build/middlewares/bodyValidationMiddleware.d.ts +69 -3
- package/build/middlewares/bodyValidationMiddleware.js +68 -2
- package/build/middlewares/dependencyInjectionMiddleware.d.ts +238 -0
- package/build/middlewares/dependencyInjectionMiddleware.js +238 -0
- package/build/middlewares/errorHandlerMiddleware.d.ts +94 -0
- package/build/middlewares/errorHandlerMiddleware.js +105 -0
- package/build/middlewares/guards/RouteGuards.d.ts +476 -21
- package/build/middlewares/guards/RouteGuards.js +418 -21
- package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.d.ts +271 -0
- package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.js +301 -0
- package/build/middlewares/guards/cache/CacheAdapter.d.ts +369 -28
- package/build/middlewares/guards/cache/CacheAdapter.js +124 -5
- package/build/middlewares/guards/cache/MemoryCacheAdapter.d.ts +113 -4
- package/build/middlewares/guards/cache/MemoryCacheAdapter.js +113 -4
- package/build/middlewares/guards/config/GuardConfiguration.d.ts +568 -18
- package/build/middlewares/guards/config/GuardConfiguration.js +266 -10
- package/build/middlewares/guards/guards/FastAuthGuard.d.ts +5 -5
- package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +5 -13
- package/build/middlewares/guards/guards/PermissionGuardFactory.js +4 -4
- package/build/middlewares/guards/index.d.ts +43 -1
- package/build/middlewares/guards/index.js +46 -1
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +1 -1
- package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +1 -1
- package/build/middlewares/guards/services/FastUserContextService.d.ts +20 -33
- package/build/middlewares/guards/services/FastUserContextService.js +19 -5
- package/build/middlewares/headerVariablesMiddleware.d.ts +118 -0
- package/build/middlewares/headerVariablesMiddleware.js +118 -0
- package/build/middlewares/httpAttributesMiddleware.d.ts +235 -0
- package/build/middlewares/httpAttributesMiddleware.js +236 -1
- package/build/middlewares/index.d.ts +3 -1
- package/build/middlewares/index.js +6 -1
- package/build/middlewares/queryParametersMiddleware.d.ts +105 -0
- package/build/middlewares/queryParametersMiddleware.js +105 -0
- package/build/middlewares/rateLimitingMiddleware.d.ts +601 -9
- package/build/middlewares/rateLimitingMiddleware.js +623 -11
- package/build/middlewares/responseWrapperMiddleware.d.ts +170 -1
- package/build/middlewares/responseWrapperMiddleware.js +170 -1
- package/build/middlewares/securityAuditMiddleware.js +5 -5
- package/package.json +11 -9
- package/build/core/containerPool.d.ts +0 -44
- package/build/core/containerPool.js +0 -103
- package/build/middlewares/validationMiddleware.d.ts +0 -9
- package/build/middlewares/validationMiddleware.js +0 -40
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CustomTokenVerificationPort Adapter
|
|
3
|
+
*
|
|
4
|
+
* Bridges the CustomTokenVerificationPort interface from AuthenticationMiddleware
|
|
5
|
+
* to the RouteGuards TokenValidator interface, enabling code reuse and unified
|
|
6
|
+
* token validation across the entire Noony Framework.
|
|
7
|
+
*
|
|
8
|
+
* Key Features:
|
|
9
|
+
* - Seamless integration between authentication systems
|
|
10
|
+
* - Maintains type safety through generics
|
|
11
|
+
* - Supports any token validation implementation (JWT, OAuth, API keys, etc.)
|
|
12
|
+
* - Preserves all existing RouteGuards functionality
|
|
13
|
+
* - Zero-overhead abstraction with full performance
|
|
14
|
+
*
|
|
15
|
+
* Benefits:
|
|
16
|
+
* - One authentication interface to implement and maintain
|
|
17
|
+
* - Consistent patterns across AuthenticationMiddleware and RouteGuards
|
|
18
|
+
* - Backward compatibility with existing RouteGuards implementations
|
|
19
|
+
* - Simplified setup for authentication workflows
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* Bridge a JWT verification port to RouteGuards:
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { CustomTokenVerificationPort } from '@/middlewares/authenticationMiddleware';
|
|
25
|
+
* import { CustomTokenVerificationPortAdapter } from '@/middlewares/guards/adapters';
|
|
26
|
+
*
|
|
27
|
+
* // Define your user type
|
|
28
|
+
* interface User {
|
|
29
|
+
* id: string;
|
|
30
|
+
* email: string;
|
|
31
|
+
* roles: string[];
|
|
32
|
+
* sub: string; // JWT subject
|
|
33
|
+
* exp: number; // JWT expiration
|
|
34
|
+
* iat: number; // Issued at
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* // Implement token verification once
|
|
38
|
+
* const jwtVerifier: CustomTokenVerificationPort<User> = {
|
|
39
|
+
* async verifyToken(token: string): Promise<User> {
|
|
40
|
+
* const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
|
|
41
|
+
* return {
|
|
42
|
+
* id: payload.sub,
|
|
43
|
+
* email: payload.email,
|
|
44
|
+
* roles: payload.roles || [],
|
|
45
|
+
* sub: payload.sub,
|
|
46
|
+
* exp: payload.exp,
|
|
47
|
+
* iat: payload.iat
|
|
48
|
+
* };
|
|
49
|
+
* }
|
|
50
|
+
* };
|
|
51
|
+
*
|
|
52
|
+
* // Create adapter for RouteGuards
|
|
53
|
+
* const tokenValidator = new CustomTokenVerificationPortAdapter(
|
|
54
|
+
* jwtVerifier,
|
|
55
|
+
* {
|
|
56
|
+
* userIdExtractor: (user: User) => user.id,
|
|
57
|
+
* expirationExtractor: (user: User) => user.exp
|
|
58
|
+
* }
|
|
59
|
+
* );
|
|
60
|
+
*
|
|
61
|
+
* // Use with RouteGuards
|
|
62
|
+
* await RouteGuards.configure(
|
|
63
|
+
* GuardSetup.production(),
|
|
64
|
+
* userPermissionSource,
|
|
65
|
+
* tokenValidator, // Works seamlessly!
|
|
66
|
+
* authConfig
|
|
67
|
+
* );
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* API key verification with custom user structure:
|
|
72
|
+
* ```typescript
|
|
73
|
+
* interface APIKeyUser {
|
|
74
|
+
* keyId: string;
|
|
75
|
+
* permissions: string[];
|
|
76
|
+
* organization: string;
|
|
77
|
+
* expiresAt: number;
|
|
78
|
+
* isActive: boolean;
|
|
79
|
+
* }
|
|
80
|
+
*
|
|
81
|
+
* const apiKeyVerifier: CustomTokenVerificationPort<APIKeyUser> = {
|
|
82
|
+
* async verifyToken(token: string): Promise<APIKeyUser> {
|
|
83
|
+
* const keyData = await validateAPIKey(token);
|
|
84
|
+
* if (!keyData || !keyData.isActive) {
|
|
85
|
+
* throw new Error('Invalid or inactive API key');
|
|
86
|
+
* }
|
|
87
|
+
* return keyData;
|
|
88
|
+
* }
|
|
89
|
+
* };
|
|
90
|
+
*
|
|
91
|
+
* // Adapter with custom extractors
|
|
92
|
+
* const apiTokenValidator = new CustomTokenVerificationPortAdapter(
|
|
93
|
+
* apiKeyVerifier,
|
|
94
|
+
* {
|
|
95
|
+
* userIdExtractor: (user: APIKeyUser) => user.keyId,
|
|
96
|
+
* expirationExtractor: (user: APIKeyUser) => user.expiresAt,
|
|
97
|
+
* additionalValidation: (user: APIKeyUser) => user.isActive
|
|
98
|
+
* }
|
|
99
|
+
* );
|
|
100
|
+
*
|
|
101
|
+
* // Seamlessly works with RouteGuards
|
|
102
|
+
* await RouteGuards.configure(
|
|
103
|
+
* GuardSetup.production(),
|
|
104
|
+
* userPermissionSource,
|
|
105
|
+
* apiTokenValidator,
|
|
106
|
+
* authConfig
|
|
107
|
+
* );
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* OAuth token verification:
|
|
112
|
+
* ```typescript
|
|
113
|
+
* interface OAuthUser {
|
|
114
|
+
* sub: string; // OAuth subject
|
|
115
|
+
* email: string;
|
|
116
|
+
* scope: string[]; // OAuth scopes
|
|
117
|
+
* exp: number;
|
|
118
|
+
* client_id: string;
|
|
119
|
+
* }
|
|
120
|
+
*
|
|
121
|
+
* const oauthVerifier: CustomTokenVerificationPort<OAuthUser> = {
|
|
122
|
+
* async verifyToken(token: string): Promise<OAuthUser> {
|
|
123
|
+
* // Validate with OAuth provider
|
|
124
|
+
* const response = await fetch(`${OAUTH_INTROSPECT_URL}`, {
|
|
125
|
+
* method: 'POST',
|
|
126
|
+
* headers: { 'Authorization': `Bearer ${token}` }
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* const tokenInfo = await response.json();
|
|
130
|
+
* if (!tokenInfo.active) {
|
|
131
|
+
* throw new Error('Token is not active');
|
|
132
|
+
* }
|
|
133
|
+
*
|
|
134
|
+
* return tokenInfo as OAuthUser;
|
|
135
|
+
* }
|
|
136
|
+
* };
|
|
137
|
+
*
|
|
138
|
+
* const oauthTokenValidator = new CustomTokenVerificationPortAdapter(
|
|
139
|
+
* oauthVerifier,
|
|
140
|
+
* {
|
|
141
|
+
* userIdExtractor: (user: OAuthUser) => user.sub,
|
|
142
|
+
* expirationExtractor: (user: OAuthUser) => user.exp
|
|
143
|
+
* }
|
|
144
|
+
* );
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* @author Noony Framework Team
|
|
148
|
+
* @version 1.0.0
|
|
149
|
+
*/
|
|
150
|
+
import { CustomTokenVerificationPort } from '../../authenticationMiddleware';
|
|
151
|
+
import { TokenValidator } from '../guards/FastAuthGuard';
|
|
152
|
+
/**
|
|
153
|
+
* Configuration options for the CustomTokenVerificationPort adapter.
|
|
154
|
+
* Provides flexible configuration for extracting required data from
|
|
155
|
+
* different user object structures.
|
|
156
|
+
*/
|
|
157
|
+
export interface AdapterConfig<T> {
|
|
158
|
+
/**
|
|
159
|
+
* Extract user ID from the verified user object.
|
|
160
|
+
* This ID will be used for permission lookups and caching.
|
|
161
|
+
*/
|
|
162
|
+
userIdExtractor: (user: T) => string;
|
|
163
|
+
/**
|
|
164
|
+
* Extract token expiration timestamp from the user object.
|
|
165
|
+
* Should return Unix timestamp (seconds since epoch).
|
|
166
|
+
*
|
|
167
|
+
* @param user - Verified user object
|
|
168
|
+
* @returns Unix timestamp or undefined if no expiration
|
|
169
|
+
*/
|
|
170
|
+
expirationExtractor?: (user: T) => number | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Optional additional validation after token verification.
|
|
173
|
+
* Allows custom business logic validation on the verified user.
|
|
174
|
+
*
|
|
175
|
+
* @param user - Verified user object
|
|
176
|
+
* @returns true if user passes additional validation
|
|
177
|
+
*/
|
|
178
|
+
additionalValidation?: (user: T) => boolean | Promise<boolean>;
|
|
179
|
+
/**
|
|
180
|
+
* Custom error message for token validation failures.
|
|
181
|
+
* If not provided, uses the original error from the verification port.
|
|
182
|
+
*/
|
|
183
|
+
errorMessage?: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Adapter class that bridges CustomTokenVerificationPort to TokenValidator.
|
|
187
|
+
* Enables seamless integration between AuthenticationMiddleware and RouteGuards
|
|
188
|
+
* while maintaining full type safety and performance.
|
|
189
|
+
*
|
|
190
|
+
* @template T - The user type returned by the CustomTokenVerificationPort
|
|
191
|
+
*/
|
|
192
|
+
export declare class CustomTokenVerificationPortAdapter<T> implements TokenValidator {
|
|
193
|
+
private readonly verificationPort;
|
|
194
|
+
private readonly config;
|
|
195
|
+
constructor(verificationPort: CustomTokenVerificationPort<T>, config: AdapterConfig<T>);
|
|
196
|
+
/**
|
|
197
|
+
* Validate and decode token using the wrapped CustomTokenVerificationPort.
|
|
198
|
+
*
|
|
199
|
+
* @param token - JWT token string to validate
|
|
200
|
+
* @returns Validation result with decoded user data
|
|
201
|
+
*/
|
|
202
|
+
validateToken(token: string): Promise<{
|
|
203
|
+
valid: boolean;
|
|
204
|
+
decoded?: T;
|
|
205
|
+
error?: string;
|
|
206
|
+
}>;
|
|
207
|
+
/**
|
|
208
|
+
* Extract user ID from the decoded token/user data.
|
|
209
|
+
* Uses the configured userIdExtractor function.
|
|
210
|
+
*
|
|
211
|
+
* @param decoded - Decoded user data from validateToken
|
|
212
|
+
* @returns User ID string
|
|
213
|
+
*/
|
|
214
|
+
extractUserId(decoded: T): string;
|
|
215
|
+
/**
|
|
216
|
+
* Check if the token is expired based on the decoded data.
|
|
217
|
+
* Uses the configured expirationExtractor if available.
|
|
218
|
+
*
|
|
219
|
+
* @param decoded - Decoded user data from validateToken
|
|
220
|
+
* @returns true if token is expired, false otherwise
|
|
221
|
+
*/
|
|
222
|
+
isTokenExpired(decoded: T): boolean;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Helper factory functions for common token verification scenarios.
|
|
226
|
+
* Provides pre-configured adapters for standard authentication patterns.
|
|
227
|
+
*/
|
|
228
|
+
export declare class TokenVerificationAdapterFactory {
|
|
229
|
+
/**
|
|
230
|
+
* Create adapter for standard JWT tokens with common claims.
|
|
231
|
+
* Assumes the user object has 'sub' for user ID and 'exp' for expiration.
|
|
232
|
+
*
|
|
233
|
+
* @param verificationPort - JWT token verification port
|
|
234
|
+
* @returns Configured adapter for JWT tokens
|
|
235
|
+
*/
|
|
236
|
+
static forJWT<T extends {
|
|
237
|
+
sub: string;
|
|
238
|
+
exp?: number;
|
|
239
|
+
}>(verificationPort: CustomTokenVerificationPort<T>): CustomTokenVerificationPortAdapter<T>;
|
|
240
|
+
/**
|
|
241
|
+
* Create adapter for API key tokens with custom ID and expiration fields.
|
|
242
|
+
*
|
|
243
|
+
* @param verificationPort - API key verification port
|
|
244
|
+
* @param userIdField - Field name for user/key ID (e.g., 'keyId', 'apiKeyId')
|
|
245
|
+
* @param expirationField - Optional field name for expiration (e.g., 'expiresAt', 'exp')
|
|
246
|
+
* @returns Configured adapter for API key tokens
|
|
247
|
+
*/
|
|
248
|
+
static forAPIKey<T extends Record<string, unknown>>(verificationPort: CustomTokenVerificationPort<T>, userIdField: keyof T, expirationField?: keyof T): CustomTokenVerificationPortAdapter<T>;
|
|
249
|
+
/**
|
|
250
|
+
* Create adapter for OAuth tokens with standard OAuth claims.
|
|
251
|
+
*
|
|
252
|
+
* @param verificationPort - OAuth token verification port
|
|
253
|
+
* @param additionalScopes - Optional required OAuth scopes
|
|
254
|
+
* @returns Configured adapter for OAuth tokens
|
|
255
|
+
*/
|
|
256
|
+
static forOAuth<T extends {
|
|
257
|
+
sub: string;
|
|
258
|
+
exp?: number;
|
|
259
|
+
scope?: string[];
|
|
260
|
+
}>(verificationPort: CustomTokenVerificationPort<T>, additionalScopes?: string[]): CustomTokenVerificationPortAdapter<T>;
|
|
261
|
+
/**
|
|
262
|
+
* Create adapter with custom configuration.
|
|
263
|
+
* Use this for non-standard token structures or complex validation logic.
|
|
264
|
+
*
|
|
265
|
+
* @param verificationPort - Token verification port
|
|
266
|
+
* @param config - Custom adapter configuration
|
|
267
|
+
* @returns Configured adapter with custom settings
|
|
268
|
+
*/
|
|
269
|
+
static custom<T>(verificationPort: CustomTokenVerificationPort<T>, config: AdapterConfig<T>): CustomTokenVerificationPortAdapter<T>;
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=CustomTokenVerificationPortAdapter.d.ts.map
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CustomTokenVerificationPort Adapter
|
|
4
|
+
*
|
|
5
|
+
* Bridges the CustomTokenVerificationPort interface from AuthenticationMiddleware
|
|
6
|
+
* to the RouteGuards TokenValidator interface, enabling code reuse and unified
|
|
7
|
+
* token validation across the entire Noony Framework.
|
|
8
|
+
*
|
|
9
|
+
* Key Features:
|
|
10
|
+
* - Seamless integration between authentication systems
|
|
11
|
+
* - Maintains type safety through generics
|
|
12
|
+
* - Supports any token validation implementation (JWT, OAuth, API keys, etc.)
|
|
13
|
+
* - Preserves all existing RouteGuards functionality
|
|
14
|
+
* - Zero-overhead abstraction with full performance
|
|
15
|
+
*
|
|
16
|
+
* Benefits:
|
|
17
|
+
* - One authentication interface to implement and maintain
|
|
18
|
+
* - Consistent patterns across AuthenticationMiddleware and RouteGuards
|
|
19
|
+
* - Backward compatibility with existing RouteGuards implementations
|
|
20
|
+
* - Simplified setup for authentication workflows
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* Bridge a JWT verification port to RouteGuards:
|
|
24
|
+
* ```typescript
|
|
25
|
+
* import { CustomTokenVerificationPort } from '@/middlewares/authenticationMiddleware';
|
|
26
|
+
* import { CustomTokenVerificationPortAdapter } from '@/middlewares/guards/adapters';
|
|
27
|
+
*
|
|
28
|
+
* // Define your user type
|
|
29
|
+
* interface User {
|
|
30
|
+
* id: string;
|
|
31
|
+
* email: string;
|
|
32
|
+
* roles: string[];
|
|
33
|
+
* sub: string; // JWT subject
|
|
34
|
+
* exp: number; // JWT expiration
|
|
35
|
+
* iat: number; // Issued at
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* // Implement token verification once
|
|
39
|
+
* const jwtVerifier: CustomTokenVerificationPort<User> = {
|
|
40
|
+
* async verifyToken(token: string): Promise<User> {
|
|
41
|
+
* const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
|
|
42
|
+
* return {
|
|
43
|
+
* id: payload.sub,
|
|
44
|
+
* email: payload.email,
|
|
45
|
+
* roles: payload.roles || [],
|
|
46
|
+
* sub: payload.sub,
|
|
47
|
+
* exp: payload.exp,
|
|
48
|
+
* iat: payload.iat
|
|
49
|
+
* };
|
|
50
|
+
* }
|
|
51
|
+
* };
|
|
52
|
+
*
|
|
53
|
+
* // Create adapter for RouteGuards
|
|
54
|
+
* const tokenValidator = new CustomTokenVerificationPortAdapter(
|
|
55
|
+
* jwtVerifier,
|
|
56
|
+
* {
|
|
57
|
+
* userIdExtractor: (user: User) => user.id,
|
|
58
|
+
* expirationExtractor: (user: User) => user.exp
|
|
59
|
+
* }
|
|
60
|
+
* );
|
|
61
|
+
*
|
|
62
|
+
* // Use with RouteGuards
|
|
63
|
+
* await RouteGuards.configure(
|
|
64
|
+
* GuardSetup.production(),
|
|
65
|
+
* userPermissionSource,
|
|
66
|
+
* tokenValidator, // Works seamlessly!
|
|
67
|
+
* authConfig
|
|
68
|
+
* );
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* API key verification with custom user structure:
|
|
73
|
+
* ```typescript
|
|
74
|
+
* interface APIKeyUser {
|
|
75
|
+
* keyId: string;
|
|
76
|
+
* permissions: string[];
|
|
77
|
+
* organization: string;
|
|
78
|
+
* expiresAt: number;
|
|
79
|
+
* isActive: boolean;
|
|
80
|
+
* }
|
|
81
|
+
*
|
|
82
|
+
* const apiKeyVerifier: CustomTokenVerificationPort<APIKeyUser> = {
|
|
83
|
+
* async verifyToken(token: string): Promise<APIKeyUser> {
|
|
84
|
+
* const keyData = await validateAPIKey(token);
|
|
85
|
+
* if (!keyData || !keyData.isActive) {
|
|
86
|
+
* throw new Error('Invalid or inactive API key');
|
|
87
|
+
* }
|
|
88
|
+
* return keyData;
|
|
89
|
+
* }
|
|
90
|
+
* };
|
|
91
|
+
*
|
|
92
|
+
* // Adapter with custom extractors
|
|
93
|
+
* const apiTokenValidator = new CustomTokenVerificationPortAdapter(
|
|
94
|
+
* apiKeyVerifier,
|
|
95
|
+
* {
|
|
96
|
+
* userIdExtractor: (user: APIKeyUser) => user.keyId,
|
|
97
|
+
* expirationExtractor: (user: APIKeyUser) => user.expiresAt,
|
|
98
|
+
* additionalValidation: (user: APIKeyUser) => user.isActive
|
|
99
|
+
* }
|
|
100
|
+
* );
|
|
101
|
+
*
|
|
102
|
+
* // Seamlessly works with RouteGuards
|
|
103
|
+
* await RouteGuards.configure(
|
|
104
|
+
* GuardSetup.production(),
|
|
105
|
+
* userPermissionSource,
|
|
106
|
+
* apiTokenValidator,
|
|
107
|
+
* authConfig
|
|
108
|
+
* );
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* OAuth token verification:
|
|
113
|
+
* ```typescript
|
|
114
|
+
* interface OAuthUser {
|
|
115
|
+
* sub: string; // OAuth subject
|
|
116
|
+
* email: string;
|
|
117
|
+
* scope: string[]; // OAuth scopes
|
|
118
|
+
* exp: number;
|
|
119
|
+
* client_id: string;
|
|
120
|
+
* }
|
|
121
|
+
*
|
|
122
|
+
* const oauthVerifier: CustomTokenVerificationPort<OAuthUser> = {
|
|
123
|
+
* async verifyToken(token: string): Promise<OAuthUser> {
|
|
124
|
+
* // Validate with OAuth provider
|
|
125
|
+
* const response = await fetch(`${OAUTH_INTROSPECT_URL}`, {
|
|
126
|
+
* method: 'POST',
|
|
127
|
+
* headers: { 'Authorization': `Bearer ${token}` }
|
|
128
|
+
* });
|
|
129
|
+
*
|
|
130
|
+
* const tokenInfo = await response.json();
|
|
131
|
+
* if (!tokenInfo.active) {
|
|
132
|
+
* throw new Error('Token is not active');
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* return tokenInfo as OAuthUser;
|
|
136
|
+
* }
|
|
137
|
+
* };
|
|
138
|
+
*
|
|
139
|
+
* const oauthTokenValidator = new CustomTokenVerificationPortAdapter(
|
|
140
|
+
* oauthVerifier,
|
|
141
|
+
* {
|
|
142
|
+
* userIdExtractor: (user: OAuthUser) => user.sub,
|
|
143
|
+
* expirationExtractor: (user: OAuthUser) => user.exp
|
|
144
|
+
* }
|
|
145
|
+
* );
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @author Noony Framework Team
|
|
149
|
+
* @version 1.0.0
|
|
150
|
+
*/
|
|
151
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
152
|
+
exports.TokenVerificationAdapterFactory = exports.CustomTokenVerificationPortAdapter = void 0;
|
|
153
|
+
/**
|
|
154
|
+
* Adapter class that bridges CustomTokenVerificationPort to TokenValidator.
|
|
155
|
+
* Enables seamless integration between AuthenticationMiddleware and RouteGuards
|
|
156
|
+
* while maintaining full type safety and performance.
|
|
157
|
+
*
|
|
158
|
+
* @template T - The user type returned by the CustomTokenVerificationPort
|
|
159
|
+
*/
|
|
160
|
+
class CustomTokenVerificationPortAdapter {
|
|
161
|
+
verificationPort;
|
|
162
|
+
config;
|
|
163
|
+
constructor(verificationPort, config) {
|
|
164
|
+
this.verificationPort = verificationPort;
|
|
165
|
+
this.config = config;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Validate and decode token using the wrapped CustomTokenVerificationPort.
|
|
169
|
+
*
|
|
170
|
+
* @param token - JWT token string to validate
|
|
171
|
+
* @returns Validation result with decoded user data
|
|
172
|
+
*/
|
|
173
|
+
async validateToken(token) {
|
|
174
|
+
try {
|
|
175
|
+
// Use the wrapped verification port to verify the token
|
|
176
|
+
const user = await this.verificationPort.verifyToken(token);
|
|
177
|
+
// Run additional validation if configured
|
|
178
|
+
if (this.config.additionalValidation) {
|
|
179
|
+
const additionalValid = await this.config.additionalValidation(user);
|
|
180
|
+
if (!additionalValid) {
|
|
181
|
+
return {
|
|
182
|
+
valid: false,
|
|
183
|
+
error: this.config.errorMessage || 'Additional validation failed',
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
valid: true,
|
|
189
|
+
decoded: user,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
return {
|
|
194
|
+
valid: false,
|
|
195
|
+
error: this.config.errorMessage ||
|
|
196
|
+
(error instanceof Error ? error.message : 'Token validation failed'),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Extract user ID from the decoded token/user data.
|
|
202
|
+
* Uses the configured userIdExtractor function.
|
|
203
|
+
*
|
|
204
|
+
* @param decoded - Decoded user data from validateToken
|
|
205
|
+
* @returns User ID string
|
|
206
|
+
*/
|
|
207
|
+
extractUserId(decoded) {
|
|
208
|
+
return this.config.userIdExtractor(decoded);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Check if the token is expired based on the decoded data.
|
|
212
|
+
* Uses the configured expirationExtractor if available.
|
|
213
|
+
*
|
|
214
|
+
* @param decoded - Decoded user data from validateToken
|
|
215
|
+
* @returns true if token is expired, false otherwise
|
|
216
|
+
*/
|
|
217
|
+
isTokenExpired(decoded) {
|
|
218
|
+
if (!this.config.expirationExtractor) {
|
|
219
|
+
// If no expiration extractor is configured, assume token is valid
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
const expirationTime = this.config.expirationExtractor(decoded);
|
|
223
|
+
if (!expirationTime) {
|
|
224
|
+
// If no expiration time is available, assume token is valid
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
// Compare with current time (convert to seconds)
|
|
228
|
+
const currentTime = Math.floor(Date.now() / 1000);
|
|
229
|
+
return expirationTime <= currentTime;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
exports.CustomTokenVerificationPortAdapter = CustomTokenVerificationPortAdapter;
|
|
233
|
+
/**
|
|
234
|
+
* Helper factory functions for common token verification scenarios.
|
|
235
|
+
* Provides pre-configured adapters for standard authentication patterns.
|
|
236
|
+
*/
|
|
237
|
+
class TokenVerificationAdapterFactory {
|
|
238
|
+
/**
|
|
239
|
+
* Create adapter for standard JWT tokens with common claims.
|
|
240
|
+
* Assumes the user object has 'sub' for user ID and 'exp' for expiration.
|
|
241
|
+
*
|
|
242
|
+
* @param verificationPort - JWT token verification port
|
|
243
|
+
* @returns Configured adapter for JWT tokens
|
|
244
|
+
*/
|
|
245
|
+
static forJWT(verificationPort) {
|
|
246
|
+
return new CustomTokenVerificationPortAdapter(verificationPort, {
|
|
247
|
+
userIdExtractor: (user) => user.sub,
|
|
248
|
+
expirationExtractor: (user) => user.exp,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Create adapter for API key tokens with custom ID and expiration fields.
|
|
253
|
+
*
|
|
254
|
+
* @param verificationPort - API key verification port
|
|
255
|
+
* @param userIdField - Field name for user/key ID (e.g., 'keyId', 'apiKeyId')
|
|
256
|
+
* @param expirationField - Optional field name for expiration (e.g., 'expiresAt', 'exp')
|
|
257
|
+
* @returns Configured adapter for API key tokens
|
|
258
|
+
*/
|
|
259
|
+
static forAPIKey(verificationPort, userIdField, expirationField) {
|
|
260
|
+
return new CustomTokenVerificationPortAdapter(verificationPort, {
|
|
261
|
+
userIdExtractor: (user) => String(user[userIdField]),
|
|
262
|
+
expirationExtractor: expirationField
|
|
263
|
+
? (user) => user[expirationField]
|
|
264
|
+
: undefined,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Create adapter for OAuth tokens with standard OAuth claims.
|
|
269
|
+
*
|
|
270
|
+
* @param verificationPort - OAuth token verification port
|
|
271
|
+
* @param additionalScopes - Optional required OAuth scopes
|
|
272
|
+
* @returns Configured adapter for OAuth tokens
|
|
273
|
+
*/
|
|
274
|
+
static forOAuth(verificationPort, additionalScopes) {
|
|
275
|
+
return new CustomTokenVerificationPortAdapter(verificationPort, {
|
|
276
|
+
userIdExtractor: (user) => user.sub,
|
|
277
|
+
expirationExtractor: (user) => user.exp,
|
|
278
|
+
additionalValidation: additionalScopes
|
|
279
|
+
? (user) => {
|
|
280
|
+
if (!user.scope || !Array.isArray(user.scope)) {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
return additionalScopes.every((requiredScope) => user.scope.includes(requiredScope));
|
|
284
|
+
}
|
|
285
|
+
: undefined,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Create adapter with custom configuration.
|
|
290
|
+
* Use this for non-standard token structures or complex validation logic.
|
|
291
|
+
*
|
|
292
|
+
* @param verificationPort - Token verification port
|
|
293
|
+
* @param config - Custom adapter configuration
|
|
294
|
+
* @returns Configured adapter with custom settings
|
|
295
|
+
*/
|
|
296
|
+
static custom(verificationPort, config) {
|
|
297
|
+
return new CustomTokenVerificationPortAdapter(verificationPort, config);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
exports.TokenVerificationAdapterFactory = TokenVerificationAdapterFactory;
|
|
301
|
+
//# sourceMappingURL=CustomTokenVerificationPortAdapter.js.map
|