UNPKG

@noony-serverless/core

Version:

A Middy base framework compatible with Firebase and GCP Cloud Functions with TypeScript

271 lines 9.39 kB
/** * CustomTokenVerificationPort Adapter * * Bridges the CustomTokenVerificationPort interface from AuthenticationMiddleware * to the RouteGuards TokenValidator interface, enabling code reuse and unified * token validation across the entire Noony Framework. * * Key Features: * - Seamless integration between authentication systems * - Maintains type safety through generics * - Supports any token validation implementation (JWT, OAuth, API keys, etc.) * - Preserves all existing RouteGuards functionality * - Zero-overhead abstraction with full performance * * Benefits: * - One authentication interface to implement and maintain * - Consistent patterns across AuthenticationMiddleware and RouteGuards * - Backward compatibility with existing RouteGuards implementations * - Simplified setup for authentication workflows * * @example * Bridge a JWT verification port to RouteGuards: * ```typescript * import { CustomTokenVerificationPort } from '@/middlewares/authenticationMiddleware'; * import { CustomTokenVerificationPortAdapter } from '@/middlewares/guards/adapters'; * * // Define your user type * interface User { * id: string; * email: string; * roles: string[]; * sub: string; // JWT subject * exp: number; // JWT expiration * iat: number; // Issued at * } * * // Implement token verification once * const jwtVerifier: CustomTokenVerificationPort<User> = { * async verifyToken(token: string): Promise<User> { * const payload = jwt.verify(token, process.env.JWT_SECRET!) as any; * return { * id: payload.sub, * email: payload.email, * roles: payload.roles || [], * sub: payload.sub, * exp: payload.exp, * iat: payload.iat * }; * } * }; * * // Create adapter for RouteGuards * const tokenValidator = new CustomTokenVerificationPortAdapter( * jwtVerifier, * { * userIdExtractor: (user: User) => user.id, * expirationExtractor: (user: User) => user.exp * } * ); * * // Use with RouteGuards * await RouteGuards.configure( * GuardSetup.production(), * userPermissionSource, * tokenValidator, // Works seamlessly! * authConfig * ); * ``` * * @example * API key verification with custom user structure: * ```typescript * interface APIKeyUser { * keyId: string; * permissions: string[]; * organization: string; * expiresAt: number; * isActive: boolean; * } * * const apiKeyVerifier: CustomTokenVerificationPort<APIKeyUser> = { * async verifyToken(token: string): Promise<APIKeyUser> { * const keyData = await validateAPIKey(token); * if (!keyData || !keyData.isActive) { * throw new Error('Invalid or inactive API key'); * } * return keyData; * } * }; * * // Adapter with custom extractors * const apiTokenValidator = new CustomTokenVerificationPortAdapter( * apiKeyVerifier, * { * userIdExtractor: (user: APIKeyUser) => user.keyId, * expirationExtractor: (user: APIKeyUser) => user.expiresAt, * additionalValidation: (user: APIKeyUser) => user.isActive * } * ); * * // Seamlessly works with RouteGuards * await RouteGuards.configure( * GuardSetup.production(), * userPermissionSource, * apiTokenValidator, * authConfig * ); * ``` * * @example * OAuth token verification: * ```typescript * interface OAuthUser { * sub: string; // OAuth subject * email: string; * scope: string[]; // OAuth scopes * exp: number; * client_id: string; * } * * const oauthVerifier: CustomTokenVerificationPort<OAuthUser> = { * async verifyToken(token: string): Promise<OAuthUser> { * // Validate with OAuth provider * const response = await fetch(`${OAUTH_INTROSPECT_URL}`, { * method: 'POST', * headers: { 'Authorization': `Bearer ${token}` } * }); * * const tokenInfo = await response.json(); * if (!tokenInfo.active) { * throw new Error('Token is not active'); * } * * return tokenInfo as OAuthUser; * } * }; * * const oauthTokenValidator = new CustomTokenVerificationPortAdapter( * oauthVerifier, * { * userIdExtractor: (user: OAuthUser) => user.sub, * expirationExtractor: (user: OAuthUser) => user.exp * } * ); * ``` * * @author Noony Framework Team * @version 1.0.0 */ import { CustomTokenVerificationPort } from '../../authenticationMiddleware'; import { TokenValidator } from '../guards/FastAuthGuard'; /** * Configuration options for the CustomTokenVerificationPort adapter. * Provides flexible configuration for extracting required data from * different user object structures. */ export interface AdapterConfig<T> { /** * Extract user ID from the verified user object. * This ID will be used for permission lookups and caching. */ userIdExtractor: (user: T) => string; /** * Extract token expiration timestamp from the user object. * Should return Unix timestamp (seconds since epoch). * * @param user - Verified user object * @returns Unix timestamp or undefined if no expiration */ expirationExtractor?: (user: T) => number | undefined; /** * Optional additional validation after token verification. * Allows custom business logic validation on the verified user. * * @param user - Verified user object * @returns true if user passes additional validation */ additionalValidation?: (user: T) => boolean | Promise<boolean>; /** * Custom error message for token validation failures. * If not provided, uses the original error from the verification port. */ errorMessage?: string; } /** * Adapter class that bridges CustomTokenVerificationPort to TokenValidator. * Enables seamless integration between AuthenticationMiddleware and RouteGuards * while maintaining full type safety and performance. * * @template T - The user type returned by the CustomTokenVerificationPort */ export declare class CustomTokenVerificationPortAdapter<T> implements TokenValidator { private readonly verificationPort; private readonly config; constructor(verificationPort: CustomTokenVerificationPort<T>, config: AdapterConfig<T>); /** * Validate and decode token using the wrapped CustomTokenVerificationPort. * * @param token - JWT token string to validate * @returns Validation result with decoded user data */ validateToken(token: string): Promise<{ valid: boolean; decoded?: T; error?: string; }>; /** * Extract user ID from the decoded token/user data. * Uses the configured userIdExtractor function. * * @param decoded - Decoded user data from validateToken * @returns User ID string */ extractUserId(decoded: T): string; /** * Check if the token is expired based on the decoded data. * Uses the configured expirationExtractor if available. * * @param decoded - Decoded user data from validateToken * @returns true if token is expired, false otherwise */ isTokenExpired(decoded: T): boolean; } /** * Helper factory functions for common token verification scenarios. * Provides pre-configured adapters for standard authentication patterns. */ export declare class TokenVerificationAdapterFactory { /** * Create adapter for standard JWT tokens with common claims. * Assumes the user object has 'sub' for user ID and 'exp' for expiration. * * @param verificationPort - JWT token verification port * @returns Configured adapter for JWT tokens */ static forJWT<T extends { sub: string; exp?: number; }>(verificationPort: CustomTokenVerificationPort<T>): CustomTokenVerificationPortAdapter<T>; /** * Create adapter for API key tokens with custom ID and expiration fields. * * @param verificationPort - API key verification port * @param userIdField - Field name for user/key ID (e.g., 'keyId', 'apiKeyId') * @param expirationField - Optional field name for expiration (e.g., 'expiresAt', 'exp') * @returns Configured adapter for API key tokens */ static forAPIKey<T extends Record<string, any>>(verificationPort: CustomTokenVerificationPort<T>, userIdField: keyof T, expirationField?: keyof T): CustomTokenVerificationPortAdapter<T>; /** * Create adapter for OAuth tokens with standard OAuth claims. * * @param verificationPort - OAuth token verification port * @param additionalScopes - Optional required OAuth scopes * @returns Configured adapter for OAuth tokens */ static forOAuth<T extends { sub: string; exp?: number; scope?: string[]; }>(verificationPort: CustomTokenVerificationPort<T>, additionalScopes?: string[]): CustomTokenVerificationPortAdapter<T>; /** * Create adapter with custom configuration. * Use this for non-standard token structures or complex validation logic. * * @param verificationPort - Token verification port * @param config - Custom adapter configuration * @returns Configured adapter with custom settings */ static custom<T>(verificationPort: CustomTokenVerificationPort<T>, config: AdapterConfig<T>): CustomTokenVerificationPortAdapter<T>; } //# sourceMappingURL=CustomTokenVerificationPortAdapter.d.ts.map