Features
Authentication
Better Auth architecture for app/admin, OTP delivery, social providers, and guest access.
Authentication is implemented with Better Auth and split into two server configurations:
@ai/authfor the main appadminAuthinapps/adminfor admin panel isolation
Main app auth is provided by @ai/auth and mounted at apps/app/src/app/api/auth/[...all]/route.ts.
Admin auth is configured in apps/admin/src/lib/auth.tsx and mounted at apps/admin/src/app/api/auth/[...all]/route.ts with isolated cookie behavior.
Runtime Architecture
Main app auth (@ai/auth)
- exported from
packages/auth/src/auth.tsx - mounted at
apps/app/src/app/api/auth/[...all]/route.ts - uses Drizzle adapter (
@ai/db) and Better Auth Next.js handler - supports email/password, OTP plugin, social providers, email verification
Admin auth (adminAuth)
- defined in
apps/admin/src/lib/auth.tsx - mounted at
apps/admin/src/app/api/auth/[...all]/route.ts - uses isolated cookie prefix and OTP key namespace
OTP and Test Credentials Behavior
Main app and admin both support deterministic OTP for test addresses:
- app uses
AUTH_TEST_EMAILandAUTH_TEST_OTP_CODE - admin prefers
ADMIN_AUTH_TEST_EMAILandADMIN_AUTH_TEST_OTP_CODE
When test email is used:
- OTP generation returns fixed code
- actual email sending is skipped
- logs mark test flow explicitly
Local defaults:
- Email:
test@example.com - OTP:
123456
Guest Auth Plugin (Main App)
@ai/auth includes a custom guest plugin:
POST /api/auth/guest/sign-inGET /api/auth/guest/status- deterministic guest identity from IP hash
- built-in sign-in rate limiting
Guest users are hard-blocked from dashboard routes and redirected to /sign-in.
Environment Variables
Required baseline:
BETTER_AUTH_SECRET=...
BETTER_AUTH_URL=http://localhost:3000Provider variables (optional):
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
TWITTER_CLIENT_ID=
TWITTER_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=Email transport:
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=noreply@localhostTest credentials:
AUTH_TEST_EMAIL=test@example.com
AUTH_TEST_OTP_CODE=123456
ADMIN_AUTH_TEST_EMAIL=admin@example.com
ADMIN_AUTH_TEST_OTP_CODE=123456