import OidcProfile from "./schemas/OidcProfile"; import OidcTokenSet from "./schemas/OidcTokenSet"; import { OidcProviderConfig } from "./OidcProviderConfig"; /** * OIDC error information passed to onAuthError callback */ export interface OidcError { /** * Error code (e.g., "invalid_state", "access_denied", "token_exchange_failed") */ code: string; /** * Human-readable error message */ message: string; /** * Additional error details for debugging */ details?: any; } /** * Response from onAuthSuccess callback * Must include JWT token generated by the application via jwt-auth-plugin */ export interface AuthSuccessCallbackResponse { /** * User object from your application * Should include _id field for connection storage */ user: any; /** * JWT token for your application (not the OIDC tokens!) * Generated using ctx.plugins.jwtAuth.createToken() */ token: string; /** * Optional redirect URL after authentication * Plugin will append #token=... to this URL */ redirectUrl?: string; } /** * Response from onAuthError callback */ export interface AuthErrorCallbackResponse { /** * Optional redirect URL for error page * e.g., "/login?error=authentication_failed" */ redirectUrl?: string; } /** * Configuration options for OIDC Plugin with JWT integration * * The plugin depends on @flink-app/jwt-auth-plugin being installed and configured. * The onAuthSuccess callback receives the Flink context as a second parameter, * allowing the application to generate JWT tokens using ctx.plugins.jwtAuth.createToken(). */ export interface OidcPluginOptions { /** * OIDC provider configurations * Key = provider name (used in URLs: /oidc/{provider}/initiate) * Value = provider configuration * * At least one provider must be configured. * * Example: * { * acme: { * issuer: "https://idp.acme.com", * clientId: "...", * clientSecret: "...", * callbackUrl: "https://myapp.com/oidc/acme/callback", * discoveryUrl: "https://idp.acme.com/.well-known/openid-configuration" * }, * contoso: { * issuer: "https://login.contoso.com", * clientId: "...", * clientSecret: "...", * callbackUrl: "https://myapp.com/oidc/contoso/callback" * } * } */ providers: Record; /** * Whether to store OIDC tokens for future API access * If false, tokens are discarded after authentication (auth-only mode) * If true, encrypted tokens are stored in MongoDB for later use * * Default: false * * Set to true if you need to: * - Call IdP APIs on behalf of users * - Access user's resources at the IdP * - Use refresh tokens to maintain long-term access */ storeTokens?: boolean; /** * Callback invoked after successful OIDC authentication * * Application responsibilities: * 1. Find or create user based on OIDC profile (JIT provisioning) * 2. Link OIDC provider to user account * 3. Generate JWT token using ctx.plugins.jwtAuth.createToken(payload, roles) * 4. Return user object, JWT token, and optional redirect URL * * @param params - OIDC profile, claims, provider name, and tokens (if storeTokens enabled) * @param ctx - Flink context with access to repos and plugins (including jwtAuth) * @returns User object, JWT token, and optional redirect URL * * Example: * ```typescript * onAuthSuccess: async ({ profile, claims, provider }, ctx) => { * // Find user by OIDC subject + issuer * let user = await ctx.repos.userRepo.getOne({ * 'oidcConnections.subject': claims.sub, * 'oidcConnections.issuer': claims.iss * }); * * if (!user) { * // JIT provisioning - create new user * user = await ctx.repos.userRepo.create({ * email: claims.email, * name: claims.name, * oidcConnections: [{ * issuer: claims.iss, * subject: claims.sub, * provider * }] * }); * } * * // Generate JWT token * const token = await ctx.plugins.jwtAuth.createToken( * { userId: user._id, email: user.email }, * ['user'] * ); * * return { * user, * token, * redirectUrl: '/dashboard' * }; * } * ``` */ onAuthSuccess: (params: { /** * Normalized user profile from OIDC claims */ profile: OidcProfile; /** * Raw OIDC claims from ID token * Contains all standard and custom claims */ claims: Record; /** * Provider name (e.g., "acme", "contoso") */ provider: string; /** * OIDC tokens (only if storeTokens: true) * Includes accessToken, idToken, refreshToken */ tokens?: OidcTokenSet; }, ctx: any) => Promise; /** * Callback invoked on OIDC authentication errors * * Application responsibilities: * - Log error for debugging * - Optionally provide redirect URL for error page * * @param params - Error information and provider name * @returns Optional redirect URL for error page * * Example: * ```typescript * onAuthError: async ({ error, provider }) => { * console.error(`OIDC error for ${provider}:`, error); * * if (error.code === 'access_denied') { * return { * redirectUrl: '/login?error=user_cancelled' * }; * } * * return { * redirectUrl: '/login?error=authentication_failed' * }; * } * ``` */ onAuthError?: (params: { error: OidcError; provider: string; }) => Promise; /** * Dynamic provider loader callback * * Called when a provider is accessed but not in the static providers config. * Allows loading provider configurations from database at runtime. * * Use this for multi-tenant scenarios where each organization has different IdPs. * * @param providerName - Name of the provider to load * @returns Provider configuration or null if not found * * Example: * ```typescript * providerLoader: async (providerName) => { * const config = await ctx.repos.oidcProviderRepo.getByName(providerName); * if (!config || !config.enabled) { * return null; * } * return { * issuer: config.issuer, * clientId: config.clientId, * clientSecret: decryptSecret(config.clientSecret), * callbackUrl: config.callbackUrl, * discoveryUrl: config.discoveryUrl, * scope: config.scope * }; * } * ``` */ providerLoader?: (providerName: string) => Promise; /** * Custom collection name for OIDC sessions * Default: 'oidc_sessions' */ sessionsCollectionName?: string; /** * Custom collection name for OIDC connections (if storeTokens enabled) * Default: 'oidc_connections' */ connectionsCollectionName?: string; /** * Session TTL in seconds * Sessions are automatically cleaned up after this duration * Default: 600 (10 minutes) * * This is the maximum time a user has to complete the OIDC flow * (from /initiate to /callback). Increase if users need more time. */ sessionTTL?: number; /** * Encryption key for encrypting stored OIDC tokens * If not provided, will be derived from first configured provider's client secret * * Recommended: Use a dedicated encryption key from environment variables * Must be at least 32 characters * * Example: process.env.OIDC_ENCRYPTION_KEY */ encryptionKey?: string; /** * Whether to register OIDC routes automatically * If false, you must manually handle OIDC flow * Default: true * * Set to false if you want to implement custom route handling * or use a custom URL structure. */ registerRoutes?: boolean; } //# sourceMappingURL=OidcPluginOptions.d.ts.map