Skip to main content

Authentication and Account Management

This page explains how the authentication system works, why certain design decisions exist, and how the confirmation-token flows protect sensitive account changes.

For endpoint payloads, see Endpoints. For env vars, see Configuration.

Design Rationale

Better Auth manages sessions and the core auth lifecycle. The custom ProfileController extends this with a confirmation-token layer that enforces email verification before applying sensitive changes. This prevents account takeovers through unverified email addresses.

Session Lookup

Every protected profile endpoint calls getSession({ disableCookieCache: true }). This forces a live database read and prevents stale cookie state from granting access after a session is revoked.

Blocked Mutation Endpoints

The custom plugin confirmedAccountChangePlugin blocks three native Better Auth paths:

Blocked pathReason
/update-userBypasses email confirmation
/change-passwordBypasses current password check
/change-emailBypasses two-step email flow

When you call one of these paths, the API returns 400 BAD_REQUEST with code CONFIRMATION_REQUIRED.

Common Mistake

INCORRECT: Calling /api/auth/change-email directly from the frontend.
CORRECT: Use POST /api/profile/request-email-change to start the confirmed flow.

Callback URL Policy

Every profile change request requires a callbackURL. The API appends the confirmation token to this URL and includes it in the email.

Common Mistake

INCORRECT: callbackURL: "http://evil.example.com/confirm" — the API rejects untrusted origins.
CORRECT: callbackURL: "http://localhost:4200/profile/confirm" — must match a trusted origin.

Trusted origins in local development:

  • http://localhost:4200
  • http://127.0.0.1:4200

Profile Change Flow

One email confirmation updates name and nickname.

Email Change Flow

Two emails are sent — one to confirm the old address, one to verify the new address.

Password Change Flow

The API verifies the current password before storing the hashed new password. On confirmation, all active sessions are revoked.

The frontend must redirect the user to login after a password confirmation.

Validation and Error Reference

ConditionHTTP Status
Missing required field400 Bad Request
Untrusted or relative callback URL400 Bad Request
Email not yet verified403 Forbidden
Duplicate nickname or email409 Conflict
Invalid or expired token404 Not Found
No valid session401 Unauthorized