Skip to content

feat: Migrate authentication from NextAuth v5 to Better Auth#2360

Closed
brianmjohnson wants to merge 10 commits into
baptisteArno:mainfrom
brianmjohnson:feat/better-auth
Closed

feat: Migrate authentication from NextAuth v5 to Better Auth#2360
brianmjohnson wants to merge 10 commits into
baptisteArno:mainfrom
brianmjohnson:feat/better-auth

Conversation

@brianmjohnson
Copy link
Copy Markdown

Summary

Migrates authentication from NextAuth v5 to Better Auth.

Addresses #2349

Changes

  • Replace NextAuth with Better Auth library
  • Update auth configuration and API routes (/api/auth/[...all])
  • Migrate database schema (Account table field names)
  • Add workspace creation for new users via Better Auth database hooks
  • Replace NEXTAUTH_URL env var with BETTER_AUTH_URL
  • Add BUILDER_URL env var for consistent URL handling
  • Support configurable AUTH_COOKIE_DOMAIN and APP_NAME via env vars
  • Compute auth providers server-side instead of build-time

New Environment Variables

Variable Required Description
BETTER_AUTH_URL Yes Replaces NEXTAUTH_URL - URL of the builder app
BUILDER_URL Yes URL of the builder app (can be same as BETTER_AUTH_URL)
BETTER_AUTH_SECRET No Auth secret (falls back to ENCRYPTION_SECRET)
AUTH_COOKIE_DOMAIN No Custom cookie domain for cross-subdomain auth
APP_NAME No Application name shown in auth UI (defaults to "typebot")

Migration Notes

Database Migration

A Prisma migration is included for the Account table field changes:

  • expires_at → Renamed/restructured for Better Auth compatibility
  • id_tokenidToken
  • access_tokenaccessToken
  • refresh_tokenrefreshToken

Run the migration after updating:

bun --filter @typebot.io/prisma db:push

Environment Variables

Update your .env file:

- NEXTAUTH_URL=http://localhost:3000
+ BETTER_AUTH_URL=http://localhost:3000
+ BUILDER_URL=http://localhost:3000

Session Migration

Existing sessions will be invalidated. Users will need to sign in again after the migration.

Testing

  • GitHub OAuth authentication
  • Google OAuth authentication
  • Magic link email authentication
  • New user registration creates workspace automatically
  • Session management working correctly
  • Viewer auth handoff from builder

Note

These changes are based on commit a9b78f418 (before the oRPC migration in #2342). If there have been significant changes to the auth code paths in recent releases, some manual adaptation may be needed.

The commits include a createMissingWorkspaces.ts script that can be used to create workspaces for any existing users who don't have one.

- Update Prisma schema with Better Auth models (User, Session, Account, Verification, Passkey, TwoFactor, Jwks)
- Change User.id from CUID to UUID format
- Change emailVerified from DateTime? to Boolean
- Add cross-subdomain cookie support for SSO on .usefoundry.ai domain
- Create Better Auth configuration for builder and viewer apps
- Update SignInForm and SocialLoginButtons to use Better Auth client
- Add public environment variables for auth provider visibility
- Configure shared database sessions for SSO across apps

BREAKING: Requires new environment variables BETTER_AUTH_URL and BETTER_AUTH_SECRET

Brian Johnson in useFoundry.ai

(cherry picked from commit 1c39a71bf834d0c422d62f8230a9196289cfe4d3)
- Update verificationToken → verification model references
- Fix user schema to match Better Auth fields (emailVerified: boolean, etc.)
- Update workspace member schema for required name/email fields
- Add getMe TRPC query for fetching full user data
- Create getSessionFromContext helper for SSR pages
- Update UserProvider to fetch full user from DB instead of session
- Fix imports: nextAuth → Better Auth client
- Remove NextAuth SessionProvider from _app.tsx
- Update email verification flow for new schema structure

Brian Johnson in useFoundry.ai

(cherry picked from commit 5896a5444a82ce47b61c6be818a9624b11019876)
- Fix verificationToken → verification in whatsapp package handler
- Fix cleanExpiredData to use Better Auth schema (verification + expiresAt)
- Add opentelemetry/winston-transport override to fix inngest dependency

Brian Johnson in useFoundry.ai

(cherry picked from commit 80b79e4706f46df66f19b95aaa2148babb339c1e)
The signin page was showing "no providers configured" because it relied
on NEXT_PUBLIC_*_ENABLED environment variables that weren't set.

This fix:
- Creates getAvailableProviders() helper that checks actual OAuth credentials
- Uses getServerSideProps to pass available providers to the signin pages
- Removes dependency on build-time NEXT_PUBLIC_*_ENABLED flags
- Providers are now automatically detected from GITHUB_CLIENT_ID, etc.

Brian Johnson in useFoundry.ai

(cherry picked from commit 13057a8539f144bf245435e8d26cb44e3531b80b)
Complete migration to Better Auth by removing all NEXTAUTH_URL references:

- Remove NEXTAUTH_URL from env schema (packages/env/src/index.ts)
- Replace all env.NEXTAUTH_URL usages with env.BETTER_AUTH_URL
- Update turbo.json env configurations
- Update .env.example and .env.dev.example
- Update GitHub workflow files
- Update CLAUDE.md documentation

This makes the codebase purely Better Auth based with no NextAuth remnants.

Brian Johnson in useFoundry.ai

(cherry picked from commit 61e26b559b0370f0a0ab88cb0076af9a666ce53b)
- Rename expiresAt to accessTokenExpiresAt
- Add refreshTokenExpiresAt field

Brian Johnson in useFoundry.ai

(cherry picked from commit 8461b8c5a45034f77b73dbaee426c3971efad402)
- Add BUILDER_URL env var for viewer to link to builder dashboard
- Create proper Prisma migration for Account schema changes:
  - Rename expiresAt → accessTokenExpiresAt
  - Add refreshTokenExpiresAt field

Brian Johnson in useFoundry.ai

(cherry picked from commit 7b28e6623d3e9abe8915992df3d20524121ad680)
- Add AUTH_COOKIE_DOMAIN env var for cross-subdomain SSO
- Add APP_NAME env var for email branding (defaults to "Typebot")
- Remove hardcoded ".usefoundry.ai" cookie domain
- Remove hardcoded "Foundry" branding in emails

This makes the fork upstream-friendly with no internal references.

Brian Johnson in useFoundry.ai

(cherry picked from commit 527b9a59fb16593b2ba45220f0975b04de65e77d)
- Fixed getAuthenticatedUser to fetch full user from DB (Better Auth
  session only returns basic fields, causing schema validation errors)
- Added workspace creation in Better Auth's databaseHooks.user.create.after
- Fixed onboardingCategories default from "{}" to "[]" (must be array)
- Added createMissingWorkspaces script to fix existing users without workspaces

This resolves the 500 errors on /api/trpc routes and the "upgrade plan
to create folders" issue caused by missing workspace records.

Brian Johnson in useFoundry.ai

(cherry picked from commit f0da2b3d297d04b7093f06b3ed64bd8ef1c2ad53)
@vercel
Copy link
Copy Markdown

vercel Bot commented Jan 21, 2026

@brianmjohnson is attempting to deploy a commit to the Typebot Team on Vercel.

A member of the Team first needs to authorize it.

@brianmjohnson
Copy link
Copy Markdown
Author

#2360

The domain filtering functionality (ALLOWED_EMAIL_DOMAINS and
EMAIL_LOGIN_ENABLED) will be submitted in a separate follow-up PR.
This commit keeps the core Better Auth migration clean and focused.

Brian Johnson in useFoundry.ai
@baptisteArno
Copy link
Copy Markdown
Owner

That's great material, thanks will see if I can adapt it and make sure it is retro compatible with existing authentications :)

@baptisteArno
Copy link
Copy Markdown
Owner

We are not planning on migrating to Better Auth for now. Thanks for sharing this 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants