/** * OAuthManager - Manages OAuth tokens with automatic refresh and $Secret{} integration * * This utility allows developers to set up OAuth configurations once per app/product/env * combination, with automatic token refresh and secure storage via the Secrets system. * * @example * ```ts * // Set up OAuth with auto-refresh using ductape.api.run for token refresh * await ductape.api.oauth({ * product: 'my-product', * app: 'salesforce', * env: 'prd', * tokens: { * accessToken: initialAccessToken, * refreshToken: initialRefreshToken, * }, * expiresAt: tokenExpiry, * credentials: (tokens) => ({ * 'headers:Authorization': `Bearer ${tokens.accessToken}` * }), * onExpiry: async (currentTokens) => { * // Use ductape.api.run to call the refresh token action * const response = await ductape.api.run({ * product: 'my-product', * app: 'salesforce', * env: 'prd', * action: 'refresh-token', * input: { * 'body:grant_type': 'refresh_token', * 'body:refresh_token': currentTokens.refreshToken, * } * }); * * return { * tokens: { * accessToken: response.access_token, * refreshToken: response.refresh_token || currentTokens.refreshToken * }, * expiresIn: response.expires_in * }; * } * }); * * // Now all salesforce actions automatically include OAuth tokens * // and refresh automatically when expired * const result = await ductape.api.run({ * product: 'my-product', * app: 'salesforce', * env: 'prd', * action: 'get-contacts', * input: { limit: 10 } * }); * ``` */ import { SecretsService } from '../../secrets/secrets.service'; /** * OAuth tokens structure */ export interface IOAuthTokens { /** Access token for API requests */ accessToken: string; /** Refresh token for obtaining new access tokens */ refreshToken?: string; /** Any additional token data the user wants to store */ [key: string]: unknown; } /** * Result returned from onExpiry callback */ export interface IOAuthRefreshResult { /** New tokens */ tokens: IOAuthTokens; /** New expiration timestamp (Unix ms) or duration in seconds */ expiresAt?: number; /** Expiration duration in seconds (alternative to expiresAt) */ expiresIn?: number; } /** * Credentials builder function type */ export type CredentialsBuilder = (tokens: IOAuthTokens) => Record; /** * OAuth configuration */ export interface IOAuthConfig { /** Product tag */ product: string; /** App tag */ app: string; /** Environment slug */ env: string; /** Initial tokens (can be actual values or $Secret{} references) */ tokens: IOAuthTokens; /** Token expiration timestamp (Unix ms) */ expiresAt?: number; /** Token expiration duration in seconds (alternative to expiresAt) */ expiresIn?: number; /** Function that builds credentials from tokens */ credentials: CredentialsBuilder; /** Callback invoked when tokens expire */ onExpiry: (currentTokens: IOAuthTokens) => Promise; /** Buffer time in ms before actual expiry to trigger refresh (default: 60000 = 1 min) */ refreshBuffer?: number; } /** * Validation error thrown for invalid OAuth configurations */ export declare class OAuthError extends Error { readonly errorType: 'invalid_config' | 'refresh_failed' | 'expired' | 'not_found'; constructor(message: string, errorType: 'invalid_config' | 'refresh_failed' | 'expired' | 'not_found'); } /** * OAuthManager stores and manages OAuth configurations with automatic refresh * and $Secret{} integration for secure token storage. */ export declare class OAuthManager { /** Storage for OAuth states, keyed by product:app:env */ private states; /** Reference to secrets service for token storage */ private secretsService; /** * Set the secrets service reference */ setSecretsService(service: SecretsService): void; /** * Register an OAuth configuration for an app/product/env combination * * @param config - OAuth configuration * @throws OAuthError if configuration is invalid */ register(config: IOAuthConfig): Promise; /** * Get credentials for an app/product/env combination * Automatically refreshes tokens if expired * * @param product - Product tag * @param app - App tag * @param env - Environment slug * @returns Credentials object or undefined if not configured */ getCredentials(product: string, app: string, env: string): Promise | undefined>; /** * Refresh tokens for an app/product/env combination */ private refreshTokens; /** * Perform the actual token refresh */ private doRefresh; /** * Check if OAuth is configured for an app/product/env combination */ has(product: string, app: string, env: string): boolean; /** * Get current tokens (without triggering refresh) */ getTokens(product: string, app: string, env: string): IOAuthTokens | undefined; /** * Get token expiration time */ getExpiresAt(product: string, app: string, env: string): number | undefined; /** * Check if tokens are expired (without buffer) */ isExpired(product: string, app: string, env: string): boolean; /** * Force refresh tokens even if not expired */ forceRefresh(product: string, app: string, env: string): Promise; /** * Remove OAuth configuration for an app/product/env combination */ remove(product: string, app: string, env: string): boolean; /** * Clear all OAuth configurations */ clearAll(): void; /** * Get all registered product/app/env combinations */ list(): Array<{ product: string; app: string; env: string; expiresAt: number; }>; /** * Get the secret keys being used for a configuration */ getSecretKeys(product: string, app: string, env: string): Record | undefined; } /** * Singleton instance for convenience */ export declare const oauthManager: OAuthManager;