Email Change
Authenticated users can change their email address through a secure two-step verification flow.
How It Works
- User requests an email change with their new email and current password
- Server verifies the password and sends a verification link to the new email address
- User clicks the verification link (or submits the token)
- Server atomically updates the email across all indexes
Rate Limits
- 3 requests per user per hour
Client Usage
// Step 1: Request email change
await client.auth.changeEmail({
newEmail: 'new@example.com',
password: 'current-password',
redirectUrl: `${window.location.origin}/auth/verify-email-change`,
state: 'settings-profile',
});
// Step 2: Verify (user clicks email link, or submit token manually)
await client.auth.verifyEmailChange('verification-token');
changeEmail() also accepts redirectTo as an alias for redirectUrl. If you pass a redirect, EdgeBase appends token, type=email-change, and your optional state to that URL.
REST API
Request Email Change
POST /api/auth/change-email
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"newEmail": "new@example.com",
"password": "current-password",
"redirectUrl": "https://app.example.com/auth/verify-email-change",
"state": "settings-profile"
}
Response: { "ok": true, "token": "...", "actionUrl": "..." }
Verify Email Change
POST /api/auth/verify-email-change
Content-Type: application/json
{ "token": "verification-token" }
Response: { "user": { ... } } (updated user object)
Security
- Password re-confirmation: The current password must be provided to initiate the change
- New email verification: The verification email is sent to the new address (not the old one)
- Token TTL: Verification tokens expire after 24 hours (KV
email-change:{token}) - Single-use: Tokens are deleted after use
- Race condition protection: The new email is re-checked for uniqueness at verification time
- Disabled accounts: Returns
403if the account is disabled - Redirect allowlist: If
auth.allowedRedirectUrlsis configured, request-specific redirects must match that allowlist
Data Flow
1. POST /change-email + { newEmail, password, redirectUrl?, state? }
→ Verify password via D1 (AUTH_DB)
→ Check new email not registered in D1
→ Store token in KV (TTL 24h)
→ Build action URL from request redirect or emailChangeUrl fallback
→ Send verification email to new address
2. POST /verify-email-change + { token }
→ Read & delete token from KV
→ Re-check new email availability in D1
→ Register new email as pending in D1
→ Update email in D1 (AUTH_DB)
→ Confirm new email in D1, delete old email