Skip to content

Auth

@aooth/auth is the method layer in the aoothjs stack — it owns issuance, validation, refresh and revocation of bearer credentials, plus magic-link helpers and the email/SMS transport contracts. It does not own credentials themselves (that's @aooth/user) and it does not own HTTP wiring (that's @aooth/auth-moost).

This page is the map. Every concept here has a dedicated child page.

Where it sits

┌─────────────────────────────────────────────────────────────┐
│  Framework integration                                      │
│  @aooth/auth-moost  ·  guards · workflows · controllers   │
└────────────────────────┬────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  Method layer                                               │
│  @aooth/auth                                              │
│     AuthCredential<TPayload>                                 │
│       issue · validate · refresh · revoke                   │
│       revokeAllForUser · listForUser                        │
│       listSessions · revokeSession · revokeOtherSessions    │
│     CredentialStore<TPayload>     DenylistStore              │
│     EmailSender · SmsSender · generateMagicLinkToken        │
└────────────────────────┬────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│  Identity layer                                             │
│  @aooth/user  ·  password · MFA secret · lockout          │
└─────────────────────────────────────────────────────────────┘

The orchestrator is store-agnostic. Pick the store that matches your deployment along two axes.

The two store axes

AxisStoresToken shapeEnumerableRevocation
StatefulCredentialStoreMemory, CredentialStoreRedis, CredentialStoreAtscriptDbopaque UUIDyes (listForUser)row delete
StatelessCredentialStoreJwt, CredentialStoreEncapsulatedsigned/encryptednodenylist by jti + per-user revocation epoch

Stateless stores require a DenylistStore to support single-use operations (consume, revoke, update). Without one, those methods throw STATELESS_OPERATION_UNSUPPORTED. See Stores.

Minimal example

ts
import { AuthCredential, CredentialStoreMemory } from "@aooth/auth";

const auth = new AuthCredential<{ roles?: string[] }>({
  store: new CredentialStoreMemory(),
  accessTtl: 60 * 60 * 1000,
});

const { accessToken } = await auth.issue("alice", {
  roles: ["admin"], // typed payload field, flat (no `claims` wrapper)
  metadata: { ip: "1.1.1.1" },
});

const ctx = await auth.validate(accessToken);
// { userId: 'alice', method: 'token', credentialId: '<sha256>', expiresAt, roles: ['admin'] }

That's the whole API on the hot path: issue, validate, plus refresh / revoke / revokeAllForUser / listForUser for the rest of the lifecycle.

What each page covers

  • Credentials & SessionsAuthCredential<TPayload> orchestrator: every constructor option, every public method, the AuthContext shape, and how credentialId works as a non-replayable fingerprint. The choice between method: 'session' and method: 'token'.
  • Sessions — the multi-device "active sessions" model: one stable sessionId per login (token family), listSessions / revokeSession / revokeOtherSessions, the read-time SessionEnricher seam (no UA/geo dependency), and opt-in trackLastSeen activity tracking.
  • Tokens (JWT)CredentialStoreJwt setup with jose: algorithm choice (HS* vs. asymmetric), key management, the claim layout, and the algorithm-confusion defense. Plus CredentialStoreEncapsulated (AES-256-GCM) and when to prefer stateless over stateful.
  • Refresh & RotationRefreshConfig with all three rotation modes ('none', 'always', 'sliding'), the grace window, reuse detection and the reuseResponse revocation scope (session-family by default, user-wide on escalation). maxConcurrent enforcement and onLimit strategies.
  • Client (Browser Silent Refresh)@aooth/auth/client and createAuthedFetch: the browser-safe fetch wrapper that forwards credentials, single-flights /auth/refresh on a 401, retries once, and calls onLogout on failure. The whole client integration for a cookie-transport SPA.
  • Magic LinksgenerateMagicLinkToken() and BuildMagicLinkUrl. Storing magic-link tokens as CredentialState for atomic single-use consumption.
  • Password Reset — How the primitives in this package compose into a recovery flow. The same-millisecond epoch gate that enables auto-login after reset. The full workflow lives in @aooth/auth-moost.
  • Email & SMS Senders — The EmailSender and SmsSender contracts. The kind unions for templated delivery (recovery.magicLink, mfa.code, login.pincode, etc).
  • Stores — Implementation matrix for CredentialStore<TPayload> and DenylistStore: Memory, Redis adapter, atscript-db adapter (with the shipped .as model), and how to write your own.
  • ErrorsAuthError and every variant of AuthErrorType with trigger, payload and recommended HTTP mapping.

Installation

bash
pnpm add @aooth/auth jose

jose is a hard peer dependency only when you use CredentialStoreJwt. The other stores have no extra peers. For the Redis or atscript-db adapter, add the relevant client:

bash
# Redis adapter
pnpm add @aooth/auth ioredis

# atscript-db adapter
pnpm add @aooth/auth @atscript/db

Conventions used across these pages

  • All TTLs are in milliseconds. JWT iat / exp are seconds (RFC 7519), but the store mirrors them at ms precision in a custom state claim — see Tokens.
  • TPayload is the credential's typed payload — the flat root fields a consumer adds to their model — threaded through AuthCredential<TPayload> / CredentialStore<TPayload> and intersected as CredentialState & TPayload / AuthContext<TPayload>. There is no free-form claims container: per-token data is typed root fields that round-trip through the store and surface by name. Pick a single shape per app and keep it stable.
  • CredentialMetadata is open to TypeScript declaration merging. Augment it with declare module '@aooth/auth' to type your IP / UA / fingerprint / label keys end-to-end.
  • The package never returns secrets through validateAuthContext.credentialId is sha256(accessToken), not the token itself.

Released under the MIT License.