Skip to content

Auth and users

End-user authentication on the public site.

The frontend uses Better Auth with the official Astro integration pattern.

PieceLocation
Server configfrontend/src/auth.ts
API handlerfrontend/src/pages/api/auth/[...all].ts
Vue clientfrontend/src/lib/auth-client.ts
Session middlewarefrontend/src/middleware.tsAstro.locals.session

Configured in frontend/src/auth.ts:

  • Google OAuth (GitHub / Facebook when env vars are set)
  • Email magic links via Mailgun EU (magicLink plugin)

Sessions and user records are stored in Turso (libSQL) via Drizzle ORM (frontend/src/db/schema.ts), including roles, favorites, and vacation planner data.

VariablePurpose
AUTH_SECRETSigning secret (≥32 chars); also read by Better Auth
BETTER_AUTH_URLPublic site URL for OAuth/magic-link callbacks (e.g. https://www.soultales.com). In local dev, omit this: the app uses http://localhost:4321 automatically.
AUTH_GOOGLE_*, AUTH_GITHUB_*, AUTH_FB_*OAuth client credentials
MAILGUN_API_KEY, FROM_EMAIL_ADDRESSMagic-link email delivery
ASTRO_DB_REMOTE_URL, ASTRO_DB_APP_TOKENTurso database

When upgrading from Auth.js, run frontend/scripts/migrate-to-better-auth.sql against Turso (staging first). Existing sessions are invalidated; users sign in again.

Traveler accounts on the public site are separate from partner accounts on the dashboard (Clerk). A person may have both, but they are different systems.