Docs

Search documentation

Jump to a documentation page.

PricingMarketingApp

Search documentation

Jump to a documentation page.

Auth Flow

Auth & sessions

Authentication is powered by Better Auth with a Drizzle adapter on Postgres. Session cookies are integrated with TanStack Start via the tanstackStartCookies() plugin (must be last in the plugin list).

Server entrypoint

  • packages/server/src/auth.tsbetterAuth({ ... }) instance.
  • Required env: AUTH_SECRET, DATABASE_URL, BETTER_AUTH_URL (defaults to http://localhost:3001 if omitted).
  • BETTER_AUTH_TRUSTED_ORIGINS — comma-separated; merged with trimming for redirectTo / OAuth callbacks across hosts.
  • Optional BETTER_AUTH_COOKIE_DOMAINadvanced.defaultCookieAttributes.domain for cross-subdomain cookies.

Features enabled

  • Email + password with optional AUTH_REQUIRE_EMAIL_VERIFICATION=1 (only after Resend / EMAIL_FROM work).
  • Password reset and email verification hooks call packages/server/src/email/send-auth-email.ts (Resend when configured; otherwise dev console logs in development).
  • Social providers — built from env via packages/server/src/auth/social-provider-registry.ts (Google/GitHub when ids and secrets are set).
  • User field mapping — Better Auth image → DB column avatar_url.

Session behavior

  • expiresIn — 30 days of inactivity.
  • updateAge — refresh if session older than 1 day.
  • cookieCache — session payload cached in cookie for 5 minutes (Better Auth option).

Database hooks

On user create, after signup:

  • Logs analytics (USER_SIGNUP with OAuth provider when applicable).
  • Creates a personal organization (slug from email prefix + random suffix) and an owner organization_members row.
  • Logs ORG_CREATED.

Admin plugin and impersonation

  • admin() plugin with adminUserIds from ADMIN_USER_IDS env (packages/server/src/admin/admin-config.ts).
  • Impersonation session duration: 1 hour (impersonationSessionDuration: 60 * 60).
  • Admin client usage from the product UI for impersonate/stop (see shared admin components).

Session for loaders and RPC

  • packages/server/src/auth-session.tsgetSession server function (dynamic imports to keep client bundles free of postgres).
  • Returns SessionWithOrgs: user, organizations with roles, welcome onboarding flag, platform admin flag, and optional impersonation metadata (resolved from sessions.impersonated_by).

Use this for “who is signed in” and org membership in route loaders and mutations.

Platform admin guard

  • packages/server/src/admin/admin-guard.tsrequirePlatformAdmin ensures a signed-in user is a platform admin; otherwise redirects to home or sign-in.

API route

  • Product app serves Better Auth HTTP via TanStack Start API route (e.g. /api/auth/* under apps/web).

Related