User Settings
The Settings page (/dashboard/settings) gives each user control over their account security. It is built on Better Auth’s client-side plugins and provides three main security features: Two-Factor Authentication (2FA), Passkeys, and active session management.
2FA — Two-Factor Authentication
DBS uses TOTP (Time-based One-Time Password) via Better Auth’s twoFactor plugin. Users scan a QR code with any authenticator app (Google Authenticator, Authy, 1Password, etc.) and enter a 6-digit code to enable it.
Enabling 2FA
'use client';
import { authClient } from '@/lib/auth-client';
import { useState } from 'react';
import QRCode from 'qrcode.react';
export function Enable2FAForm() {
const [qrUri, setQrUri] = useState<string | null>(null);
const [backupCodes, setBackupCodes] = useState<string[]>([]);
const [step, setStep] = useState<'password' | 'verify' | 'done'>('password');
const handleEnable = async (password: string) => {
const { data, error } = await authClient.twoFactor.enable({ password });
if (error) {
toast.error(error.message);
return;
}
setQrUri(data!.totpURI);
setBackupCodes(data!.backupCodes);
setStep('verify');
};
const handleVerify = async (code: string) => {
const { error } = await authClient.twoFactor.verifyTotp({ code });
if (error) {
toast.error('Invalid code. Please try again.');
return;
}
setStep('done');
toast.success('2FA enabled successfully!');
};
if (step === 'verify' && qrUri) {
return (
<div>
<QRCode value={qrUri} size={200} />
<p>Scan with your authenticator app, then enter the 6-digit code:</p>
<TotpInput onSubmit={handleVerify} />
<div>
<strong>Backup codes (save these):</strong>
<pre>{backupCodes.join('\n')}</pre>
</div>
</div>
);
}
return <PasswordForm onSubmit={handleEnable} />;
}Disabling 2FA
const handleDisable = async (password: string) => {
const { error } = await authClient.twoFactor.disable({ password });
if (error) toast.error(error.message);
else toast.success('2FA has been disabled.');
};2FA Login Flow
When a user with 2FA enabled logs in, Better Auth returns a twoFactorRequired status. The login form should detect this and prompt for the TOTP code:
const { error } = await authClient.signIn.email({ email, password });
if (error?.status === 403 && error.message === 'twoFactorRequired') {
setShowTotpPrompt(true);
return;
}
// In the TOTP prompt:
await authClient.twoFactor.verifyTotp({ code: totpCode });Passkeys (WebAuthn)
Passkeys allow users to log in using their device’s biometrics (Touch ID, Face ID, Windows Hello) — no password needed.
Adding a Passkey
import { authClient } from '@/lib/auth-client';
const handleAddPasskey = async () => {
const { error } = await authClient.passkey.addPasskey({
name: 'My MacBook Pro', // User-defined label for this device
});
if (error) toast.error(error.message);
else {
toast.success('Passkey added!');
mutate(); // refresh passkey list
}
};Listing & Deleting Passkeys
// List all registered passkeys for the current user
const { data: passkeys } = await authClient.passkey.listUserPasskeys();
// Delete a specific passkey
await authClient.passkey.deletePasskey({ id: passkeyId });Passkeys are device-specific. Users should add a passkey on each device they want to use for passwordless login.
Session Management
Users can see all their active sessions and remotely revoke any of them — useful if they left a session open on a shared computer.
import { authClient } from '@/lib/auth-client';
// List all active sessions
const { data: sessions } = await authClient.listSessions();
// sessions[n].userAgent → browser + OS info
// sessions[n].ipAddress → last seen IP
// sessions[n].createdAt → when the session started
// sessions[n].isCurrent → is this the active session?
// Revoke a specific session
await authClient.revokeSession({ token: session.token });
// Revoke all sessions except the current one
await authClient.revokeOtherSessions();Settings API Endpoints
| Method | Endpoint | Permission | Description |
|---|---|---|---|
GET | /api/settings | settings.manage | Get all system configuration keys |
PUT | /api/settings | settings.manage | Update a system configuration key |
The /api/settings endpoints manage system-level configuration (like RESEND_API_KEY, APP_NAME). These are different from user-level settings (2FA, passkeys, sessions) which are managed exclusively through Better Auth client methods.