@analog-tools/auth
Version:
Authentication module for AnalogJS applications
125 lines (124 loc) • 4.15 kB
TypeScript
import { H3Event } from 'h3';
import { AnalogAuthConfig } from '../types/auth.types';
/**
* Service for handling OAuth authentication in a Backend-for-Frontend pattern
*/
export declare class OAuthAuthenticationService {
private logger;
private inflightRefreshes;
constructor(config: AnalogAuthConfig);
private readonly config;
private openIDConfigCache;
private configLastFetched;
private readonly CONFIG_CACHE_TTL;
private TOKEN_REFRESH_SAFETY_MARGIN;
private normalizedWhitelistExtensions;
private jwks?;
private jwksUri?;
/**
* Validate that the service has been properly initialized
* @throws Error if mandatory configuration is missing
*/
private validateConfiguration;
/**
* Initialize session for the request
*/
initSession(event: H3Event): Promise<void>;
getConfig(): AnalogAuthConfig;
/**
* Safely access a configuration value
* @param key The configuration key to retrieve
* @param fallbackValue Optional fallback value if the config value doesn't exist
* @returns The configuration value or fallback value
* @throws Error if the configuration value doesn't exist and no fallback is provided
*/
getConfigValue<K extends keyof AnalogAuthConfig>(key: K, fallbackValue?: AnalogAuthConfig[K]): AnalogAuthConfig[K];
/**
* Check if the route is unprotected
* @param path The request path
* @returns True if the route is unprotected, false otherwise
*/
isUnprotectedRoute(path: string): boolean;
/**
* Get OAuth authorization URL for login
*/
getAuthorizationUrl(params: {
state: string;
codeChallenge: string;
nonce: string;
redirectUri?: string;
}): Promise<string>;
/**
* Exchange authorization code for tokens
*/
private exchangeCodeForTokens;
/**
* Refresh access token using refresh token
*/
private refreshTokens;
private refreshTokensDeduped;
/**
* Get user info from OAuth provider with improved error handling and retry logic
*/
private getUserInfo;
/**
* Verify an OIDC ID token: signature (via the provider's JWKS), `iss`, `aud`,
* `exp`/`nbf`, the per-login `nonce`, `azp` (when present), and — when the
* provider sends it — `at_hash` binding the token to `accessToken`. Returns
* the verified claims
* so the caller can anchor identity in the cryptographically validated token.
*/
private validateIdToken;
/**
* Handle OAuth callback
*/
handleCallback(event: H3Event, code: string, state: string): Promise<{
user: any;
tokens: any;
}>;
private resolveUserIdentity;
private resolveSessionIdentity;
private invalidateOtherUserSessions;
/**
* Calculate if token needs refresh based on safety margin
* @param expiresAt Timestamp when token expires
* @returns True if token should be refreshed
*/
private shouldRefreshToken;
/**
* Serverless-compatible method to refresh expiring tokens
* This should be called by a scheduled function/CRON job
* rather than using setInterval which doesn't work reliably in serverless
*/
refreshExpiringTokens(): Promise<{
refreshed: number;
failed: number;
total: number;
}>;
/**
* Check if user is authenticated
*/
isAuthenticated(event: H3Event): Promise<boolean>;
/**
* Get authenticated user
*/
getAuthenticatedUser(event: H3Event): Promise<any>;
/**
* Revoke an access token
*/
private revokeToken;
/**
* Logout user
*/
logout(event: H3Event): Promise<string>;
/**
* Fetch OpenID Configuration from the well-known endpoint
*/
private getOpenIDConfiguration;
/**
* Validate a fetched OpenID configuration before trusting its endpoints:
* the document's `issuer` must match the configured issuer (OIDC Discovery
* §4.3), and every advertised endpoint we use must be https (localhost aside).
*/
private assertTrustedOpenIDConfiguration;
}