Auth API reference

Current emitted signatures and options for @db3.ai/app/auth.

On this pageSource-backed Markdown

Imports and examples

Import supported APIs from @db3.ai/app/auth. These signatures come from the staged package used by consumers. Relative filenames in declarations describe type dependencies; they are not extra supported deep imports.

Use the guide for setup, executable examples, failure handling and ownership. A signature is not proof that every deployment or provider has been exercised.

Account, provider and session operations

Account, provider and session operations
ts
import { type Database } from '../db/index.js';
import type { Config } from '../config/index.js';
import { AuthProvider } from './AuthProvider.js';
import { AuthToken, type AuthTokenUsage, type CreateAuthTokenOptions } from './AuthToken.js';
import { PasswordResetToken } from './PasswordResetToken.js';
import { type PasswordHash } from './passwordHash.js';
import { UserIdentity, type UserIdentityModel } from './UserIdentity.js';
import type * as auth from './contracts/index.js';
/**
 * Credentials accepted by the built-in password provider.
 *
 * Apps may include the configured identity field, usually `email`, alongside
 * the password so the auth service can locate the provider row.
 */
export interface PasswordCredentials {
    /**
     * Plaintext password submitted by the user.
     */
    password: string;
    /**
     * Additional credential fields, including the configured identity value.
     */
    [fieldName: string]: unknown;
}
/**
 * Input used when creating a user through the built-in password provider.
 */
export interface RegisterPasswordInput extends PasswordCredentials {
    /**
     * Additional user fields accepted by the configured identity model.
     */
    [fieldName: string]: unknown;
}
/**
 * Backwards-compatible alias for password credentials.
 */
export type AuthCredentials = PasswordCredentials;
/**
 * Backwards-compatible alias for password registration input.
 */
export type RegisterIdentityInput = RegisterPasswordInput;
/**
 * Request payload used to redeem a password reset token.
 *
 * Additional fields allow apps to include the configured identity value, such
 * as an email address, so token redemption can confirm the link belongs to the
 * submitted identity.
 */
export interface ResetPasswordInput {
    [fieldName: string]: unknown;
    token: string;
    password: string;
}
/**
 * Bearer token issued for an authenticated user.
 */
export interface IssuedAuthToken<TIdentity extends UserIdentity = UserIdentity> {
    /**
     * Token type used in HTTP Authorization headers.
     */
    type: 'Bearer';
    /**
     * Plaintext bearer token shown once to the caller.
     */
    token: string;
    /**
     * Absolute expiry time, or null for a non-expiring token.
     */
    expiresAt: Date | null;
    /**
     * Authenticated identity the token belongs to.
     */
    user: TIdentity;
}
/**
 * Password reset token issued for an identity.
 */
export interface IssuedPasswordResetToken<TIdentity extends UserIdentity = UserIdentity> {
    /**
     * Token purpose marker.
     */
    type: 'password_reset';
    /**
     * Plaintext reset token shown once to the caller.
     */
    token: string;
    /**
     * Absolute expiry time for the reset token.
     */
    expiresAt: Date;
    /**
     * Identity the reset token belongs to.
     */
    user: TIdentity;
}
/**
 * Options used when issuing a bearer token.
 */
export interface AuthTokenOptions extends CreateAuthTokenOptions {
    /**
     * Relative token lifetime in milliseconds. Null disables token expiry.
     */
    expiresInMs?: number | null;
}
export interface PasswordResetTokenOptions {
    /**
     * Absolute timestamp when the token should stop being usable.
     */
    expiresAt?: Date;
    /**
     * Relative token lifetime in milliseconds when an absolute expiry is not supplied.
     */
    expiresInMs?: number;
}
/**
 * Initial values accepted by an auth request context.
 */
export type AuthRequestContextValues = Map<string, unknown> | Record<string, unknown> | Iterable<readonly [string, unknown]>;
/**
 * Request-scoped storage used to isolate auth state between concurrent requests.
 */
export interface AuthRequestContext {
    /**
     * True when code is running inside an active request context.
     */
    active: boolean;
    /**
     * Runs a callback with optional initial request-scoped values.
     *
     * @param callback - Work to run inside the request context.
     * @param initialValues - Optional values to seed into the context.
     * @returns The callback result.
     */
    run<TResult>(callback: () => TResult, initialValues?: AuthRequestContextValues): TResult;
    /**
     * Reads a request-scoped value.
     *
     * @param key - Context key to read.
     * @returns Stored value, or undefined when missing.
     */
    get<TValue = unknown>(key: string): TValue | undefined;
    /**
     * Stores a request-scoped value.
     *
     * @param key - Context key to write.
     * @param value - Value to store.
     * @returns The stored value.
     */
    set<TValue>(key: string, value: TValue): TValue;
    /**
     * Reads a value or stores the factory result when missing.
     *
     * @param key - Context key to read or populate.
     * @param factory - Factory used when no value has been stored.
     * @returns Existing or newly-created value.
     */
    remember<TValue>(key: string, factory: () => TValue): TValue;
}
/**
 * Runtime options for the framework auth service.
 */
export interface AuthOptions<TIdentity extends UserIdentity = UserIdentity> {
    /**
     * Database wrapper used for auth persistence.
     */
    db: Database;
    /**
     * User identity model for the host app.
     */
    identityModel?: UserIdentityModel<TIdentity>;
    /**
     * Provider-link model. Override only when extending provider persistence.
     */
    providerModel?: typeof AuthProvider;
    /**
     * Authentication providers enabled for the app.
     */
    providers?: auth.AuthProviderRegistry<TIdentity>;
    /**
     * App config repository used to read `auth.providers` when explicit
     * providers are not supplied.
     */
    config?: Config;
    /**
     * Password hashing service for password provider credentials.
     */
    passwordHash?: PasswordHash;
    /**
     * Bearer token model.
     */
    tokenModel?: typeof AuthToken;
    /**
     * Default bearer token lifetime in milliseconds. Null disables expiry.
     */
    tokenLifetimeMs?: number | null;
    /**
     * Password reset token model.
     */
    passwordResetTokenModel?: typeof PasswordResetToken;
    /**
     * Default password reset token lifetime in milliseconds.
     */
    passwordResetTokenLifetimeMs?: number;
    /**
     * Request context used to isolate current-user state.
     */
    requestContext?: AuthRequestContext;
}
/**
 * Error thrown when registration would duplicate an existing identity.
 */
export declare class AuthIdentityExistsError extends Error {
    readonly field: string;
    readonly value: unknown;
    /**
     * Creates an identity duplication error.
     *
     * @param field - Logical identity field that collided.
     * @param value - Submitted identity value.
     */
    constructor(field: string, value: unknown);
}
/**
 * Error thrown when code attempts to use a disabled auth provider.
 */
export declare class AuthProviderNotConfiguredError extends Error {
    readonly provider: string;
    /**
     * Creates a provider configuration error.
     *
     * @param provider - Provider name that is not enabled.
     */
    constructor(provider: string);
}
/**
 * Error thrown when unlinking a provider would leave a user unable to log in.
 */
export declare class AuthLastProviderError extends Error {
    /**
     * Creates a last-provider removal error.
     */
    constructor();
}
export declare const AUTH_USER_CONTEXT_KEY = "auth.user";
/**
 * Authentication service for the current app/request scope.
 */
export declare class Auth<TIdentity extends UserIdentity = UserIdentity> {
    private fallbackAuthenticatedUser;
    private fallbackAuthenticatedToken;
    private readonly db;
    private readonly IdentityModel;
    private readonly ProviderModel;
    private readonly TokenModel;
    private readonly PasswordResetTokenModel;
    private readonly providerRegistry;
    private readonly passwordHash;
    private readonly tokenLifetimeMs;
    private readonly passwordResetTokenLifetimeMs;
    private readonly requestContext?;
    /**
     * Creates an auth service bound to a database and provider registry.
     *
     * @param options - Auth runtime options.
     */
    constructor(options: AuthOptions<TIdentity>);
    /**
     * Hashes a plaintext password using the configured auth password service.
     *
     * @param plainText - Plaintext password to hash.
     * @returns Stored password hash.
     */
    hashPassword(plainText: string): Promise<string>;
    /**
     * Verifies a plaintext password against a stored password hash.
     *
     * @param plainText - Plaintext password supplied by the user.
     * @param hash - Stored password hash.
     * @returns True when the password matches.
     */
    verifyPassword(plainText: string, hash: string): Promise<boolean>;
    /**
     * Returns configured authentication provider names.
     *
     * @returns Enabled provider names.
     */
    configuredProviders(): string[];
    /**
     * True when a user is currently authenticated.
     */
    get check(): boolean;
    /**
     * The currently authenticated user, or null when no user is authenticated.
     */
    get user(): TIdentity | null;
    /**
     * Returns the bearer-token record authenticated for the current request.
     */
    get token(): AuthToken | null;
    /**
     * Runs work inside an isolated auth scope.
     *
     * HTTP routes should use this so `auth.user` cannot bleed between concurrent
     * requests on the shared app singleton.
     *
     * @param user - User to expose as authenticated inside the callback.
     * @param callback - Work to run inside the auth scope.
     * @returns The callback result.
     */
    runWithUser<TResult>(user: TIdentity | null, callback: () => TResult): TResult;
    /**
     * Attempts to authenticate password credentials and stores the user on success.
     *
     * @param credentials - Password provider credentials.
     * @returns True when credentials authenticated successfully.
     */
    attempt(credentials: PasswordCredentials): Promise<boolean>;
    /**
     * Authenticates password credentials and returns the user on success.
     *
     * @param credentials - Password provider credentials.
     * @returns Authenticated user, or null when credentials fail.
     */
    authenticate(credentials: PasswordCredentials): Promise<TIdentity | null>;
    /**
     * Authenticates password credentials and returns the user on success.
     *
     * @param credentials - Password provider credentials.
     * @returns Authenticated user, or null when credentials fail.
     */
    authenticatePassword(credentials: PasswordCredentials): Promise<TIdentity | null>;
    /**
     * Authenticates credentials and creates a bearer token on success.
     *
     * @param credentials - Password provider credentials.
     * @param options - Token creation options.
     * @returns Issued token, or null when credentials fail.
     */
    issueToken(credentials: PasswordCredentials, options?: AuthTokenOptions): Promise<IssuedAuthToken<TIdentity> | null>;
    /**
     * Authenticates password credentials and creates a bearer token on success.
     *
     * @param credentials - Password provider credentials.
     * @param options - Token creation options.
     * @returns Issued token, or null when credentials fail.
     */
    issueTokenForPassword(credentials: PasswordCredentials, options?: AuthTokenOptions): Promise<IssuedAuthToken<TIdentity> | null>;
    /**
     * Authenticates through a configured provider and creates a bearer token.
     *
     * @param provider - Configured provider name.
     * @param input - Provider-specific credential payload.
     * @param options - Token creation options.
     * @returns Issued token, or null when provider verification fails.
     */
    issueTokenForProvider(provider: string, input: unknown, options?: AuthTokenOptions): Promise<IssuedAuthToken<TIdentity> | null>;
    /**
     * Creates a new password-backed identity and returns its first bearer token.
     *
     * @param input - User fields and password provider credential.
     * @param options - Token creation options.
     * @returns Issued token for the new user.
     */
    register(input: RegisterPasswordInput, options?: AuthTokenOptions): Promise<IssuedAuthToken<TIdentity>>;
    /**
     * Creates a new user and links the built-in password provider.
     *
     * @param input - User fields and password provider credential.
     * @param options - Token creation options.
     * @returns Issued token for the new user.
     */
    registerWithPassword(input: RegisterPasswordInput, options?: AuthTokenOptions): Promise<IssuedAuthToken<TIdentity>>;
    /**
     * Returns the authentication providers linked to a user.
     *
     * @param user - User whose providers should be loaded.
     * @returns Provider rows linked to the user.
     */
    providersFor(user: TIdentity): Promise<AuthProvider[]>;
    /**
     * Links a configured provider to an existing user.
     *
     * @param user - User receiving the new provider link.
     * @param provider - Configured provider name.
     * @param input - Provider-specific credential payload.
     * @returns Linked provider row, or null when verification fails.
     */
    linkProvider(user: TIdentity, provider: string, input: unknown): Promise<AuthProvider | null>;
    /**
     * Removes one provider from a user while preserving at least one login path.
     *
     * @param user - User whose provider should be removed.
     * @param providerIdOrName - Provider row id or provider name to remove.
     * @returns True when a provider row was deleted.
     */
    unlinkProvider(user: TIdentity, providerIdOrName: string): Promise<boolean>;
    /**
     * Creates or replaces the built-in password provider for a user.
     *
     * @param user - User who owns the password provider.
     * @param password - New plaintext password to hash and store.
     * @returns Saved password provider row.
     */
    setPasswordProvider(user: TIdentity, password: string): Promise<AuthProvider>;
    /**
     * Changes a user's password provider after verifying the current password.
     *
     * @param user - User whose password should change.
     * @param currentPassword - Current plaintext password for verification.
     * @param nextPassword - Replacement plaintext password.
     * @returns True when the password was changed.
     */
    changePasswordProvider(user: TIdentity, currentPassword: string, nextPassword: string): Promise<boolean>;
    /**
     * Authenticates through a non-password provider and stores the user on success.
     *
     * @param provider - Configured provider name.
     * @param input - Provider-specific credential payload.
     * @returns Authenticated user, or null when verification fails.
     */
    authenticateProvider(provider: string, input: unknown): Promise<TIdentity | null>;
    /**
     * Creates a single-use password reset token for an already-loaded identity.
     *
     * Callers should find the identity at the request boundary and pass the
     * loaded model here so token creation only owns token persistence.
     *
     * @param user - Identity receiving the reset token.
     * @param options - Reset token creation options.
     * @returns Issued password reset token.
     */
    createPasswordResetToken(user: TIdentity, options?: PasswordResetTokenOptions): Promise<IssuedPasswordResetToken<TIdentity>>;
    /**
     * Resets the password provider using a valid password reset token.
     *
     * @param input - Reset token, new password, and optional identity value.
     * @returns Identity whose password changed, or null when redemption fails.
     */
    resetPassword(input: ResetPasswordInput): Promise<TIdentity | null>;
    /**
     * Creates a bearer token for an already-authenticated identity.
     *
     * @param user - Identity receiving the bearer token.
     * @param options - Token creation options.
     * @returns Issued bearer token.
     */
    createToken(user: TIdentity, options?: AuthTokenOptions): Promise<IssuedAuthToken<TIdentity>>;
    /**
     * Authenticates a bearer token and stores the matching identity on success.
     *
     * @param token - Plaintext bearer token.
     * @param usage - Request metadata observed while authenticating the token.
     * @returns Authenticated identity, or null when the token is invalid.
     */
    authenticateToken(token: string, usage?: AuthTokenUsage): Promise<TIdentity | null>;
    /**
     * Returns active bearer sessions belonging to a user.
     *
     * @param user - Account whose sessions should be listed.
     * @returns Active, non-expired sessions ordered newest first.
     */
    tokensFor(user: TIdentity): Promise<AuthToken[]>;
    /**
     * Revokes one bearer session owned by a user.
     *
     * @param user - Account that owns the session.
     * @param tokenId - Auth token primary key.
     * @returns True when an active session was revoked.
     */
    revokeToken(user: TIdentity, tokenId: string): Promise<boolean>;
    /**
     * Revokes the bearer session authenticated for the current request.
     *
     * @returns True when the current session was revoked.
     */
    revokeCurrentToken(): Promise<boolean>;
    /**
     * Builds the request-context key used to memoize bearer-token authentication.
     *
     * @param tokenHash - Hashed bearer token.
     * @returns Request-context cache key.
     */
    private tokenContextKey;
    /**
     * Authenticates a pre-hashed bearer token against persistent auth records.
     *
     * @param tokenHash - Hashed bearer token.
     * @returns Authenticated identity, or null when the token is invalid.
     */
    private authenticateTokenHash;
    /**
     * Marks a user model as authenticated.
     *
     * @param user - User to mark as authenticated.
     * @returns The saved authenticated user.
     */
    login(user: TIdentity): Promise<TIdentity>;
    /**
     * Clears the authenticated user.
     */
    logout(): void;
    /**
     * Returns the authenticated user or throws when auth is missing.
     *
     * @returns The current authenticated user.
     */
    requireUser(): TIdentity;
    /**
     * Verifies provider-specific input and normalizes the returned profile.
     *
     * @param provider - Configured provider name.
     * @param input - Provider-specific credential payload.
     * @param user - Current user when linking a provider.
     * @returns Normalized provider profile, or null when verification fails.
     */
    private verifyProvider;
    /**
     * Resolves a configured provider or throws a configuration error.
     *
     * @param provider - Provider name to resolve.
     * @returns Provider configuration.
     */
    private requireProvider;
    /**
     * Resolves the configured password provider.
     *
     * @returns Password provider driver with password mutation helpers.
     */
    private passwordProvider;
    /**
     * Saves a verified provider profile onto a user account.
     *
     * @param user - User receiving the provider link.
     * @param profile - Verified provider profile.
     * @returns Saved provider row.
     */
    private saveLinkedProvider;
    /**
     * Finds a provider row by provider-owned identity.
     *
     * @param provider - Provider name.
     * @param providerUserId - Provider-owned account id.
     * @returns Matching provider row, or null.
     */
    private findProvider;
    /**
     * Loads the user attached to a provider row.
     *
     * @param provider - Persisted provider row.
     * @returns Linked identity, or null when missing.
     */
    private userForProvider;
    /**
     * Creates a user account from a verified external provider profile.
     *
     * @param profile - Verified provider profile.
     * @returns Created identity, or null when no email is available.
     */
    private createIdentityForProvider;
    /**
     * Backfills account-owned profile fields from a verified provider profile.
     *
     * Provider values are defaults only. Existing account values are preserved
     * so a later user-selected avatar is not overwritten during provider login.
     * The normal login save persists any backfilled values.
     *
     * @param user - Authenticated account receiving missing defaults.
     * @param profile - Verified provider profile.
     */
    private applyProviderProfileDefaults;
    /**
     * Stores the current authenticated user in request or fallback scope.
     *
     * @param user - User to expose as authenticated.
     */
    private setAuthenticatedUser;
    /**
     * Stores the authenticated token in request or fallback scope.
     *
     * @param token - Token record to expose for session management.
     */
    private setAuthenticatedToken;
    /**
     * Runs a callback with a temporary fallback user outside request scope.
     *
     * @param user - User to expose during the callback.
     * @param callback - Work to run with the temporary user.
     * @returns The callback result.
     */
    private runWithFallbackUser;
    /**
     * Finds an identity by the configured identity field.
     *
     * @param input - Payload containing the configured identity value.
     * @returns Matching identity, or null.
     */
    private findIdentity;
    /**
     * Checks whether password reset input belongs to the loaded user.
     *
     * @param input - Reset password payload.
     * @param user - User loaded from the reset token.
     * @returns True when the submitted identity is absent or matches the token user.
     */
    private passwordResetIdentityMatches;
    /**
     * Reads a user primary key as a non-empty string.
     *
     * @param user - User model to inspect.
     * @returns Primary key string, or null when missing.
     */
    private userPrimaryKey;
    /**
     * Reads the configured identity value from a user.
     *
     * @param user - User model to inspect.
     * @returns Normalized identity value, or null when missing.
     */
    private userIdentityValue;
    /**
     * Reads the configured identity value from a payload.
     *
     * @param input - Payload to inspect.
     * @returns Normalized identity value, or null when missing.
     */
    private normalizedIdentity;
    /**
     * Calculates the default bearer token expiry.
     *
     * @param expiresInMs - Optional token lifetime override.
     * @returns Absolute expiry time, or null for a non-expiring token.
     */
    private defaultTokenExpiry;
    /**
     * Calculates the default password reset token expiry.
     *
     * @param expiresInMs - Optional reset token lifetime override.
     * @returns Absolute expiry time.
     */
    private defaultPasswordResetTokenExpiry;
}

Account model

Account model
ts
import { ActiveRecord, type ActiveRecordClass, type FieldBuilder } from '../db/index.js';
type RecoveryCodes = string[];
export type UserIdentityModel<TIdentity extends UserIdentity = UserIdentity> = ActiveRecordClass<TIdentity> & {
    identityField: string;
};
/**
 * Auth-owned base user model.
 *
 * Apps can extend this model to add domain-specific fields and behaviour while
 * the auth package keeps ownership of account identity fields. Credential
 * storage lives on `AuthProvider` rows so users can link multiple login methods.
 */
export declare class UserIdentity extends ActiveRecord {
    static table: string;
    static primaryKey: string;
    static identityField: string;
    static fields(field: FieldBuilder): {
        id: import("../db/index.js").UlidField;
        name: import("../db/index.js").StringField;
        email: import("../db/index.js").EmailField;
        emailVerifiedAt: import("../db/index.js").TimestampField;
        avatarUrl: import("../db/index.js").StringField;
        rememberToken: import("../db/index.js").StringField;
        createdAt: import("../db/index.js").TimestampField;
        updatedAt: import("../db/index.js").TimestampField;
        twoFactorSecret: import("../db/index.js").TextField;
        twoFactorRecoveryCodes: import("../db/index.js").JsonStringField<RecoveryCodes>;
        twoFactorConfirmedAt: import("../db/index.js").TimestampField;
        lastLoginAt: import("../db/index.js").TimestampField;
    };
    id: string | null;
    name: string | null;
    email: string | null;
    emailVerifiedAt: Date | null;
    avatarUrl: string | null;
    rememberToken: string | null;
    createdAt: Date | null;
    updatedAt: Date | null;
    twoFactorSecret: string | null;
    twoFactorRecoveryCodes: RecoveryCodes | null;
    twoFactorConfirmedAt: Date | null;
    lastLoginAt: Date | null;
    get emailDomain(): string | null;
    markEmailVerified(date?: Date): void;
}
export {};

Provider model and safe summary

Provider model and safe summary
ts
import { ActiveRecord, PasswordField, type FieldBuilder } from '../db/index.js';
import type * as auth from './contracts/index.js';
import { type PasswordHash } from './passwordHash.js';
export declare const PASSWORD_AUTH_PROVIDER = "password";
/** Safe provider metadata suitable for account-management screens. */
export interface AuthProviderSummary {
    /** Persistent provider-row identifier used for scoped removal. */
    id: string;
    /** Stable provider name such as password or google. */
    provider: string;
    /** Human-friendly provider label. */
    label: string | null;
    /** Email address reported or owned by the provider. */
    email: string | null;
    /** Avatar URL reported by the provider. */
    avatarUrl: string | null;
    /** Most recent successful login through this provider. */
    lastLoginAt: string | null;
    /** Time the provider was linked to the account. */
    createdAt: string | null;
}
/**
 * Persisted authentication method linked to one user account.
 *
 * Password, Google, magic-link, and future login mechanisms all share this
 * model. Provider-specific verification happens in the auth service or a
 * provider driver; this model owns the durable account-to-provider link.
 */
export declare class AuthProvider extends ActiveRecord {
    static table: string;
    static primaryKey: string;
    static comment: string;
    /**
     * Defines the provider link, credential, and display metadata columns.
     *
     * @param field - Framework field builder.
     * @returns Field definitions for the auth provider table.
     */
    static fields(field: FieldBuilder): {
        id: import("../db/index.js").UlidField;
        userId: import("../db/index.js").StringField;
        provider: import("../db/index.js").StringField;
        providerUserId: import("../db/index.js").StringField;
        label: import("../db/index.js").StringField;
        email: import("../db/index.js").EmailField;
        emailVerifiedAt: import("../db/index.js").TimestampField;
        name: import("../db/index.js").StringField;
        avatarUrl: import("../db/index.js").StringField;
        password: PasswordField;
        profile: import("../db/index.js").JsonStringField<Record<string, unknown>>;
        lastLoginAt: import("../db/index.js").TimestampField;
        createdAt: import("../db/index.js").TimestampField;
        updatedAt: import("../db/index.js").TimestampField;
    };
    /**
     * Applies normalized provider metadata to this row.
     *
     * @param profile - Provider profile returned by a driver.
     */
    applyProfile(profile: auth.AuthProviderProfile): void;
    /**
     * Marks this provider as used for authentication.
     *
     * @param date - Login time to store.
     */
    markUsed(date?: Date): void;
    /**
     * Returns true when this provider stores a local password credential.
     *
     * @returns Whether this row is the built-in password provider.
     */
    isPasswordProvider(): boolean;
    /**
     * Returns settings-safe provider metadata.
     *
     * Password hashes, provider-owned identifiers, and raw profile metadata are
     * deliberately excluded from this projection.
     *
     * @returns Provider summary for account-management APIs.
     */
    toSummary(): AuthProviderSummary;
    /**
     * Verifies a plaintext password against the provider password hash.
     *
     * @param plainText - Password supplied by the user.
     * @param passwordHash - Password hashing service to use.
     * @returns True when the password matches this provider.
     */
    verifyPassword(plainText: string, passwordHash?: PasswordHash): Promise<boolean>;
    id: string | null;
    userId: string | null;
    provider: string | null;
    providerUserId: string | null;
    label: string | null;
    email: string | null;
    emailVerifiedAt: Date | null;
    name: string | null;
    avatarUrl: string | null;
    password: null;
    profile: Record<string, unknown> | null;
    lastLoginAt: Date | null;
    createdAt: Date | null;
    updatedAt: Date | null;
}

Token model and safe session

Token model and safe session
ts
import { ActiveRecord, type FieldBuilder } from '../db/index.js';
export interface CreateAuthTokenOptions {
    /** Human-friendly session name displayed to the user. */
    name?: string;
    /** Absolute token expiry. Null creates a non-expiring token. */
    expiresAt?: Date | null;
    /** Latest client IP address observed for the session. */
    ipAddress?: string | null;
    /** Raw user-agent string captured when the session was created. */
    userAgent?: string | null;
    /** Parsed browser name, such as Chrome or Mobile Safari. */
    browser?: string | null;
    /** Parsed operating-system name, such as macOS or iOS. */
    operatingSystem?: string | null;
    /** Parsed device label, such as iPhone or Desktop. */
    device?: string | null;
}
/**
 * Request metadata refreshed when a bearer token is authenticated.
 */
export interface AuthTokenUsage {
    /** Latest client IP address observed for the session. */
    ipAddress?: string | null;
}
/**
 * Safe session information suitable for account-management APIs.
 */
export interface AuthSessionData {
    id: string;
    name: string | null;
    ipAddress: string | null;
    browser: string | null;
    operatingSystem: string | null;
    device: string | null;
    expiresAt: string | null;
    lastUsedAt: string | null;
    createdAt: string | null;
}
/**
 * Persisted bearer token for API/mobile clients.
 *
 * The raw token is only returned to the client once. The database stores a
 * SHA-256 hash so a token table leak does not expose immediately usable bearer
 * tokens.
 */
export declare class AuthToken extends ActiveRecord {
    static table: string;
    static primaryKey: string;
    static fields(field: FieldBuilder): {
        id: import("../db/index.js").UlidField;
        userId: import("../db/index.js").StringField;
        tokenHash: import("../db/index.js").StringField;
        name: import("../db/index.js").StringField;
        ipAddress: import("../db/index.js").StringField;
        userAgent: import("../db/index.js").TextField;
        browser: import("../db/index.js").StringField;
        operatingSystem: import("../db/index.js").StringField;
        device: import("../db/index.js").StringField;
        expiresAt: import("../db/index.js").TimestampField;
        lastUsedAt: import("../db/index.js").TimestampField;
        revokedAt: import("../db/index.js").TimestampField;
        createdAt: import("../db/index.js").TimestampField;
    };
    id: string | null;
    userId: string | null;
    tokenHash: string | null;
    name: string | null;
    ipAddress: string | null;
    userAgent: string | null;
    browser: string | null;
    operatingSystem: string | null;
    device: string | null;
    expiresAt: Date | null;
    lastUsedAt: Date | null;
    revokedAt: Date | null;
    createdAt: Date | null;
    /**
     * Generates a cryptographically random bearer token.
     *
     * @returns Plaintext bearer token shown to the client once.
     */
    static generatePlainTextToken(): string;
    /**
     * Hashes a plaintext bearer token for persistent lookup.
     *
     * @param token - Plaintext bearer token.
     * @returns SHA-256 token hash.
     */
    static hashToken(token: string): string;
    /**
     * Returns whether the token has passed its expiry time.
     *
     * @param date - Comparison time.
     * @returns True when the session is expired.
     */
    isExpired(date?: Date): boolean;
    /**
     * Returns whether the session can currently authenticate.
     *
     * @param date - Comparison time.
     * @returns True when the token is neither revoked nor expired.
     */
    isActive(date?: Date): boolean;
    /**
     * Records token activity and optional request metadata.
     *
     * @param date - Activity time.
     * @param usage - Request metadata observed during authentication.
     */
    markUsed(date?: Date, usage?: AuthTokenUsage): void;
    /**
     * Permanently revokes this session.
     *
     * @param date - Revocation time.
     */
    revoke(date?: Date): void;
    /**
     * Returns safe session information without the token hash or raw user agent.
     *
     * @returns Session data for account-management APIs.
     */
    toSessionData(): AuthSessionData;
}

Reset tokens

Reset tokens
ts
import { ActiveRecord, type FieldBuilder } from '../db/index.js';
/**
 * Single-use password reset token.
 *
 * The raw token is only sent in email. The database stores a SHA-256 hash so
 * reset-token table leaks do not expose usable reset links.
 */
export declare class PasswordResetToken extends ActiveRecord {
    static table: string;
    static primaryKey: string;
    static fields(field: FieldBuilder): {
        id: import("../db/index.js").UlidField;
        userId: import("../db/index.js").StringField;
        email: import("../db/index.js").EmailField;
        tokenHash: import("../db/index.js").StringField;
        expiresAt: import("../db/index.js").TimestampField;
        usedAt: import("../db/index.js").TimestampField;
        createdAt: import("../db/index.js").TimestampField;
    };
    id: string | null;
    userId: string | null;
    email: string | null;
    tokenHash: string | null;
    expiresAt: Date | null;
    usedAt: Date | null;
    createdAt: Date | null;
    static generatePlainTextToken(): string;
    static hashToken(token: string): string;
    isExpired(date?: Date): boolean;
    isUsed(): boolean;
    isUsable(date?: Date): boolean;
    markUsed(date?: Date): void;
}

Provider verification contract

Provider verification contract
ts
import type { UserIdentity } from '../UserIdentity.js';
/**
 * Normalized identity details returned by an authentication provider.
 *
 * Provider drivers translate their own proof mechanism into this shape. The
 * auth service owns persistence and session issuance after the driver proves
 * that the caller controls the provider account.
 */
export interface AuthProviderProfile {
    /**
     * Stable provider name, such as `password`, `google`, or `magic_link`.
     */
    provider: string;
    /**
     * Stable provider-owned account id.
     *
     * For OAuth/OIDC providers this should be the provider subject/id, not an
     * email address. The built-in password and magic-link providers use the
     * normalized email address because the email inbox/account is the proof.
     */
    providerUserId: string;
    /**
     * Email address reported or proven by the provider.
     */
    email?: string | null;
    /**
     * When the provider proved the email address belongs to the user.
     */
    emailVerifiedAt?: Date | null;
    /**
     * Human-friendly provider account name.
     */
    name?: string | null;
    /**
     * Provider account avatar URL for account settings displays.
     */
    avatarUrl?: string | null;
    /**
     * Optional UI label for the linked provider row.
     */
    label?: string | null;
    /**
     * Safe provider metadata that callers may need to inspect later.
     */
    profile?: Record<string, unknown> | null;
}
/**
 * Pluggable authentication provider driver.
 *
 * Drivers perform provider-specific verification. They should not create users
 * or sessions; provider-owned helpers may update provider rows when the auth
 * service explicitly calls them for flows such as password setup.
 */
export interface AuthProviderDriver<TInput = unknown, TIdentity extends UserIdentity = UserIdentity> {
    /**
     * Stable provider name used in `auth_providers.provider`.
     */
    provider: string;
    /**
     * Verifies provider-specific input and returns a normalized profile.
     *
     * @param input - Provider-specific credential payload.
     * @returns Normalized provider profile, or null when verification fails.
     */
    verify(input: TInput): Promise<AuthProviderProfile | null>;
}
/**
 * Object-style provider config read from the app config repository.
 */
export interface AuthProviderOptions {
    /**
     * Built-in or custom driver name. Defaults to the provider key.
     */
    driver?: string;
    /**
     * Whether this provider should be registered. Defaults to true.
     */
    enabled?: boolean;
    /**
     * Provider-specific configuration values.
     */
    [option: string]: unknown;
}
/**
 * Provider configuration accepted by the auth service.
 *
 * `true` enables a built-in provider such as `password`; driver instances
 * enable external or custom first-party providers.
 */
export type AuthProviderConfig<TIdentity extends UserIdentity = UserIdentity> = true | false | AuthProviderOptions | AuthProviderDriver<unknown, TIdentity>;
/**
 * Map of provider names enabled for an app.
 */
export type AuthProviderRegistry<TIdentity extends UserIdentity = UserIdentity> = Record<string, AuthProviderConfig<TIdentity>>;

Password hashing helpers

Password hashing helpers
ts
export interface PasswordHash {
    hash(plainText: string): Promise<string>;
    verify(plainText: string, hash: string): Promise<boolean>;
}
export interface ScryptPasswordHashOptions {
    cost?: number;
    blockSize?: number;
    parallelization?: number;
    keyLength?: number;
    saltLength?: number;
    maxmem?: number;
}
export declare class ScryptPasswordHash implements PasswordHash {
    private readonly cost;
    private readonly blockSize;
    private readonly parallelization;
    private readonly keyLength;
    private readonly saltLength;
    private readonly maxmem?;
    constructor(options?: ScryptPasswordHashOptions);
    hash(plainText: string): Promise<string>;
    verify(plainText: string, hash: string): Promise<boolean>;
    private derive;
    private parse;
}
export declare const defaultPasswordHash: ScryptPasswordHash;

Google provider

Google provider
ts
import type { webcrypto } from 'node:crypto';
import type * as auth from '../contracts/index.js';
import type { UserIdentity } from '../UserIdentity.js';
export declare const GOOGLE_AUTH_PROVIDER = "google";
export type GoogleJsonWebKey = webcrypto.JsonWebKey & {
    kid?: string;
};
type Fetch = typeof fetch;
/**
 * Input accepted by the Google auth provider.
 */
export interface GoogleAuthProviderInput {
    /**
     * Google Identity Services credential field containing the ID token.
     */
    credential?: string;
    /**
     * Alternative explicit ID-token field for non-GIS clients.
     */
    idToken?: string;
    /**
     * CSRF token submitted in the request body by Google Identity Services.
     */
    g_csrf_token?: string;
    /**
     * Alternative explicit CSRF token field.
     */
    csrfToken?: string;
    /**
     * CSRF token read from the request cookie by the route.
     */
    csrfCookie?: string;
}
/**
 * Runtime options for Google ID-token verification.
 */
export interface GoogleAuthProviderOptions {
    /**
     * Single Google OAuth web client id.
     */
    clientId?: string;
    /**
     * Accepted Google OAuth web client ids.
     */
    clientIds?: string[];
    /**
     * Optional Google Workspace hosted domain restriction.
     */
    hostedDomain?: string;
    /**
     * JWK endpoint used to fetch Google signing keys.
     */
    jwksUrl?: string;
    /**
     * Fetch implementation, injectable for tests.
     */
    fetch?: Fetch;
    /**
     * Static signing keys, injectable for deterministic tests.
     */
    jwks?: GoogleJsonWebKey[];
    /**
     * Clock skew allowance in seconds.
     */
    clockSkewSeconds?: number;
    /**
     * Time source used for expiry checks.
     */
    now?: () => Date | number;
}
/**
 * Provider driver for Google Sign-In ID tokens.
 *
 * This provider verifies a Google-signed ID token and translates the verified
 * claims into the framework's normalized provider profile. It intentionally
 * does not store OAuth access or refresh tokens.
 */
export declare class GoogleAuthProvider<TIdentity extends UserIdentity = UserIdentity> implements auth.AuthProviderDriver<GoogleAuthProviderInput, TIdentity> {
    readonly provider = "google";
    private readonly clientIds;
    private readonly hostedDomain;
    private readonly jwksUrl;
    private readonly fetcher;
    private readonly staticJwks;
    private readonly clockSkewSeconds;
    private readonly now;
    private jwksCache;
    /**
     * Creates a Google auth provider.
     *
     * @param options - Google provider verification options.
     */
    constructor(options?: GoogleAuthProviderOptions);
    /**
     * Verifies a Google ID token and returns the normalized provider profile.
     *
     * @param input - Google credential payload.
     * @returns Normalized Google provider profile, or null when verification fails.
     */
    verify(input: GoogleAuthProviderInput): Promise<auth.AuthProviderProfile | null>;
    /**
     * Checks whether supplied CSRF values match when either value is present.
     *
     * @param input - Google credential payload.
     * @returns True when CSRF values are absent or exactly match.
     */
    private csrfTokensMatch;
    /**
     * Verifies a compact JWT from Google.
     *
     * @param idToken - Compact Google ID token.
     * @returns Verified header and payload, or null when invalid.
     */
    private verifyIdToken;
    /**
     * Validates the required Google ID-token claims.
     *
     * @param payload - Decoded JWT payload.
     * @returns True when required claims are acceptable.
     */
    private claimsAreValid;
    /**
     * Returns Google JWKs, using cache-control when keys are fetched remotely.
     *
     * @returns Google signing keys.
     */
    private jwks;
    /**
     * Returns the current time in milliseconds.
     *
     * @returns Current epoch milliseconds.
     */
    private nowMs;
}
export {};

Password provider

Password provider
ts
import { AuthProvider } from '../AuthProvider.js';
import type * as auth from '../contracts/index.js';
import type { PasswordCredentials } from '../Auth.js';
import type { UserIdentity, UserIdentityModel } from '../UserIdentity.js';
import { type PasswordHash } from '../passwordHash.js';
/**
 * Construction options for the password auth provider.
 */
export interface PasswordAuthProviderOptions<TIdentity extends UserIdentity = UserIdentity> {
    /**
     * User identity model configured for the host app.
     */
    identityModel: UserIdentityModel<TIdentity>;
    /**
     * Provider-link model configured for the auth service.
     */
    providerModel?: typeof AuthProvider;
    /**
     * Password hashing service used to verify stored hashes.
     */
    passwordHash?: PasswordHash;
}
/**
 * Provider driver for first-party email and password authentication.
 *
 * The password provider is not OAuth, but it still satisfies the same provider
 * contract by proving control of a provider-owned identity: the account email
 * plus a valid password hash stored on `auth_providers`.
 */
export declare class PasswordAuthProvider<TIdentity extends UserIdentity = UserIdentity> implements auth.AuthProviderDriver<PasswordCredentials, TIdentity> {
    readonly provider = "password";
    private readonly IdentityModel;
    private readonly ProviderModel;
    private readonly passwordHash;
    /**
     * Creates a password auth provider.
     *
     * @param options - Password provider dependencies configured at app startup.
     */
    constructor(options: PasswordAuthProviderOptions<TIdentity>);
    /**
     * Verifies submitted password credentials against the stored provider row.
     *
     * @param input - Submitted password credential payload.
     * @returns Normalized password provider profile, or null when verification fails.
     */
    verify(input: PasswordCredentials): Promise<auth.AuthProviderProfile | null>;
    /**
     * Creates or replaces the password provider for a user.
     *
     * @param user - User who owns the password provider.
     * @param password - Plaintext password to hash and store.
     * @returns Saved password provider row.
     */
    setPassword(user: TIdentity, password: string): Promise<AuthProvider>;
    /**
     * Changes a user's password after verifying the current password.
     *
     * @param user - User whose password should change.
     * @param currentPassword - Current plaintext password.
     * @param nextPassword - Replacement plaintext password.
     * @returns True when the password provider was changed.
     */
    changePassword(user: TIdentity, currentPassword: string, nextPassword: string): Promise<boolean>;
    /**
     * Links the password provider to an existing user.
     *
     * @param user - User receiving the password provider.
     * @param input - Submitted password credential payload.
     * @returns Saved provider row, or null when no password was supplied.
     */
    link(user: TIdentity, input: unknown): Promise<AuthProvider | null>;
    /**
     * Finds a password provider by normalized email identity.
     *
     * @param identity - Normalized email identity.
     * @returns Matching password provider row, or null.
     */
    private findProvider;
    /**
     * Finds the password provider linked to a user.
     *
     * @param userId - User primary key.
     * @returns Matching password provider row, or null.
     */
    private findUserProvider;
    /**
     * Reads a user primary key as a non-empty string.
     *
     * @param user - User model to inspect.
     * @returns Primary key string, or null when missing.
     */
    private userPrimaryKey;
    /**
     * Reads the configured identity value from a user.
     *
     * @param user - User model to inspect.
     * @returns Normalized identity value, or null when missing.
     */
    private userIdentityValue;
}
/**
 * Checks whether a value can be used as password credentials.
 *
 * @param value - Unknown credential payload.
 * @returns True when a password string is present.
 */
export declare function isPasswordCredentials(value: unknown): value is PasswordCredentials;
/**
 * Normalizes an auth identity value for provider matching.
 *
 * @param value - Unknown identity value.
 * @returns Lowercase trimmed identity string, or null.
 */
export declare function normalizeIdentity(value: unknown): string | null;