Skip to content

User Account Settings

User account settings are presented as a modal dialog accessible from the account menu via “My Account”. The modal uses the same split-pane layout as organization settings — sidebar navigation on the left, scrollable content on the right — with three tabs.

The modal is opened from the AccountMenu dropdown in the app shell. It can also be triggered programmatically via the settings modal state in AppShell.

Displays and edits the user’s personal information:

  • Avatar — Shows user initials as fallback
  • Display name — Editable text field with save feedback
  • Email — Read-only display (changed from Security tab)
  • Language — Locale selector (persisted per user)
authClient.updateUser({ name: "New Name" })

Security tab with password, email change, 2FA, passkeys, and session management

Comprehensive security management with six sections:

Three-field form: current password, new password, confirm password. Changing the password automatically revokes all other sessions.

authClient.changePassword({
currentPassword: "old",
newPassword: "new",
revokeOtherSessions: true,
})

Enter a new email address. A verification email is sent — the email is not changed until the user confirms the new address.

authClient.changeEmail({ newEmail: "new@example.com" })

Four-state flow:

StateUIAction
Not enabledPassword confirmation formauthClient.twoFactor.enable({ password })
SetupQR code + 6-digit code inputauthClient.twoFactor.verifyTotp({ code })
Backup codes8 single-use codes in 2-column gridSave codes (shown once)
EnabledGreen status + disable buttonauthClient.twoFactor.disable({ password })

Backup codes are generated during enable and displayed once — they cannot be retrieved again.

Conditional section — only shown when passkeys are enabled in system configuration.

  • Add passkey — Opens the browser’s WebAuthn credential creation dialog
  • List passkeys — Shows name and creation date for each registered passkey
  • Delete passkey — Remove a specific passkey
authClient.passkey.addPasskey()
authClient.passkey.deletePasskey({ id: passkeyId })

Link and unlink social provider accounts. Only shows providers enabled in system configuration.

ProviderAvailable when
GooglesocialProviders.google enabled
GitHubsocialProviders.github enabled
ApplesocialProviders.apple enabled
MicrosoftsocialProviders.microsoft enabled
// Link
authClient.linkSocial({ provider: "google", callbackURL: "/settings" })
// Unlink
authClient.unlinkAccount({ providerId })

Cannot unlink the last authentication method — at least one sign-in method must remain.

Lists all active sessions with browser/device info (parsed from user agent) and last active date. The current session is marked with a badge.

// List all sessions
const sessions = authClient.multiSession.listDeviceSessions()
// Sign out all other devices
authClient.revokeOtherSessions()

Maximum: 5 concurrent sessions per user (enforced by backend).

Lists all organizations the user belongs to with name, slug, and role badge (Owner, Admin, Member).

Leave organization — Available for non-sole-owners. If the user is the only owner, the button is disabled with a tooltip: “Transfer ownership to another member before leaving.”

authClient.organization.leave({ organizationId })

Located in the Security tab danger zone. Requires the user to type the confirmation phrase Delete my account into a text input.

Restrictions: Cannot delete account if the user is the sole owner of any organization. Must transfer ownership or delete the organization first.

Deletion process:

  1. Revokes all user sessions
  2. Removes all organization memberships
  3. Bans the user account
  4. Anonymizes PII: name → [deleted-{userId}], email → deleted-{userId}@redacted.local
  5. Audit logged
  6. Redirects to sign-in page
authClient.deleteUser({ callbackURL: "/sign-in" })

Several sections are conditionally displayed based on system configuration:

FlagControls
auth.passkeyEnabledPasskey section visibility
socialProviders.{provider}.enabledPer-provider connect/disconnect
security.passwordMinLengthPassword validation (default: 10)
security.sessionDurationSession TTL (default: 24 hours)
FilePurpose
packages/web-shell/src/components/settings/user-settings-modal.tsxModal shell and tab routing
packages/web-shell/src/components/settings/tabs/profile-tab.tsxName, avatar, and language editing
packages/web-shell/src/components/settings/tabs/security-tab.tsxPassword, 2FA, passkeys, social, sessions, account deletion
packages/web-shell/src/components/settings/tabs/organization-tab.tsxOrg membership list and leave
packages/web-shell/src/components/account-menu.tsxModal trigger in app shell
packages/web-shell/src/components/shared/danger-zone.tsxReusable destructive action component
packages/backend/src/convex/modules/core/users/user_api.tsUser deletion and PII anonymization
packages/backend/src/convex/lib/core/auth/convex_auth.tsBetterAuth configuration (2FA, passkeys, social, sessions)