Authentication

Login, register, verify, reset, MFA. Standard flows; nothing surprising.

Routes

RoutePurpose
GET /auth/loginLogin form.
GET /auth/registerRegistration form.
GET /auth/verify?token=…Email-verification confirmation.
GET /auth/forgotRequest a password-reset email.
GET /auth/reset?token=…Reset password form.

Register

Email + password + confirm password + optional name. On submit:

  1. Account is created with verified: false.
  2. A verification email is sent with a 24-hour token.
  3. User is shown "check your email".

Until verified, the account can't log in.

Verify

Click the link in the email → GET /auth/verify?token=… → account is marked verified: true and the user is auto-logged in.

If the token is expired or used, a "request a new verification" link is offered.

Login

Email + password. Sessions are server-side (HMAC-signed cookies) with a 30-day rolling expiry.

If MFA is enabled, after password validates the user is prompted for the TOTP code.

Forgot password

Email input → reset link sent. Link is valid for 1 hour and single-use.

The reset form requires the new password twice. After reset, all existing sessions for that account are invalidated.

MFA (TOTP)

Set up in Account → Security → Two-factor.

  1. POST /api/auth/mfa-setup returns a TOTP secret + a QR code data URL.
  2. Scan with any TOTP app (Authy, 1Password, Google Authenticator).
  3. POST /api/auth/mfa-verify with the current 6-digit code confirms.
  4. Recovery codes (8 single-use) are shown once — save them.

Once enabled, every login requires the code after the password.

Recovery codes

Single-use 8-character codes. Used in place of the TOTP code if you lose your authenticator. Get a fresh batch in Account → Security → Recovery codes (invalidates the old batch).

Session cookies

  • HttpOnly + Secure + SameSite=Lax.
  • Signed with the server's secret.
  • 30-day rolling expiry — every authenticated request bumps the expiry.

Logout

POST /auth/logout invalidates the session server-side and clears the cookie. To log out of all sessions, see Account & profile.