Skip to main content

Auth and OAuth Flow

This document describes the current auth behavior for API and AdminJS.

Session Model

  • Auth uses signed HTTP-only cookies (ledgerline_auth) managed by AuthSessionManager.
  • Session payloads are stored in cache (AppContext.cache) with an 8 hour TTL by default.
    • Production uses Valkey/Redis when VALKEY_URL is configured.
    • Dev/test fall back to in-memory cache via the cache port.
  • Logout clears the cookie and removes the cache-backed session record.
  • Discord callback sessions use provider token lifetime (expiresInSeconds) when available, so the local auth session lasts for the same window Discord grants.
  • Production now requires a cache URL (VALKEY_URL or REDIS_URL) so auth state does not silently fall back to process-local memory.

Discord OAuth Endpoints

  • GET /api/auth/:provider/start

    • Resolves provider config by provider + tenant (x-tenant-id, tenantId query/body, or session tenant).
    • Requires redirectUri query param, or falls back to DISCORD_REDIRECT_URI then DISCORD_CALLBACK_URL.
    • Creates a short-lived one-time OAuth state record in cache.
    • Default returns JSON: { authorizationUrl, state }.
    • With mode=redirect, returns 302 directly to authorizationUrl.
  • GET /api/auth/:provider/callback

    • Requires code and state.
    • Consumes and validates OAuth state (one-time use, TTL, provider match).
    • Exchanges code via provider adapter.
    • Creates/links user identity and creates a cookie session.
    • If OAuth state includes postLoginRedirect, returns 302 to that path; otherwise returns JSON { session }.

AdminJS Auth Entry

  • Default admin entrypoint is Discord OAuth redirect mode:
    • /api/auth/discord/start?tenantId=default&mode=redirect&postLoginRedirect=/admin
  • Set ADMIN_AUTH_USE_LOCAL=true to use local login entrypoint:
    • /api/auth/local/start?tenantId=default

Provider Bootstrapping

  • Local provider is upserted in src/init/api.init.ts when LOCAL_AUTH_ENABLED=true.
  • Discord provider is upserted for tenant default when both DISCORD_CLIENT_ID and DISCORD_CLIENT_SECRET are set.
  • For multi-tenant deployments, provider records should be managed per tenant in provider data.