Menu

API Reference

View as Markdown

@kovojs/better-auth

Generated from 3 public subpaths — 28 exports, 28 documented. Do not edit by hand.

@kovojs/better-auth#

Task: Shared app-binding contracts, session guards, CSRF configuration, and redirect-protocol mounting.

Source: packages/better-auth/src/index.ts

Values#

authed#

Guard that requires an authenticated session, narrowing the request to an AuthenticatedRequest. A thin re-export of the framework's guards.authed for use on auth-protected mutations and routes; an unauthenticated request denies with a login-redirect intent (SPEC.md §6.5).

Signature

ts
function authed<Request extends SessionRequestLike>(): Guard<
  Request,
  AuthenticatedRequest<Request>
>;

role#

Guard that requires the session user to hold a given role. Denies with an unauthenticated (→ login redirect) intent when there is no session user, and with a forbidden (→ 403) intent when the user lacks the role. The role name is type-checked against the request's own roles element type when known (SPEC.md §6.5).

Signature

ts
function role<Request extends BetterAuthRoleRequest>(
  requiredRole: NonNullable<NonNullable<Request['session']>['user']> extends {
    roles?: readonly (infer Role)[] | null;
  }
    ? Extract<Role, string>
    : string,
): Guard<Request>;
function role(requiredRole: string): Guard<BetterAuthRoleRequest>;

betterAuthCsrfFromEnvironment#

Create a frozen CSRF config from bootstrap-pinned operator signing material.

The raw environment string is consumed inside this first-party package and converted to an opaque signing-key ring before the result crosses into generated source (SPEC §6.6 C9).

Signature

ts
function betterAuthCsrfFromEnvironment<
  Request extends BetterAuthCsrfRequestLike = BetterAuthCsrfRequestLike,
>(options: BetterAuthEnvironmentCsrfOptions): Readonly<CsrfOptions<Request>>;

mount#

Mounts Better Auth's own request handler at a prefix endpoint so its browser redirect protocol — OAuth/magic-link callbacks and similar safe-method provider round-trips — is served under one declared path, while credential forms stay on typed mutations (SPEC.md §9.1).

SECURITY — this endpoint is always declared with csrf: false. Per SPEC.md §6.6, CSRF protection is default-ON for server-rendered, cookie-authenticated mutations, and csrf: false is the framework's sanctioned opt-out reserved for endpoints that are not browser-form-driven or are authenticated by some other means (e.g. non-browser / externally-authenticated callers). Better Auth's redirect protocol handler is exactly such an endpoint: the inbound requests are external-provider redirects and the library-supplied OAuth state parameter (not a Kovo CSRF token) carries the anti-forgery guarantee, so a Kovo CSRF token cannot be present or required here. Disabling CSRF on this prefix does NOT relax protection on the app's own credential mutations, which keep CSRF on. The framework hardcodes GET: an unsafe-method callback needs a separate framework-owned, self-verifying adapter rather than widening this prefix authority.

Signature

ts
function mount<const Path extends string>(
  path: Path,
  adapter: BetterAuthMountAdapter,
): EndpointDeclaration<Path, 'GET', 'prefix'>;

betterAuthPasswordResetMailDoor#

Validate and capture a deployer mail sender behind an opaque password-reset-only capability.

The type brand is ergonomics; exact registry membership is the runtime authority.

Signature

ts
function betterAuthPasswordResetMailDoor(
  send: BetterAuthPasswordResetMailSender,
): BetterAuthPasswordResetMailDoor;

Supporting types#

BetterAuthAppBindings#

Capability-minimized result shared by the Postgres and SQLite app binding constructors.

The raw Better Auth instance, Drizzle adapter, system database, deployment secret, and signing controls are structurally absent (SPEC §6.6/§10.3 C9).

Signature

ts
interface BetterAuthAppBindings<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
  AuthenticatedRequest extends Request = Request & { session: SessionValue },
> {
  /** Opaque provider/callback router token accepted only by `mount()`. */
  mountAdapter: BetterAuthMountAdapter;
  /** Create the configured fixed development account, or do nothing when disabled/production. */
  seedDemoUser(): Promise<void>;
  /** Runtime-sanitized Better Auth session provider. */
  sessionProvider: SessionProvider<Request, SessionValue>;
  /** CSRF-protected Better Auth email/password sign-in mutation. */
  signIn: BetterAuthAppSignInMutation<Request>;
  /** CSRF-protected Better Auth sign-out mutation with framework-fixed authenticated access. */
  signOut: BetterAuthAppSignOutMutation<Request, AuthenticatedRequest>;
}

BetterAuthAppBindingsOptions#

Human-authored options shared by the Postgres and SQLite app binding constructors.

Deployment secrets, base URL, persistent revocation storage, authenticated sign-out posture, and system database authority are framework-owned and therefore cannot be supplied here (SPEC §6.6/§10.3 C9).

Signature

ts
interface BetterAuthAppBindingsOptions<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
> {
  /** Kovo CSRF configuration shared by the credential mutations. */
  csrf: CsrfOptions<Request>;
  /** Sanitized projection from Better Auth's credential-free session/user records. */
  mapSession: BetterAuthSessionMapper<Session, User, SessionValue>;
  /** Exact Better Auth Drizzle table record from the app's pinned schema. */
  schema: Record<string, unknown>;
  /** Explicit pre-auth access decision for the sign-in mutation. */
  signInAccess: AccessDecision;
}

BetterAuthAppCredentialResult#

Public wire result returned by the first-party credential mutations.

Signature

ts
interface BetterAuthAppCredentialResult<Status extends string> {
  /** Same-origin destination applied after the credential transition. */
  redirectTo: string;
  /** Stable credential-transition outcome. */
  status: Status;
}

BetterAuthAppRequest#

Lifecycle request consumed by the first-party Better Auth app binding.

The request contains only Kovo's native request carrier, resolved client identity, CSRF identity, and sanitized session. Raw Better Auth request/context objects are deliberately absent (SPEC §6.6).

Signature

ts
type BetterAuthAppRequest<SessionValue extends { id: string } = { id: string }> = {
  /** Framework-resolved anonymous pre-auth identity, when available. */
  authCsrfId?: string | null;
  /** Framework-resolved client IP attached by Kovo's request lifecycle (SPEC §9.5). */
  clientIp?: string;
  /** Native request headers used by the fixed Better Auth session provider. */
  headers: Headers;
  /** Sanitized app session returned by the configured mapper. */
  session?: SessionValue | null;
  /** Absolute incoming request URL from Kovo's native request carrier. */
  url: string;
} & BetterAuthCsrfRequestLike;

BetterAuthAppSignInMutation#

CSRF-protected email/password sign-in mutation returned by an app binding constructor.

Signature

ts
type BetterAuthAppSignInMutation<Request extends BetterAuthAppRequest> = MutationDefinition<
  'auth/sign-in',
  Schema<{ email: string; next: string | undefined; password: string }>,
  {
    INVALID_CREDENTIALS: Schema<Record<string, never>>;
    RATE_LIMITED: Schema<Record<string, never>>;
  },
  Request,
  BetterAuthAppCredentialResult<'signed-in'>,
  Request
> &
  MutationFormDefinition<'auth/sign-in', Request> &
  AppMutationAdapter;

BetterAuthAppSignOutMutation#

CSRF-protected sign-out mutation returned by an app binding constructor.

Signature

ts
type BetterAuthAppSignOutMutation<
  Request extends BetterAuthAppRequest,
  AuthenticatedRequest extends Request,
> = MutationDefinition<
  'auth/sign-out',
  Schema<Record<string, never>>,
  Record<string, never>,
  Request,
  BetterAuthAppCredentialResult<'signed-out'>,
  AuthenticatedRequest
> &
  MutationFormDefinition<'auth/sign-out', Request> &
  AppMutationAdapter;

BetterAuthRoleRequest#

Minimal request shape the role guard reads: an optional session.

Signature

ts
interface BetterAuthRoleRequest {
  session?: BetterAuthRoleSession | null;
}

BetterAuthRoleSession#

Minimal session shape the role guard reads: an optional user.

Signature

ts
interface BetterAuthRoleSession {
  user?: BetterAuthRoleUser | null;
}

BetterAuthRoleUser#

Minimal user shape the role guard reads: an optional id and an optional roles list. Apps' own session-user types structurally satisfy this (SPEC.md §6.5).

Signature

ts
interface BetterAuthRoleUser {
  id?: string;
  roles?: readonly string[] | null;
}

BetterAuthCsrfRequestLike#

Request fields the framework-owned Better Auth CSRF binding is permitted to inspect.

Signature

ts
interface BetterAuthCsrfRequestLike {
  /** Anonymous pre-auth identity, when the request lifecycle has already resolved one. */
  authCsrfId?: string | null;
  /** Sanitized Better Auth session identity resolved by the framework session provider. */
  session?: { id: string } | null;
}

BetterAuthEnvironmentCsrfOptions#

Options used to build a CSRF config from boot-pinned signing material.

Signature

ts
interface BetterAuthEnvironmentCsrfOptions {
  /** Form field name used by generated credential mutations. */
  field: string;
}

BetterAuthMountAdapter#

Opaque handle for the Better Auth router privately constructed by Kovo's fixed database bindings. It exposes no handler or auth object; {@link mount} is its only app-facing consumer (SPEC §6.6/§9.1).

Signature

ts
interface BetterAuthMountAdapter {
  readonly [betterAuthMountAdapterBrand]: 'kovo-better-auth-mount-adapter';
}

BetterAuthPasswordResetMailDoor#

Opaque capability for the single password-reset mail purpose.

Construct it with {@link betterAuthPasswordResetMailDoor}; structural objects and callbacks cannot be supplied directly to a fixed binding (SPEC §6.6 C9-C10).

Signature

ts
interface BetterAuthPasswordResetMailDoor {
  readonly [betterAuthPasswordResetMailDoorBrand]: 'better-auth-password-reset-mail-door';
}

BetterAuthPasswordResetMailMessage#

The only data Kovo permits to cross its password-reset email-egress door (SPEC §6.6/§9.2).

Signature

ts
interface BetterAuthPasswordResetMailMessage {
  /** Validated recipient selected by the fixed Better Auth account-recovery operation. */
  readonly to: string;
  /** Same-origin Better Auth callback URL carrying the opaque reset token. */
  readonly resetUrl: string;
}

BetterAuthPasswordResetMailSender#

A deployer-owned mail sender invoked only with a password-reset message.

Signature

ts
type BetterAuthPasswordResetMailSender = (
  message: Readonly<BetterAuthPasswordResetMailMessage>,
) => Promise<void>;

BetterAuthPasswordResetOptions#

Feature-conditional password-reset options accepted by fixed SQLite/Postgres bindings.

Signature

ts
interface BetterAuthPasswordResetOptions {
  /** Explicit pre-auth access decision for the CSRF-protected request mutation. */
  access: AccessDecision;
  /** Constructor-minted, purpose-closed mail capability. */
  mail: BetterAuthPasswordResetMailDoor;
  /** Canonical same-origin path that receives Better Auth's reset token redirect. */
  resetPath: string;
}

BetterAuthSafeField#

Author-time field-key filter used by Better Auth's sanitized session projection. Credential nouns are omitted when they are the whole key, a snake/kebab suffix, or a camel-case suffix. Runtime recursive reconstruction remains the confidentiality proof (SPEC §10.3 C9-C10).

Signature

ts
type BetterAuthSafeField<Key> = Key extends string
  ? Lowercase<Key> extends
      | 'apikey'
      | 'apisecret'
      | 'backupcode'
      | 'backupcodes'
      | 'certificate'
      | 'code'
      | 'codes'
      | 'credential'
      | 'credentials'
      | 'hash'
      | 'key'
      | 'keys'
      | 'otp'
      | 'passcode'
      | 'passphrase'
      | 'password'
      | 'pin'
      | 'privatekey'
      | 'salt'
      | 'secret'
      | 'secrets'
      | 'seed'
      | 'signature'
      | 'token'
      | 'tokens'
    ? never
    : Key extends
          | `${string}${
              | 'ApiKey'
              | 'ApiSecret'
              | 'BackupCode'
              | 'BackupCodes'
              | 'Certificate'
              | 'Code'
              | 'Codes'
              | 'Credential'
              | 'Credentials'
              | 'Hash'
              | 'Key'
              | 'Keys'
              | 'Otp'
              | 'Passcode'
              | 'Passphrase'
              | 'Password'
              | 'Pin'
              | 'PrivateKey'
              | 'Salt'
              | 'Secret'
              | 'Secrets'
              | 'Seed'
              | 'Signature'
              | 'Token'
              | 'Tokens'}`
          | `${string}${'_' | '-'}${
              | 'apikey'
              | 'apisecret'
              | 'backupcode'
              | 'backupcodes'
              | 'certificate'
              | 'code'
              | 'codes'
              | 'credential'
              | 'credentials'
              | 'hash'
              | 'key'
              | 'keys'
              | 'otp'
              | 'passcode'
              | 'passphrase'
              | 'password'
              | 'pin'
              | 'privatekey'
              | 'salt'
              | 'secret'
              | 'secrets'
              | 'seed'
              | 'signature'
              | 'token'
              | 'tokens'}`
      ? never
      : Key
  : Key;

BetterAuthSanitizedRecord#

A Better Auth row after Kovo removes credential-shaped fields before app code sees it. The mapped type is author-time defense-in-depth; recursive runtime reconstruction owns enforcement (SPEC §10.3 C9 and AGENTS.md's type-level security ergonomics rule).

Signature

ts
type BetterAuthSanitizedRecord<Value> = Value extends object
  ? {
      [Key in keyof Value as BetterAuthSafeField<Key>]: BetterAuthSanitizedValue<Value[Key]>;
    }
  : Value;

BetterAuthSanitizedSessionPayload#

The reconstructed { session, user } projection delivered to an app-authored session mapper. Better Auth bearer tokens, password hashes, API keys, and similarly credential-shaped fields are absent at runtime and omitted from the common TypeScript field vocabulary.

Signature

ts
interface BetterAuthSanitizedSessionPayload<Session, User> {
  session: BetterAuthSanitizedRecord<Session>;
  user: BetterAuthSanitizedRecord<User>;
}

BetterAuthSanitizedValue#

A recursively reconstructed Better Auth value. JSON objects lose credential-shaped fields, arrays and dates are copied, and scalar values are preserved.

Signature

ts
type BetterAuthSanitizedValue<Value> = Value extends Date
  ? Date
  : Value extends readonly unknown[]
    ? { [Index in keyof Value]: BetterAuthSanitizedValue<Value[Index]> }
    : Value extends object
      ? BetterAuthSanitizedRecord<Value>
      : Value;

BetterAuthSessionMapper#

Function the app supplies to a fixed SQLite/Postgres binding constructor to project Better Auth's { session, user } payload into the app's own session value. Called once per authenticated request (SPEC §6.5/§6.6).

Signature

ts
type BetterAuthSessionMapper<AuthSession, AuthUser, SessionValue> = (
  value: BetterAuthSanitizedSessionPayload<AuthSession, AuthUser>,
) => SessionValue;

@kovojs/better-auth/postgres#

Task: Purpose-closed Better Auth bindings for one framework-owned Postgres app runtime.

Source: packages/better-auth/src/public-postgres.ts

Values#

createBetterAuthPostgresAppBindings#

Bind Better Auth to an exact framework-owned Postgres app runtime.

Kovo mints the purpose-closed system database capability internally, fixes persistent principal revocation and authenticated sign-out posture, consumes deployment secrets/base URL from the boot-pinned environment, and returns only sanitized app bindings (SPEC §6.6/§10.3 C9).

Signature

ts
function createBetterAuthPostgresAppBindings<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
>(
  runtime: KovoPostgresAppRuntimeDb,
  options: BetterAuthAppBindingsOptions<SessionValue, Request>,
): Readonly<BetterAuthAppBindings<SessionValue, Request>>;

@kovojs/better-auth/sqlite#

Task: Purpose-closed Better Auth bindings for one framework-owned SQLite app runtime.

Source: packages/better-auth/src/public-sqlite.ts

Values#

createBetterAuthSqliteAppBindings#

Bind Better Auth to an exact framework-owned SQLite app runtime.

Kovo recovers the purpose-closed system database capability internally, fixes principal revocation and authenticated sign-out posture, consumes deployment secrets/base URL from the boot-pinned environment, and returns only sanitized app bindings (SPEC §6.6/§10.3 C9).

Signature

ts
function createBetterAuthSqliteAppBindings<
  SessionValue extends { id: string },
  Request extends BetterAuthAppRequest<SessionValue> = BetterAuthAppRequest<SessionValue>,
>(
  runtime: KovoSqliteAppRuntime,
  options: BetterAuthAppBindingsOptions<SessionValue, Request>,
): Readonly<BetterAuthAppBindings<SessionValue, Request>>;