@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.
Files changed (62) hide show
  1. package/build/core/core.d.ts +16 -48
  2. package/build/core/core.js +2 -61
  3. package/build/core/handler.d.ts +37 -16
  4. package/build/core/handler.js +131 -42
  5. package/build/core/index.d.ts +0 -1
  6. package/build/core/index.js +0 -1
  7. package/build/middlewares/ConsolidatedValidationMiddleware.d.ts +126 -0
  8. package/build/middlewares/ConsolidatedValidationMiddleware.js +330 -0
  9. package/build/middlewares/ProcessingMiddleware.d.ts +138 -0
  10. package/build/middlewares/ProcessingMiddleware.js +425 -0
  11. package/build/middlewares/SecurityMiddleware.d.ts +157 -0
  12. package/build/middlewares/SecurityMiddleware.js +307 -0
  13. package/build/middlewares/authenticationMiddleware.d.ts +379 -0
  14. package/build/middlewares/authenticationMiddleware.js +216 -0
  15. package/build/middlewares/bodyParserMiddleware.d.ts +99 -0
  16. package/build/middlewares/bodyParserMiddleware.js +99 -0
  17. package/build/middlewares/bodyValidationMiddleware.d.ts +69 -3
  18. package/build/middlewares/bodyValidationMiddleware.js +68 -2
  19. package/build/middlewares/dependencyInjectionMiddleware.d.ts +238 -0
  20. package/build/middlewares/dependencyInjectionMiddleware.js +238 -0
  21. package/build/middlewares/errorHandlerMiddleware.d.ts +94 -0
  22. package/build/middlewares/errorHandlerMiddleware.js +105 -0
  23. package/build/middlewares/guards/RouteGuards.d.ts +476 -21
  24. package/build/middlewares/guards/RouteGuards.js +418 -21
  25. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.d.ts +271 -0
  26. package/build/middlewares/guards/adapters/CustomTokenVerificationPortAdapter.js +301 -0
  27. package/build/middlewares/guards/cache/CacheAdapter.d.ts +369 -28
  28. package/build/middlewares/guards/cache/CacheAdapter.js +124 -5
  29. package/build/middlewares/guards/cache/MemoryCacheAdapter.d.ts +113 -4
  30. package/build/middlewares/guards/cache/MemoryCacheAdapter.js +113 -4
  31. package/build/middlewares/guards/config/GuardConfiguration.d.ts +568 -18
  32. package/build/middlewares/guards/config/GuardConfiguration.js +266 -10
  33. package/build/middlewares/guards/guards/FastAuthGuard.d.ts +5 -5
  34. package/build/middlewares/guards/guards/PermissionGuardFactory.d.ts +5 -13
  35. package/build/middlewares/guards/guards/PermissionGuardFactory.js +4 -4
  36. package/build/middlewares/guards/index.d.ts +43 -1
  37. package/build/middlewares/guards/index.js +46 -1
  38. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.d.ts +1 -1
  39. package/build/middlewares/guards/resolvers/ExpressionPermissionResolver.js +1 -1
  40. package/build/middlewares/guards/resolvers/PermissionResolver.d.ts +1 -1
  41. package/build/middlewares/guards/resolvers/PlainPermissionResolver.d.ts +1 -1
  42. package/build/middlewares/guards/resolvers/WildcardPermissionResolver.d.ts +1 -1
  43. package/build/middlewares/guards/services/FastUserContextService.d.ts +20 -33
  44. package/build/middlewares/guards/services/FastUserContextService.js +19 -5
  45. package/build/middlewares/headerVariablesMiddleware.d.ts +118 -0
  46. package/build/middlewares/headerVariablesMiddleware.js +118 -0
  47. package/build/middlewares/httpAttributesMiddleware.d.ts +235 -0
  48. package/build/middlewares/httpAttributesMiddleware.js +236 -1
  49. package/build/middlewares/index.d.ts +3 -1
  50. package/build/middlewares/index.js +6 -1
  51. package/build/middlewares/queryParametersMiddleware.d.ts +105 -0
  52. package/build/middlewares/queryParametersMiddleware.js +105 -0
  53. package/build/middlewares/rateLimitingMiddleware.d.ts +601 -9
  54. package/build/middlewares/rateLimitingMiddleware.js +623 -11
  55. package/build/middlewares/responseWrapperMiddleware.d.ts +170 -1
  56. package/build/middlewares/responseWrapperMiddleware.js +170 -1
  57. package/build/middlewares/securityAuditMiddleware.js +5 -5
  58. package/package.json +11 -9
  59. package/build/core/containerPool.d.ts +0 -44
  60. package/build/core/containerPool.js +0 -103
  61. package/build/middlewares/validationMiddleware.d.ts +0 -9
  62. package/build/middlewares/validationMiddleware.js +0 -40
@@ -20,24 +20,128 @@
20
20
  * - Comprehensive monitoring and audit trails
21
21
  * - Framework-agnostic middleware integration
22
22
  *
23
- * Usage Examples:
23
+ * @example
24
+ * Complete guard system setup:
24
25
  * ```typescript
25
- * // Simple permissions (fastest)
26
- * .use(RouteGuards.requirePermissions(['user:read', 'user:update']))
26
+ * import { RouteGuards, GuardSetup } from '@noony-serverless/core';
27
27
  *
28
- * // Wildcard patterns (hierarchical)
29
- * .use(RouteGuards.requireWildcardPermissions(['admin.*', 'org.reports.*']))
28
+ * // Define user permission source
29
+ * const userPermissionSource = {
30
+ * async getUserPermissions(userId: string): Promise<string[]> {
31
+ * const user = await getUserFromDatabase(userId);
32
+ * return user.permissions;
33
+ * }
34
+ * };
30
35
  *
31
- * // Complex expressions (boolean logic)
32
- * .use(RouteGuards.requireComplexPermissions({
33
- * or: [
34
- * { permission: 'admin.users' },
35
- * { and: [
36
- * { permission: 'moderator.content' },
37
- * { permission: 'org.reports.view' }
38
- * ]}
39
- * ]
40
- * }))
36
+ * // Define token validator
37
+ * const tokenValidator = {
38
+ * async validateToken(token: string) {
39
+ * try {
40
+ * const decoded = jwt.verify(token, process.env.JWT_SECRET);
41
+ * return { valid: true, decoded };
42
+ * } catch (error) {
43
+ * return { valid: false, error: error.message };
44
+ * }
45
+ * },
46
+ * extractUserId: (decoded: unknown) => (decoded as any).sub,
47
+ * isTokenExpired: (decoded: unknown) => (decoded as any).exp < Date.now() / 1000
48
+ * };
49
+ *
50
+ * // Configure guard system
51
+ * await RouteGuards.configure(
52
+ * GuardSetup.production(),
53
+ * userPermissionSource,
54
+ * tokenValidator,
55
+ * {
56
+ * tokenHeader: 'authorization',
57
+ * tokenPrefix: 'Bearer ',
58
+ * requireEmailVerification: true,
59
+ * allowInactiveUsers: false
60
+ * }
61
+ * );
62
+ * ```
63
+ *
64
+ * @example
65
+ * Simple permission checks (fastest - ~0.1ms cached):
66
+ * ```typescript
67
+ * import { Handler, RouteGuards } from '@noony-serverless/core';
68
+ *
69
+ * const userManagementHandler = new Handler()
70
+ * .use(RouteGuards.requirePermissions(['user:read', 'user:update']))
71
+ * .handle(async (context) => {
72
+ * // User has either 'user:read' OR 'user:update' permission
73
+ * const users = await getUsers();
74
+ * return { success: true, users };
75
+ * });
76
+ * ```
77
+ *
78
+ * @example
79
+ * Wildcard permission patterns (hierarchical - ~0.2ms cached):
80
+ * ```typescript
81
+ * const adminHandler = new Handler()
82
+ * .use(RouteGuards.requireWildcardPermissions(['admin.*', 'org.reports.*']))
83
+ * .handle(async (context) => {
84
+ * // User has any permission starting with 'admin.' OR 'org.reports.'
85
+ * const adminData = await getAdminDashboard();
86
+ * return { success: true, data: adminData };
87
+ * });
88
+ * ```
89
+ *
90
+ * @example
91
+ * Complex boolean expressions (~0.5ms cached):
92
+ * ```typescript
93
+ * const complexAccessHandler = new Handler()
94
+ * .use(RouteGuards.requireComplexPermissions({
95
+ * or: [
96
+ * { permission: 'admin.users' },
97
+ * { and: [
98
+ * { permission: 'moderator.content' },
99
+ * { permission: 'org.reports.view' }
100
+ * ]}
101
+ * ]
102
+ * }))
103
+ * .handle(async (context) => {
104
+ * // User has 'admin.users' OR ('moderator.content' AND 'org.reports.view')
105
+ * return { success: true, accessGranted: true };
106
+ * });
107
+ * ```
108
+ *
109
+ * @example
110
+ * Authentication-only (no permissions):
111
+ * ```typescript
112
+ * const profileHandler = new Handler()
113
+ * .use(RouteGuards.requireAuth())
114
+ * .handle(async (context) => {
115
+ * // Only checks if user is authenticated
116
+ * const profile = await getUserProfile(context.user.id);
117
+ * return { success: true, profile };
118
+ * });
119
+ * ```
120
+ *
121
+ * @example
122
+ * Cache invalidation for security:
123
+ * ```typescript
124
+ * // Invalidate specific user when permissions change
125
+ * await RouteGuards.invalidateUserPermissions('user-123', 'Permission update');
126
+ *
127
+ * // System-wide invalidation for major updates
128
+ * await RouteGuards.invalidateAllPermissions('System update deployed');
129
+ *
130
+ * // Emergency invalidation for security incidents
131
+ * await RouteGuards.emergencyInvalidation('Security breach detected');
132
+ * ```
133
+ *
134
+ * @example
135
+ * Monitoring and health checks:
136
+ * ```typescript
137
+ * // Get comprehensive system statistics
138
+ * const stats = RouteGuards.getSystemStats();
139
+ * console.log('Guard system performance:', stats.systemHealth);
140
+ *
141
+ * // Perform health check
142
+ * const health = await RouteGuards.healthCheck();
143
+ * console.log('System status:', health.status);
144
+ * console.log('Recommendations:', health.details.recommendations);
41
145
  * ```
42
146
  *
43
147
  * @author Noony Framework Team
@@ -64,6 +168,50 @@ const ConservativeCacheInvalidation_1 = require("./cache/ConservativeCacheInvali
64
168
  const FastAuthGuard_1 = require("./guards/FastAuthGuard");
65
169
  const PermissionGuardFactory_1 = require("./guards/PermissionGuardFactory");
66
170
  const PermissionRegistry_1 = require("./registry/PermissionRegistry");
171
+ const CustomTokenVerificationPortAdapter_1 = require("./adapters/CustomTokenVerificationPortAdapter");
172
+ /**
173
+ * Helper function to check if a token validator is a CustomTokenVerificationPort
174
+ */
175
+ function isCustomTokenVerificationPort(validator) {
176
+ return (typeof validator === 'object' &&
177
+ 'verifyToken' in validator &&
178
+ !('validateToken' in validator));
179
+ }
180
+ /**
181
+ * Convert any token validator to the TokenValidator interface expected by RouteGuards.
182
+ * Automatically wraps CustomTokenVerificationPort implementations with an adapter.
183
+ */
184
+ function normalizeTokenValidator(validator) {
185
+ if (isCustomTokenVerificationPort(validator)) {
186
+ // For CustomTokenVerificationPort, we create a generic adapter
187
+ // We use a basic configuration that tries to extract common fields
188
+ return new CustomTokenVerificationPortAdapter_1.CustomTokenVerificationPortAdapter(validator, {
189
+ userIdExtractor: (user) => {
190
+ // Try to extract user ID from common field names
191
+ if (user && typeof user === 'object') {
192
+ const userObj = user;
193
+ return String(userObj.sub ||
194
+ userObj.id ||
195
+ userObj.userId ||
196
+ userObj.user_id ||
197
+ 'unknown');
198
+ }
199
+ return 'unknown';
200
+ },
201
+ expirationExtractor: (user) => {
202
+ // Try to extract expiration from common field names
203
+ if (user && typeof user === 'object') {
204
+ const userObj = user;
205
+ const exp = userObj.exp || userObj.expiresAt || userObj.expires_at;
206
+ return typeof exp === 'number' ? exp : undefined;
207
+ }
208
+ return undefined;
209
+ },
210
+ });
211
+ }
212
+ // Already a TokenValidator, return as-is
213
+ return validator;
214
+ }
67
215
  /**
68
216
  * Route Guards Facade Implementation
69
217
  *
@@ -107,9 +255,58 @@ let RouteGuards = class RouteGuards {
107
255
  *
108
256
  * @param profile - Environment profile with guard configurations
109
257
  * @param permissionSource - User permission data source
110
- * @param tokenValidator - JWT token validation service
258
+ * @param tokenValidator - Token validation service (supports both TokenValidator and CustomTokenVerificationPort)
111
259
  * @param authConfig - Authentication guard configuration
112
260
  * @returns Promise resolving when configuration is complete
261
+ *
262
+ * @example
263
+ * Using with CustomTokenVerificationPort from AuthenticationMiddleware:
264
+ * ```typescript
265
+ * import { CustomTokenVerificationPort } from '@/middlewares/authenticationMiddleware';
266
+ * import { RouteGuards, GuardSetup } from '@/middlewares/guards';
267
+ *
268
+ * // Same token verifier used across the framework
269
+ * const tokenVerifier: CustomTokenVerificationPort<User> = {
270
+ * async verifyToken(token: string): Promise<User> {
271
+ * const payload = jwt.verify(token, process.env.JWT_SECRET!) as JWTPayload;
272
+ * return {
273
+ * id: payload.sub,
274
+ * email: payload.email,
275
+ * roles: payload.roles || [],
276
+ * sub: payload.sub,
277
+ * exp: payload.exp
278
+ * };
279
+ * }
280
+ * };
281
+ *
282
+ * // Configure RouteGuards with the same verifier
283
+ * await RouteGuards.configure(
284
+ * GuardSetup.production(),
285
+ * userPermissionSource,
286
+ * tokenVerifier, // Automatically wrapped with adapter
287
+ * authConfig
288
+ * );
289
+ * ```
290
+ *
291
+ * @example
292
+ * Traditional usage with TokenValidator (backward compatible):
293
+ * ```typescript
294
+ * const tokenValidator: TokenValidator = {
295
+ * async validateToken(token: string) {
296
+ * // Your existing validation logic
297
+ * return { valid: true, decoded: userPayload };
298
+ * },
299
+ * extractUserId: (decoded) => decoded.sub,
300
+ * isTokenExpired: (decoded) => decoded.exp < Date.now() / 1000
301
+ * };
302
+ *
303
+ * await RouteGuards.configure(
304
+ * GuardSetup.production(),
305
+ * userPermissionSource,
306
+ * tokenValidator, // Works as before
307
+ * authConfig
308
+ * );
309
+ * ```
113
310
  */
114
311
  static async configure(profile, permissionSource, tokenValidator, authConfig) {
115
312
  if (RouteGuards_1.isConfigured) {
@@ -119,20 +316,30 @@ let RouteGuards = class RouteGuards {
119
316
  try {
120
317
  // Create guard configuration
121
318
  const config = GuardConfiguration_1.GuardConfiguration.fromEnvironmentProfile(profile);
122
- // Select cache adapter based on environment
319
+ // Get effective cache type considering environment variable override
320
+ // Environment variable NOONY_GUARD_CACHE_ENABLE takes precedence for security
321
+ const effectiveCacheType = GuardConfiguration_1.GuardConfiguration.getEffectiveCacheType(profile.cacheType);
322
+ // Select cache adapter based on effective cache type
123
323
  let cache;
124
- if (profile.cacheType === 'memory') {
324
+ if (effectiveCacheType === 'memory') {
125
325
  cache = new MemoryCacheAdapter_1.MemoryCacheAdapter({
126
326
  maxSize: config.cache.maxEntries || 1000,
127
327
  defaultTTL: config.cache.defaultTtlMs || 15 * 60 * 1000,
128
328
  name: 'guard-memory-cache',
129
329
  });
130
330
  }
131
- else if (profile.cacheType === 'none') {
331
+ else if (effectiveCacheType === 'none') {
132
332
  cache = new NoopCacheAdapter_1.NoopCacheAdapter();
333
+ // Log cache status for debugging
334
+ if (!GuardConfiguration_1.GuardConfiguration.isCachingEnabled()) {
335
+ console.log(`🚫 Guard caching disabled by environment variable NOONY_GUARD_CACHE_ENABLE`);
336
+ }
337
+ else {
338
+ console.log(`🚫 Guard caching disabled by configuration (cacheType: 'none')`);
339
+ }
133
340
  }
134
341
  else {
135
- // Default to memory cache
342
+ // Default to memory cache (redis support would go here)
136
343
  cache = new MemoryCacheAdapter_1.MemoryCacheAdapter({
137
344
  maxSize: 1000,
138
345
  defaultTTL: 15 * 60 * 1000,
@@ -145,8 +352,10 @@ let RouteGuards = class RouteGuards {
145
352
  const userContextService = new FastUserContextService_1.FastUserContextService(cache, config, permissionSource, permissionRegistry);
146
353
  // Create cache invalidation service
147
354
  const cacheInvalidation = new ConservativeCacheInvalidation_1.ConservativeCacheInvalidation(cache);
355
+ // Normalize token validator to ensure compatibility
356
+ const normalizedTokenValidator = normalizeTokenValidator(tokenValidator);
148
357
  // Create authentication guard
149
- const authGuard = new FastAuthGuard_1.FastAuthGuard(cache, config, authConfig, userContextService, cacheInvalidation, tokenValidator);
358
+ const authGuard = new FastAuthGuard_1.FastAuthGuard(cache, config, authConfig, userContextService, cacheInvalidation, normalizedTokenValidator);
150
359
  // Create permission guard factory
151
360
  const guardFactory = new PermissionGuardFactory_1.PermissionGuardFactory(userContextService, config, cache);
152
361
  // Register services with TypeDI container
@@ -165,6 +374,8 @@ let RouteGuards = class RouteGuards {
165
374
  console.log('✅ RouteGuards configured successfully', {
166
375
  environment: profile.environment,
167
376
  cacheType: profile.cacheType,
377
+ effectiveCacheType: effectiveCacheType,
378
+ cachingEnabled: GuardConfiguration_1.GuardConfiguration.isCachingEnabled(),
168
379
  permissionStrategy: config.security.permissionResolutionStrategy,
169
380
  timestamp: new Date().toISOString(),
170
381
  });
@@ -333,6 +544,192 @@ let RouteGuards = class RouteGuards {
333
544
  const instance = RouteGuards_1.getInstance();
334
545
  return instance.performHealthCheck();
335
546
  }
547
+ /**
548
+ * Factory method: Configure RouteGuards with CustomTokenVerificationPort for JWT tokens.
549
+ * Provides a streamlined setup for JWT-based authentication with common field extraction.
550
+ *
551
+ * @example
552
+ * Quick JWT setup with CustomTokenVerificationPort:
553
+ * ```typescript
554
+ * import { CustomTokenVerificationPort } from '@/middlewares/authenticationMiddleware';
555
+ *
556
+ * interface JWTUser {
557
+ * sub: string;
558
+ * email: string;
559
+ * roles: string[];
560
+ * exp: number;
561
+ * }
562
+ *
563
+ * const jwtVerifier: CustomTokenVerificationPort<JWTUser> = {
564
+ * async verifyToken(token: string): Promise<JWTUser> {
565
+ * const payload = jwt.verify(token, process.env.JWT_SECRET!) as any;
566
+ * return {
567
+ * sub: payload.sub,
568
+ * email: payload.email,
569
+ * roles: payload.roles || [],
570
+ * exp: payload.exp
571
+ * };
572
+ * }
573
+ * };
574
+ *
575
+ * // One-line setup for JWT authentication
576
+ * await RouteGuards.configureWithJWT(
577
+ * GuardSetup.production(),
578
+ * userPermissionSource,
579
+ * jwtVerifier,
580
+ * {
581
+ * tokenHeader: 'authorization',
582
+ * tokenPrefix: 'Bearer ',
583
+ * requireEmailVerification: true
584
+ * }
585
+ * );
586
+ * ```
587
+ */
588
+ static async configureWithJWT(profile, permissionSource, jwtVerifier, authConfig) {
589
+ // Create a properly typed adapter for JWT tokens
590
+ const tokenValidator = CustomTokenVerificationPortAdapter_1.TokenVerificationAdapterFactory.forJWT(jwtVerifier);
591
+ await RouteGuards_1.configure(profile, permissionSource, tokenValidator, authConfig);
592
+ }
593
+ /**
594
+ * Factory method: Configure RouteGuards with CustomTokenVerificationPort for API keys.
595
+ * Provides setup for API key-based authentication with flexible field mapping.
596
+ *
597
+ * @example
598
+ * API key authentication setup:
599
+ * ```typescript
600
+ * interface APIKeyUser {
601
+ * keyId: string;
602
+ * permissions: string[];
603
+ * organization: string;
604
+ * expiresAt?: number;
605
+ * isActive: boolean;
606
+ * }
607
+ *
608
+ * const apiKeyVerifier: CustomTokenVerificationPort<APIKeyUser> = {
609
+ * async verifyToken(token: string): Promise<APIKeyUser> {
610
+ * const keyData = await validateAPIKeyInDatabase(token);
611
+ * if (!keyData || !keyData.isActive) {
612
+ * throw new Error('Invalid or inactive API key');
613
+ * }
614
+ * return keyData;
615
+ * }
616
+ * };
617
+ *
618
+ * await RouteGuards.configureWithAPIKey(
619
+ * GuardSetup.production(),
620
+ * userPermissionSource,
621
+ * apiKeyVerifier,
622
+ * {
623
+ * tokenHeader: 'x-api-key',
624
+ * tokenPrefix: '',
625
+ * allowInactiveUsers: false
626
+ * },
627
+ * 'keyId',
628
+ * 'expiresAt'
629
+ * );
630
+ * ```
631
+ */
632
+ static async configureWithAPIKey(profile, permissionSource, apiKeyVerifier, authConfig, userIdField, expirationField) {
633
+ // Create a properly configured adapter for API keys
634
+ const tokenValidator = CustomTokenVerificationPortAdapter_1.TokenVerificationAdapterFactory.forAPIKey(apiKeyVerifier, userIdField, expirationField);
635
+ await RouteGuards_1.configure(profile, permissionSource, tokenValidator, authConfig);
636
+ }
637
+ /**
638
+ * Factory method: Configure RouteGuards with CustomTokenVerificationPort for OAuth tokens.
639
+ * Provides setup for OAuth-based authentication with scope validation.
640
+ *
641
+ * @example
642
+ * OAuth token authentication with scope requirements:
643
+ * ```typescript
644
+ * interface OAuthUser {
645
+ * sub: string;
646
+ * email: string;
647
+ * scope: string[];
648
+ * exp: number;
649
+ * client_id: string;
650
+ * }
651
+ *
652
+ * const oauthVerifier: CustomTokenVerificationPort<OAuthUser> = {
653
+ * async verifyToken(token: string): Promise<OAuthUser> {
654
+ * const response = await fetch(`${OAUTH_INTROSPECT_URL}`, {
655
+ * method: 'POST',
656
+ * headers: { 'Authorization': `Bearer ${token}` },
657
+ * body: new URLSearchParams({ token })
658
+ * });
659
+ *
660
+ * const tokenInfo = await response.json();
661
+ * if (!tokenInfo.active) {
662
+ * throw new Error('Token is not active');
663
+ * }
664
+ *
665
+ * return tokenInfo as OAuthUser;
666
+ * }
667
+ * };
668
+ *
669
+ * await RouteGuards.configureWithOAuth(
670
+ * GuardSetup.production(),
671
+ * userPermissionSource,
672
+ * oauthVerifier,
673
+ * {
674
+ * tokenHeader: 'authorization',
675
+ * tokenPrefix: 'Bearer ',
676
+ * requireEmailVerification: false
677
+ * },
678
+ * ['read:profile', 'write:data'] // Required OAuth scopes
679
+ * );
680
+ * ```
681
+ */
682
+ static async configureWithOAuth(profile, permissionSource, oauthVerifier, authConfig, requiredScopes) {
683
+ // Create a properly configured adapter for OAuth tokens
684
+ const tokenValidator = CustomTokenVerificationPortAdapter_1.TokenVerificationAdapterFactory.forOAuth(oauthVerifier, requiredScopes);
685
+ await RouteGuards_1.configure(profile, permissionSource, tokenValidator, authConfig);
686
+ }
687
+ /**
688
+ * Factory method: Configure RouteGuards with a custom CustomTokenVerificationPort adapter.
689
+ * Provides maximum flexibility for custom token validation scenarios.
690
+ *
691
+ * @example
692
+ * Custom token validation with business-specific logic:
693
+ * ```typescript
694
+ * interface CustomUser {
695
+ * userId: string;
696
+ * tenantId: string;
697
+ * roles: string[];
698
+ * sessionExpiry: number;
699
+ * isVerified: boolean;
700
+ * }
701
+ *
702
+ * const customVerifier: CustomTokenVerificationPort<CustomUser> = {
703
+ * async verifyToken(token: string): Promise<CustomUser> {
704
+ * // Your custom verification logic
705
+ * return await verifyCustomToken(token);
706
+ * }
707
+ * };
708
+ *
709
+ * await RouteGuards.configureWithCustom(
710
+ * GuardSetup.production(),
711
+ * userPermissionSource,
712
+ * customVerifier,
713
+ * {
714
+ * tokenHeader: 'x-auth-token',
715
+ * tokenPrefix: 'Custom ',
716
+ * customValidation: async (token, user) => {
717
+ * return user.isVerified && user.tenantId === 'valid-tenant';
718
+ * }
719
+ * },
720
+ * {
721
+ * userIdExtractor: (user) => user.userId,
722
+ * expirationExtractor: (user) => user.sessionExpiry,
723
+ * additionalValidation: (user) => user.isVerified
724
+ * }
725
+ * );
726
+ * ```
727
+ */
728
+ static async configureWithCustom(profile, permissionSource, customVerifier, authConfig, adapterConfig) {
729
+ // Create a custom configured adapter
730
+ const tokenValidator = CustomTokenVerificationPortAdapter_1.TokenVerificationAdapterFactory.custom(customVerifier, adapterConfig);
731
+ await RouteGuards_1.configure(profile, permissionSource, tokenValidator, authConfig);
732
+ }
336
733
  // Private implementation methods
337
734
  createPlainPermissionGuard(permissions, options) {
338
735
  this.trackGuardCreation();