import type { UnidyClient } from "../api"; import { AuthHelpers } from "./auth-helpers"; export declare const DEFAULT_TOKEN_EXPIRATION_BUFFER_SECONDS = 10; /** * Decoded JWT payload for Unidy auth tokens. */ export interface TokenPayload { /** Unidy user id (subject). */ sub: string; /** Sign-in session id. */ sid: string; /** Expiration time (Unix seconds). */ exp: number; /** Issued-at time (Unix seconds). */ iat: number; /** Issuer. */ iss: string; /** Audience. */ aud: string; /** Nonce. */ nonce: string; /** Time of authentication (Unix seconds). */ auth_time: number; /** User email. */ email: string; /** Whether the email has been verified. */ email_verified: boolean; [key: string]: unknown; } /** * Auth-specific error with a machine-readable code and whether re-authentication is required. */ export type AuthError = Error & { code: "TOKEN_EXPIRED" | "REFRESH_FAILED" | "NO_TOKEN" | "INVALID_TOKEN" | "SIGN_IN_NOT_FOUND" | "SIGN_OUT_FAILED"; requiresReauth: boolean; }; /** * Singleton auth service: token validation, refresh, logout, and auth flow state (step, email, navigation). */ export declare class Auth { private static instance; private static initializationPromise; /** Helper methods for redirects, token refresh, and sign-in step recovery. */ readonly helpers: AuthHelpers; private _ready; private _resolveReady; private constructor(); /** * Resolves when the current auth operation has settled — either the initial session-restore * check-signed-in has completed, or a logout has finished. Await this before performing * one-shot auth state reads to avoid races with async session restore or in-flight sign-out. * * @example * ```js * const auth = await Auth.getInstance(); * await auth.ready; * console.log(authState.authenticated); // reliable after restore/logout settles * ``` */ get ready(): Promise; /** @internal — called by once checkSignedIn() completes. */ markReady(): void; private resetReady; /** Known error codes for email, magic code, password, and general auth flows. */ static Errors: { readonly email: { readonly NOT_FOUND: "account_not_found"; }; readonly general: { readonly ACCOUNT_LOCKED: "account_locked"; readonly SIGN_IN_ALREADY_PROCESSED: "sign_in_already_processed"; readonly SIGN_IN_EXPIRED: "sign_in_expired"; readonly SIGN_IN_NOT_FOUND: "sign_in_not_found"; }; readonly magicCode: { readonly EXPIRED: "magic_code_expired"; readonly NOT_VALID: "magic_code_not_valid"; readonly RECENTLY_CREATED: "magic_code_recently_created"; readonly USED: "magic_code_used"; }; readonly password: { readonly INVALID: "invalid_password"; readonly NOT_SET: "password_not_set"; readonly RESET_PASSWORD_ALREADY_SENT: "reset_password_already_sent"; }; readonly passwordReset: { readonly PASSWORD_TOO_WEAK: "password_too_weak"; }; }; /** * Returns the singleton Auth instance, initializing it (and waiting for config) if needed. * Multiple concurrent callers share the same in-flight initialization promise so that * initialize() — and therefore recoverSignInStep() — is never called more than once. */ static getInstance(): Promise; /** * Creates and configures the singleton Auth instance (redirect handling, reset-password, token check, step recovery). * Idempotent: returns existing instance if already initialized. * * @param client - Unidy API client used for auth requests. */ static initialize(client: UnidyClient): Promise; /** Whether the Auth singleton has been initialized. */ static isInitialized(): boolean; /** * Checks whether a JWT token is valid and not expired. * * @param token - The JWT token to validate. Can be a raw JWT string, a decoded TokenPayload, or null. * @param expirationBuffer - Number of seconds before actual expiration to consider the token invalid, used to prevent race conditions with preemptive token refresh. Defaults to 10 seconds. * @returns `true` if the token is valid and won't expire within the buffer period, `false` otherwise. * @throws Error if expirationBuffer is not positive number */ isTokenValid(token: string | TokenPayload | null, expirationBuffer?: number): boolean; /** Returns whether the user has a valid token (after refresh if needed). */ isAuthenticated(): Promise; /** * Returns a valid access token, refreshing it if expired. Use this for authenticated API calls. * * @returns The JWT string, or an AuthError if refresh fails or no token is available. */ getToken(): Promise; /** * Returns the decoded JWT payload for the current user, or null if not authenticated or decode fails. */ userTokenPayload(): Promise; /** * Logs the user out (backend call when possible) and clears local auth state. Local state is always cleared even if backend fails. * * @param globalLogout - When `true`, requests termination of all sessions on the server (global logout). Defaults to `true` only when the session was detected server-side (SSO); `false` for SDK-initiated logins. Pass `true` explicitly to force a full session termination regardless of how the user authenticated. * @returns `true` on success, or an AuthError if backend logout failed. */ logout(globalLogout?: boolean): Promise; /** Email from the current auth flow or session, if available. */ getEmail(): string | null; /** Whether the auth flow can navigate back to the previous step. */ canGoBack(): boolean; /** Navigates the auth flow back one step. Returns whether the navigation was performed. */ goBack(): boolean; /** Resets the auth flow to the initial step. */ restart(): void; /** Current step identifier of the auth flow (e.g. "email", "magic_code"). */ getCurrentStep(): string | undefined; /** Builds an AuthError with the given message, code, and requiresReauth flag. */ private createAuthError; }