Spacerr
  • Features
  • Pricing
  • FAQ
  • Docs
Get Access
Spacerr
  • Introduction
  • Features
  • Tech Stack
  • Setup
  • Configuration
  • Agents
  • Database
  • Jobs
    • Overview
    • Sign in and sign up
    • Passkeys and 2FA
  • Admin
  • Settings
  • Billing
  • Storage
  • Email
  • Support
  • Localization
  • SEO
  • Analytics
  • UI And Navigation
  • Deploying To Production
  • Testing And QA
  • Troubleshooting

Search documentation

Search documentation pages.

Documentation/Passkeys And 2FA

Passkeys And 2FA

Passkeys and two factor authentication are configured through Better Auth and exposed through the account settings UI. Users can add a passkey, enable two factor authentication, download backup codes, change their password state, and disable two factor authentication when needed.

Client Plugins

The browser auth client enables passkeys, two factor authentication, admin helpers, and last used login method tracking.

txt
export const authClient = createAuthClient({
  baseURL: ClientEnv.NEXT_PUBLIC_DOMAIN,
  plugins: [
    adminClient(),
    passkeyClient(),
    twoFactorClient({
      twoFactorPage: WebRoutes.signIn.path,
    }),
    lastLoginMethodClient(),
  ],
})

The server config mirrors those capabilities in src/features/auth/lib/auth.ts.

typescript
plugins: [
  passkey({
    rpName: SiteConfig.name,
    rpID: ServerEnv.BETTER_AUTH_PASSKEY_RP_ID,
    origin: ServerEnv.NEXT_PUBLIC_DOMAIN,
  }),
  twoFactor({
    issuer: SiteConfig.name,
  }),
  lastLoginMethod(),
]

Passkeys

Passkeys are managed from account settings in src/features/settings/components/settings-account-section/settings-account-section.tsx.

When the user adds a passkey, the app checks whether the current device supports a platform authenticator. It then asks Better Auth to create the passkey.

typescript
await authClient.passkey.addPasskey({
  authenticatorAttachment: hasPlatformAuthenticator ? "platform" : "cross-platform",
})

For local development, BETTER_AUTH_PASSKEY_RP_ID should be localhost. For production, set it to the real application domain without protocol.

dotenv
BETTER_AUTH_PASSKEY_RP_ID="localhost"

Passkey records are stored through Better Auth. See the Database section for database structure details.

Two Factor Authentication

Two factor authentication uses TOTP. Users enable it from account settings by confirming their password, scanning the generated QR code, and verifying the code from their authenticator app.

typescript
const response = await authClient.twoFactor.enable({
  password: ui.twoFactorPassword.trim(),
})

await authClient.twoFactor.verifyTotp({
  code: ui.twoFactorVerificationCode.trim(),
})

If a user signed up without a password, the settings UI asks them to create a password before enabling two factor authentication. This keeps the disable and recovery flow predictable.

Backup Codes

After TOTP verification succeeds, Better Auth returns backup codes. The UI shows them once and lets the user download them.

typescript
const content = `${backupCodes.join("\n")}\n`
const blob = new Blob([content], { type: "text/plain;charset=utf-8" })

Backup codes should be treated as sensitive recovery credentials. The app does not show them again after the setup dialog is closed.

Disabling Two Factor Authentication

Disabling two factor authentication also requires the user password.

typescript
await authClient.twoFactor.disable({
  password: ui.twoFactorPassword.trim(),
})

After disable succeeds, the settings UI clears local setup state and refreshes the session.

Last Used Method

The sign in screen uses the Better Auth last login method plugin to show the last used provider next to Google, email, password, or passkey options.

typescript
const lastUsedLoginMethod = authClient.getLastUsedLoginMethod()

This is a small UX detail, but it reduces repeat sign in friction because returning users can quickly choose the method they used last.

Where To Customize

Use these files first:

  • src/features/settings/components/settings-account-section/settings-account-section.tsx for account security UI.
  • src/features/auth/lib/auth-client.ts for browser auth plugins.
  • src/features/auth/lib/auth.ts for Better Auth server plugins.
  • src/features/settings/actions/get-passkey-status.action.ts for checking passkey state.
  • src/features/settings/store/passkey-status.store.ts for cached passkey hints.

Keep passkey and two factor UI in settings. Keep auth provider configuration in the auth feature.

Sign In And Sign Up

Learn how the auth forms, callbacks, magic links, OAuth, and password reset flows work.

Admin

Learn how the admin dashboard, user management, roles, and protected admin routes are structured.

On this page
Client PluginsPasskeysTwo Factor AuthenticationBackup CodesDisabling Two Factor AuthenticationLast Used MethodWhere To Customize