@noony-serverless/core 0.1.0 → 0.1.5

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.
Files changed (56) hide show
  1. package/build/middlewares/authenticationMiddleware.d.ts +379 -0
  2. package/build/middlewares/authenticationMiddleware.js +216 -0
  3. package/build/middlewares/bodyParserMiddleware.d.ts +99 -0
  4. package/build/middlewares/bodyParserMiddleware.js +99 -0
  5. package/build/middlewares/bodyValidationMiddleware.d.ts +68 -4
  6. package/build/middlewares/bodyValidationMiddleware.js +64 -0
  7. package/build/middlewares/dependencyInjectionMiddleware.d.ts +238 -0
  8. package/build/middlewares/dependencyInjectionMiddleware.js +238 -0
  9. package/build/middlewares/errorHandlerMiddleware.d.ts +94 -0
  10. package/build/middlewares/errorHandlerMiddleware.js +105 -0
  11. package/build/middlewares/guards/RouteGuards.d.ts +475 -0
  12. package/build/middlewares/guards/RouteGuards.js +604 -0
  13. package/build/middlewares/guards/cache/CacheAdapter.d.ts +473 -0
  14. package/build/middlewares/guards/cache/CacheAdapter.js +205 -0
  15. package/build/middlewares/guards/cache/ConservativeCacheInvalidation.d.ts +191 -0
  16. package/build/middlewares/guards/cache/ConservativeCacheInvalidation.js +510 -0
  17. package/build/middlewares/guards/cache/MemoryCacheAdapter.d.ts +228 -0
  18. package/build/middlewares/guards/cache/MemoryCacheAdapter.js +403 -0
  19. package/build/middlewares/guards/cache/NoopCacheAdapter.d.ts +95 -0
  20. package/build/middlewares/guards/cache/NoopCacheAdapter.js +131 -0
  21. package/build/middlewares/guards/config/GuardConfiguration.d.ts +612 -0
  22. package/build/middlewares/guards/config/GuardConfiguration.js +334 -0
  23. package/build/middlewares/guards/guards/FastAuthGuard.d.ts +201 -0
  24. package/build/middlewares/guards/guards/FastAuthGuard.js +460 -0
  25. package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +202 -0
  26. package/build/middlewares/guards/guards/PermissionGuardFactory.js +563 -0
  27. package/build/middlewares/guards/index.d.ts +67 -0
  28. package/build/middlewares/guards/index.js +192 -0
  29. package/build/middlewares/guards/registry/PermissionRegistry.d.ts +188 -0
  30. package/build/middlewares/guards/registry/PermissionRegistry.js +425 -0
  31. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +129 -0
  32. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +451 -0
  33. package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +155 -0
  34. package/build/middlewares/guards/resolvers/PermissionResolver.js +176 -0
  35. package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +101 -0
  36. package/build/middlewares/guards/resolvers/PlainPermissionResolver.js +248 -0
  37. package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +146 -0
  38. package/build/middlewares/guards/resolvers/WildcardPermissionResolver.js +377 -0
  39. package/build/middlewares/guards/services/FastUserContextService.d.ts +216 -0
  40. package/build/middlewares/guards/services/FastUserContextService.js +435 -0
  41. package/build/middlewares/headerVariablesMiddleware.d.ts +118 -0
  42. package/build/middlewares/headerVariablesMiddleware.js +118 -0
  43. package/build/middlewares/httpAttributesMiddleware.d.ts +235 -0
  44. package/build/middlewares/httpAttributesMiddleware.js +235 -0
  45. package/build/middlewares/index.d.ts +1 -0
  46. package/build/middlewares/index.js +1 -0
  47. package/build/middlewares/queryParametersMiddleware.d.ts +105 -0
  48. package/build/middlewares/queryParametersMiddleware.js +105 -0
  49. package/build/middlewares/rateLimitingMiddleware.d.ts +109 -5
  50. package/build/middlewares/rateLimitingMiddleware.js +109 -5
  51. package/build/middlewares/responseWrapperMiddleware.d.ts +170 -1
  52. package/build/middlewares/responseWrapperMiddleware.js +170 -1
  53. package/build/middlewares/securityAuditMiddleware.js +5 -5
  54. package/build/middlewares/validationMiddleware.d.ts +145 -0
  55. package/build/middlewares/validationMiddleware.js +145 -0
  56. package/package.json +2 -2
@@ -1,8 +1,107 @@
1
1
  import { BaseMiddleware } from '../core/handler';
2
2
  import { Context } from '../core/core';
3
+ /**
4
+ * Interface for custom token verification implementations.
5
+ * Allows integration with various authentication providers (JWT, OAuth, custom tokens).
6
+ *
7
+ * @template T - The type of user data returned after successful token verification
8
+ *
9
+ * @example
10
+ * JWT token verification:
11
+ * ```typescript
12
+ * import jwt from 'jsonwebtoken';
13
+ * import { CustomTokenVerificationPort } from '@noony-serverless/core';
14
+ *
15
+ * interface User {
16
+ * id: string;
17
+ * email: string;
18
+ * roles: string[];
19
+ * }
20
+ *
21
+ * class JWTVerificationPort implements CustomTokenVerificationPort<User> {
22
+ * constructor(private secret: string) {}
23
+ *
24
+ * async verifyToken(token: string): Promise<User> {
25
+ * try {
26
+ * const payload = jwt.verify(token, this.secret) as any;
27
+ * return {
28
+ * id: payload.sub,
29
+ * email: payload.email,
30
+ * roles: payload.roles || []
31
+ * };
32
+ * } catch (error) {
33
+ * throw new Error('Invalid token');
34
+ * }
35
+ * }
36
+ * }
37
+ * ```
38
+ *
39
+ * @example
40
+ * Custom API token verification:
41
+ * ```typescript
42
+ * class APIKeyVerificationPort implements CustomTokenVerificationPort<{ apiKey: string; permissions: string[] }> {
43
+ * async verifyToken(token: string): Promise<{ apiKey: string; permissions: string[] }> {
44
+ * const apiKey = await this.validateAPIKey(token);
45
+ * if (!apiKey) {
46
+ * throw new Error('Invalid API key');
47
+ * }
48
+ * return {
49
+ * apiKey: token,
50
+ * permissions: apiKey.permissions
51
+ * };
52
+ * }
53
+ *
54
+ * private async validateAPIKey(key: string) {
55
+ * // Validate against database or external service
56
+ * return { permissions: ['read', 'write'] };
57
+ * }
58
+ * }
59
+ * ```
60
+ */
3
61
  export interface CustomTokenVerificationPort<T> {
4
62
  verifyToken(token: string): Promise<T>;
5
63
  }
64
+ /**
65
+ * Standard JWT payload interface with common claims.
66
+ * Extends the payload with custom properties as needed.
67
+ *
68
+ * @example
69
+ * Basic JWT payload usage:
70
+ * ```typescript
71
+ * import { JWTPayload } from '@noony-serverless/core';
72
+ *
73
+ * interface CustomJWTPayload extends JWTPayload {
74
+ * userId: string;
75
+ * email: string;
76
+ * roles: string[];
77
+ * }
78
+ *
79
+ * const payload: CustomJWTPayload = {
80
+ * sub: 'user-123',
81
+ * exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour
82
+ * iat: Math.floor(Date.now() / 1000),
83
+ * iss: 'my-app',
84
+ * aud: 'my-app-users',
85
+ * userId: 'user-123',
86
+ * email: 'user@example.com',
87
+ * roles: ['user', 'admin']
88
+ * };
89
+ * ```
90
+ *
91
+ * @example
92
+ * Token validation with custom claims:
93
+ * ```typescript
94
+ * function validateCustomClaims(payload: JWTPayload & { roles?: string[] }) {
95
+ * if (!payload.roles || payload.roles.length === 0) {
96
+ * throw new Error('User must have at least one role');
97
+ * }
98
+ *
99
+ * if (payload.exp && payload.exp < Date.now() / 1000) {
100
+ * throw new Error('Token has expired');
101
+ * }
102
+ * }
103
+ * ```
104
+ */
6
105
  export interface JWTPayload {
7
106
  exp?: number;
8
107
  iat?: number;
@@ -13,6 +112,70 @@ export interface JWTPayload {
13
112
  sub?: string;
14
113
  [key: string]: unknown;
15
114
  }
115
+ /**
116
+ * Configuration options for authentication middleware.
117
+ * Provides comprehensive security controls and validation settings.
118
+ *
119
+ * @example
120
+ * Basic authentication options:
121
+ * ```typescript
122
+ * import { AuthenticationOptions } from '@noony-serverless/core';
123
+ *
124
+ * const basicOptions: AuthenticationOptions = {
125
+ * maxTokenAge: 3600, // 1 hour
126
+ * clockTolerance: 60, // 1 minute
127
+ * requiredClaims: {
128
+ * issuer: 'my-app',
129
+ * audience: 'my-app-users'
130
+ * }
131
+ * };
132
+ * ```
133
+ *
134
+ * @example
135
+ * Advanced options with rate limiting and blacklisting:
136
+ * ```typescript
137
+ * const advancedOptions: AuthenticationOptions = {
138
+ * maxTokenAge: 7200, // 2 hours
139
+ * clockTolerance: 30,
140
+ * rateLimiting: {
141
+ * maxAttempts: 5,
142
+ * windowMs: 15 * 60 * 1000 // 15 minutes
143
+ * },
144
+ * isTokenBlacklisted: async (tokenId) => {
145
+ * // Check Redis or database for blacklisted tokens
146
+ * return await redis.sismember('blacklisted_tokens', tokenId);
147
+ * },
148
+ * requiredClaims: {
149
+ * issuer: 'secure-app',
150
+ * audience: ['web-app', 'mobile-app']
151
+ * }
152
+ * };
153
+ * ```
154
+ *
155
+ * @example
156
+ * Production security configuration:
157
+ * ```typescript
158
+ * const productionOptions: AuthenticationOptions = {
159
+ * maxTokenAge: 1800, // 30 minutes - short for security
160
+ * clockTolerance: 10, // Tight tolerance
161
+ * rateLimiting: {
162
+ * maxAttempts: 3, // Strict rate limiting
163
+ * windowMs: 30 * 60 * 1000 // 30 minutes lockout
164
+ * },
165
+ * isTokenBlacklisted: async (tokenId) => {
166
+ * const result = await database.query(
167
+ * 'SELECT 1 FROM revoked_tokens WHERE jti = ?',
168
+ * [tokenId]
169
+ * );
170
+ * return result.length > 0;
171
+ * },
172
+ * requiredClaims: {
173
+ * issuer: 'production-auth-server',
174
+ * audience: 'production-api'
175
+ * }
176
+ * };
177
+ * ```
178
+ */
16
179
  export interface AuthenticationOptions {
17
180
  /**
18
181
  * Maximum token age in seconds (overrides exp claim validation)
@@ -42,11 +205,227 @@ export interface AuthenticationOptions {
42
205
  audience?: string | string[];
43
206
  };
44
207
  }
208
+ /**
209
+ * Class-based authentication middleware with comprehensive security features.
210
+ * Provides JWT validation, rate limiting, token blacklisting, and security logging.
211
+ *
212
+ * @template T - The type of user data returned by the token verification port
213
+ *
214
+ * @example
215
+ * Basic JWT authentication:
216
+ * ```typescript
217
+ * import { Handler, AuthenticationMiddleware } from '@noony-serverless/core';
218
+ * import jwt from 'jsonwebtoken';
219
+ *
220
+ * interface User {
221
+ * id: string;
222
+ * email: string;
223
+ * roles: string[];
224
+ * }
225
+ *
226
+ * class JWTVerifier implements CustomTokenVerificationPort<User> {
227
+ * async verifyToken(token: string): Promise<User> {
228
+ * const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
229
+ * return {
230
+ * id: payload.sub,
231
+ * email: payload.email,
232
+ * roles: payload.roles || []
233
+ * };
234
+ * }
235
+ * }
236
+ *
237
+ * const protectedHandler = new Handler()
238
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
239
+ * .handle(async (request, context) => {
240
+ * const user = context.user as User;
241
+ * return {
242
+ * success: true,
243
+ * data: { message: `Hello ${user.email}`, userId: user.id }
244
+ * };
245
+ * });
246
+ * ```
247
+ *
248
+ * @example
249
+ * Advanced authentication with security options:
250
+ * ```typescript
251
+ * const secureAuthMiddleware = new AuthenticationMiddleware(
252
+ * new JWTVerifier(),
253
+ * {
254
+ * maxTokenAge: 1800, // 30 minutes
255
+ * rateLimiting: {
256
+ * maxAttempts: 5,
257
+ * windowMs: 15 * 60 * 1000 // 15 minutes
258
+ * },
259
+ * isTokenBlacklisted: async (tokenId) => {
260
+ * return await redis.sismember('revoked_tokens', tokenId);
261
+ * },
262
+ * requiredClaims: {
263
+ * issuer: 'my-auth-server',
264
+ * audience: 'my-api'
265
+ * }
266
+ * }
267
+ * );
268
+ *
269
+ * const secureHandler = new Handler()
270
+ * .use(secureAuthMiddleware)
271
+ * .handle(async (request, context) => {
272
+ * // Only authenticated users reach here
273
+ * return { success: true, data: 'Secure data' };
274
+ * });
275
+ * ```
276
+ *
277
+ * @example
278
+ * Google Cloud Functions integration:
279
+ * ```typescript
280
+ * import { http } from '@google-cloud/functions-framework';
281
+ *
282
+ * const userProfileHandler = new Handler()
283
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
284
+ * .handle(async (request, context) => {
285
+ * const user = context.user as User;
286
+ * const profile = await getUserProfile(user.id);
287
+ * return { success: true, data: profile };
288
+ * });
289
+ *
290
+ * export const getUserProfile = http('getUserProfile', (req, res) => {
291
+ * return userProfileHandler.execute(req, res);
292
+ * });
293
+ * ```
294
+ */
45
295
  export declare class AuthenticationMiddleware<T> implements BaseMiddleware {
46
296
  private tokenVerificationPort;
47
297
  private options;
48
298
  constructor(tokenVerificationPort: CustomTokenVerificationPort<T>, options?: AuthenticationOptions);
49
299
  before(context: Context): Promise<void>;
50
300
  }
301
+ /**
302
+ * Factory function that creates an authentication middleware with token verification.
303
+ * Provides a functional approach for authentication setup.
304
+ *
305
+ * @template T - The type of user data returned by the token verification port
306
+ * @param tokenVerificationPort - The token verification implementation
307
+ * @param options - Authentication configuration options
308
+ * @returns A BaseMiddleware object with authentication logic
309
+ *
310
+ * @example
311
+ * Simple JWT authentication:
312
+ * ```typescript
313
+ * import { Handler, verifyAuthTokenMiddleware } from '@noony-serverless/core';
314
+ *
315
+ * class SimpleJWTVerifier implements CustomTokenVerificationPort<{ userId: string }> {
316
+ * async verifyToken(token: string): Promise<{ userId: string }> {
317
+ * // Simple token verification logic
318
+ * if (token === 'valid-token') {
319
+ * return { userId: 'user-123' };
320
+ * }
321
+ * throw new Error('Invalid token');
322
+ * }
323
+ * }
324
+ *
325
+ * const handler = new Handler()
326
+ * .use(verifyAuthTokenMiddleware(new SimpleJWTVerifier()))
327
+ * .handle(async (request, context) => {
328
+ * const user = context.user as { userId: string };
329
+ * return { success: true, userId: user.userId };
330
+ * });
331
+ * ```
332
+ *
333
+ * @example
334
+ * API key authentication with rate limiting:
335
+ * ```typescript
336
+ * interface APIKeyUser {
337
+ * keyId: string;
338
+ * permissions: string[];
339
+ * organization: string;
340
+ * }
341
+ *
342
+ * class APIKeyVerifier implements CustomTokenVerificationPort<APIKeyUser> {
343
+ * async verifyToken(token: string): Promise<APIKeyUser> {
344
+ * const keyData = await this.validateAPIKey(token);
345
+ * if (!keyData) {
346
+ * throw new Error('Invalid API key');
347
+ * }
348
+ * return keyData;
349
+ * }
350
+ *
351
+ * private async validateAPIKey(key: string): Promise<APIKeyUser | null> {
352
+ * // Database lookup or external validation
353
+ * return {
354
+ * keyId: 'key-123',
355
+ * permissions: ['read', 'write'],
356
+ * organization: 'org-456'
357
+ * };
358
+ * }
359
+ * }
360
+ *
361
+ * const apiHandler = new Handler()
362
+ * .use(verifyAuthTokenMiddleware(
363
+ * new APIKeyVerifier(),
364
+ * {
365
+ * rateLimiting: {
366
+ * maxAttempts: 100,
367
+ * windowMs: 60 * 1000 // 1 minute
368
+ * }
369
+ * }
370
+ * ))
371
+ * .handle(async (request, context) => {
372
+ * const apiUser = context.user as APIKeyUser;
373
+ * return {
374
+ * success: true,
375
+ * data: { organization: apiUser.organization }
376
+ * };
377
+ * });
378
+ * ```
379
+ *
380
+ * @example
381
+ * Express-style middleware chain:
382
+ * ```typescript
383
+ * import { Handler, verifyAuthTokenMiddleware, errorHandler } from '@noony-serverless/core';
384
+ *
385
+ * const authMiddleware = verifyAuthTokenMiddleware(
386
+ * new JWTVerifier(),
387
+ * {
388
+ * maxTokenAge: 3600,
389
+ * requiredClaims: {
390
+ * issuer: 'my-app',
391
+ * audience: 'api-users'
392
+ * }
393
+ * }
394
+ * );
395
+ *
396
+ * const protectedEndpoint = new Handler()
397
+ * .use(authMiddleware)
398
+ * .use(errorHandler())
399
+ * .handle(async (request, context) => {
400
+ * // Authenticated user available in context.user
401
+ * return { success: true, data: 'Protected resource' };
402
+ * });
403
+ * ```
404
+ *
405
+ * @example
406
+ * Multiple authentication strategies:
407
+ * ```typescript
408
+ * // Different handlers for different auth types
409
+ * const jwtHandler = new Handler()
410
+ * .use(verifyAuthTokenMiddleware(new JWTVerifier()))
411
+ * .handle(jwtLogic);
412
+ *
413
+ * const apiKeyHandler = new Handler()
414
+ * .use(verifyAuthTokenMiddleware(new APIKeyVerifier()))
415
+ * .handle(apiKeyLogic);
416
+ *
417
+ * // Route based on authentication type
418
+ * export const handleRequest = (req: any, res: any) => {
419
+ * const authHeader = req.headers.authorization;
420
+ * if (authHeader?.startsWith('Bearer jwt.')) {
421
+ * return jwtHandler.execute(req, res);
422
+ * } else if (authHeader?.startsWith('Bearer ak_')) {
423
+ * return apiKeyHandler.execute(req, res);
424
+ * } else {
425
+ * res.status(401).json({ error: 'Authentication required' });
426
+ * }
427
+ * };
428
+ * ```
429
+ */
51
430
  export declare const verifyAuthTokenMiddleware: <T>(tokenVerificationPort: CustomTokenVerificationPort<T>, options?: AuthenticationOptions) => BaseMiddleware;
52
431
  //# sourceMappingURL=authenticationMiddleware.d.ts.map
@@ -169,6 +169,93 @@ async function verifyToken(tokenVerificationPort, context, options = {}) {
169
169
  throw new errors_1.AuthenticationError('Invalid authentication');
170
170
  }
171
171
  }
172
+ /**
173
+ * Class-based authentication middleware with comprehensive security features.
174
+ * Provides JWT validation, rate limiting, token blacklisting, and security logging.
175
+ *
176
+ * @template T - The type of user data returned by the token verification port
177
+ *
178
+ * @example
179
+ * Basic JWT authentication:
180
+ * ```typescript
181
+ * import { Handler, AuthenticationMiddleware } from '@noony-serverless/core';
182
+ * import jwt from 'jsonwebtoken';
183
+ *
184
+ * interface User {
185
+ * id: string;
186
+ * email: string;
187
+ * roles: string[];
188
+ * }
189
+ *
190
+ * class JWTVerifier implements CustomTokenVerificationPort<User> {
191
+ * async verifyToken(token: string): Promise<User> {
192
+ * const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
193
+ * return {
194
+ * id: payload.sub,
195
+ * email: payload.email,
196
+ * roles: payload.roles || []
197
+ * };
198
+ * }
199
+ * }
200
+ *
201
+ * const protectedHandler = new Handler()
202
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
203
+ * .handle(async (request, context) => {
204
+ * const user = context.user as User;
205
+ * return {
206
+ * success: true,
207
+ * data: { message: `Hello ${user.email}`, userId: user.id }
208
+ * };
209
+ * });
210
+ * ```
211
+ *
212
+ * @example
213
+ * Advanced authentication with security options:
214
+ * ```typescript
215
+ * const secureAuthMiddleware = new AuthenticationMiddleware(
216
+ * new JWTVerifier(),
217
+ * {
218
+ * maxTokenAge: 1800, // 30 minutes
219
+ * rateLimiting: {
220
+ * maxAttempts: 5,
221
+ * windowMs: 15 * 60 * 1000 // 15 minutes
222
+ * },
223
+ * isTokenBlacklisted: async (tokenId) => {
224
+ * return await redis.sismember('revoked_tokens', tokenId);
225
+ * },
226
+ * requiredClaims: {
227
+ * issuer: 'my-auth-server',
228
+ * audience: 'my-api'
229
+ * }
230
+ * }
231
+ * );
232
+ *
233
+ * const secureHandler = new Handler()
234
+ * .use(secureAuthMiddleware)
235
+ * .handle(async (request, context) => {
236
+ * // Only authenticated users reach here
237
+ * return { success: true, data: 'Secure data' };
238
+ * });
239
+ * ```
240
+ *
241
+ * @example
242
+ * Google Cloud Functions integration:
243
+ * ```typescript
244
+ * import { http } from '@google-cloud/functions-framework';
245
+ *
246
+ * const userProfileHandler = new Handler()
247
+ * .use(new AuthenticationMiddleware(new JWTVerifier()))
248
+ * .handle(async (request, context) => {
249
+ * const user = context.user as User;
250
+ * const profile = await getUserProfile(user.id);
251
+ * return { success: true, data: profile };
252
+ * });
253
+ *
254
+ * export const getUserProfile = http('getUserProfile', (req, res) => {
255
+ * return userProfileHandler.execute(req, res);
256
+ * });
257
+ * ```
258
+ */
172
259
  class AuthenticationMiddleware {
173
260
  tokenVerificationPort;
174
261
  options;
@@ -181,6 +268,135 @@ class AuthenticationMiddleware {
181
268
  }
182
269
  }
183
270
  exports.AuthenticationMiddleware = AuthenticationMiddleware;
271
+ /**
272
+ * Factory function that creates an authentication middleware with token verification.
273
+ * Provides a functional approach for authentication setup.
274
+ *
275
+ * @template T - The type of user data returned by the token verification port
276
+ * @param tokenVerificationPort - The token verification implementation
277
+ * @param options - Authentication configuration options
278
+ * @returns A BaseMiddleware object with authentication logic
279
+ *
280
+ * @example
281
+ * Simple JWT authentication:
282
+ * ```typescript
283
+ * import { Handler, verifyAuthTokenMiddleware } from '@noony-serverless/core';
284
+ *
285
+ * class SimpleJWTVerifier implements CustomTokenVerificationPort<{ userId: string }> {
286
+ * async verifyToken(token: string): Promise<{ userId: string }> {
287
+ * // Simple token verification logic
288
+ * if (token === 'valid-token') {
289
+ * return { userId: 'user-123' };
290
+ * }
291
+ * throw new Error('Invalid token');
292
+ * }
293
+ * }
294
+ *
295
+ * const handler = new Handler()
296
+ * .use(verifyAuthTokenMiddleware(new SimpleJWTVerifier()))
297
+ * .handle(async (request, context) => {
298
+ * const user = context.user as { userId: string };
299
+ * return { success: true, userId: user.userId };
300
+ * });
301
+ * ```
302
+ *
303
+ * @example
304
+ * API key authentication with rate limiting:
305
+ * ```typescript
306
+ * interface APIKeyUser {
307
+ * keyId: string;
308
+ * permissions: string[];
309
+ * organization: string;
310
+ * }
311
+ *
312
+ * class APIKeyVerifier implements CustomTokenVerificationPort<APIKeyUser> {
313
+ * async verifyToken(token: string): Promise<APIKeyUser> {
314
+ * const keyData = await this.validateAPIKey(token);
315
+ * if (!keyData) {
316
+ * throw new Error('Invalid API key');
317
+ * }
318
+ * return keyData;
319
+ * }
320
+ *
321
+ * private async validateAPIKey(key: string): Promise<APIKeyUser | null> {
322
+ * // Database lookup or external validation
323
+ * return {
324
+ * keyId: 'key-123',
325
+ * permissions: ['read', 'write'],
326
+ * organization: 'org-456'
327
+ * };
328
+ * }
329
+ * }
330
+ *
331
+ * const apiHandler = new Handler()
332
+ * .use(verifyAuthTokenMiddleware(
333
+ * new APIKeyVerifier(),
334
+ * {
335
+ * rateLimiting: {
336
+ * maxAttempts: 100,
337
+ * windowMs: 60 * 1000 // 1 minute
338
+ * }
339
+ * }
340
+ * ))
341
+ * .handle(async (request, context) => {
342
+ * const apiUser = context.user as APIKeyUser;
343
+ * return {
344
+ * success: true,
345
+ * data: { organization: apiUser.organization }
346
+ * };
347
+ * });
348
+ * ```
349
+ *
350
+ * @example
351
+ * Express-style middleware chain:
352
+ * ```typescript
353
+ * import { Handler, verifyAuthTokenMiddleware, errorHandler } from '@noony-serverless/core';
354
+ *
355
+ * const authMiddleware = verifyAuthTokenMiddleware(
356
+ * new JWTVerifier(),
357
+ * {
358
+ * maxTokenAge: 3600,
359
+ * requiredClaims: {
360
+ * issuer: 'my-app',
361
+ * audience: 'api-users'
362
+ * }
363
+ * }
364
+ * );
365
+ *
366
+ * const protectedEndpoint = new Handler()
367
+ * .use(authMiddleware)
368
+ * .use(errorHandler())
369
+ * .handle(async (request, context) => {
370
+ * // Authenticated user available in context.user
371
+ * return { success: true, data: 'Protected resource' };
372
+ * });
373
+ * ```
374
+ *
375
+ * @example
376
+ * Multiple authentication strategies:
377
+ * ```typescript
378
+ * // Different handlers for different auth types
379
+ * const jwtHandler = new Handler()
380
+ * .use(verifyAuthTokenMiddleware(new JWTVerifier()))
381
+ * .handle(jwtLogic);
382
+ *
383
+ * const apiKeyHandler = new Handler()
384
+ * .use(verifyAuthTokenMiddleware(new APIKeyVerifier()))
385
+ * .handle(apiKeyLogic);
386
+ *
387
+ * // Route based on authentication type
388
+ * export const handleRequest = (req: any, res: any) => {
389
+ * const authHeader = req.headers.authorization;
390
+ * if (authHeader?.startsWith('Bearer jwt.')) {
391
+ * return jwtHandler.execute(req, res);
392
+ * } else if (authHeader?.startsWith('Bearer ak_')) {
393
+ * return apiKeyHandler.execute(req, res);
394
+ * } else {
395
+ * res.status(401).json({ error: 'Authentication required' });
396
+ * }
397
+ * };
398
+ * ```
399
+ */
184
400
  const verifyAuthTokenMiddleware = (tokenVerificationPort, options = {}) => ({
185
401
  async before(context) {
186
402
  await verifyToken(tokenVerificationPort, context, options);