The frontend uses Better Auth with the official Astro integration pattern.
| Piece | Location |
|---|---|
| Server config | frontend/src/auth.ts |
| API handler | frontend/src/pages/api/auth/[...all].ts |
| Vue client | frontend/src/lib/auth-client.ts |
| Session middleware | frontend/src/middleware.ts → Astro.locals.session |
Providers
Section titled “Providers”Configured in frontend/src/auth.ts:
- Google OAuth (GitHub / Facebook when env vars are set)
- Email magic links via Mailgun EU (
magicLinkplugin)
Session storage
Section titled “Session storage”Sessions and user records are stored in Turso (libSQL) via Drizzle ORM (frontend/src/db/schema.ts), including roles, favorites, and vacation planner data.
Environment variables
Section titled “Environment variables”| Variable | Purpose |
|---|---|
AUTH_SECRET | Signing secret (≥32 chars); also read by Better Auth |
BETTER_AUTH_URL | Public 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_ADDRESS | Magic-link email delivery |
ASTRO_DB_REMOTE_URL, ASTRO_DB_APP_TOKEN | Turso database |
Database migration
Section titled “Database migration”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.
Partner vs traveler accounts
Section titled “Partner vs traveler accounts”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.