feat(auth): self-service password reset (backend + web) #75
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/password-reset"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What & why
Adds a full self-service password-reset flow to the website. This is the hard prerequisite for the Android app (
docs/android/PLAN.md§8.2) — the app hands off to the website's reset page rather than shipping a native reset screen, so no mobile reset endpoint is needed.Backend
password_resetstable — stores only the sha256 hash of an opaque 32-byte token (same pattern asuser_invites/mobile_refresh_tokens), single-use, ~1h TTL.model/passwordResets/*andusers.getActiveByEmail(email is intentionally non-unique, so a request can match several accounts — each is emailed its own link naming its username).mailer.sendPasswordReset(fails soft when email isn't configured).POST /auth/password/forgot— always returns a generic 200 whether or not the email matches (no account enumeration).GET /auth/password/reset/:token— validate a link →{ username }, else 404.POST /auth/password/reset/:token— consume the single-use token, rotate the hash, and revoke every session (web cutoff + mobile refresh tokens). Does not auto-login, so a 2FA account still passes TOTP on next sign-in. Also serves SSO-only accounts (null hash) as their "set an initial password" path.Web
ForgotPassword+ResetPasswordpages, routes/account/forgotand/account/reset/:token, and a "Forgot your password?" link on the player login page.How it was tested
npm test(server) — all 208 tests pass (5 new intest/passwordResets.test.js).npm run build(client) — builds clean.Checklist
AI-assisted contributions (required)
Claude Code (Claude Opus 4.8). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with aCo-Authored-Bytrailer.License
Docs counterpart: RunicGateway/docs#(docs/password-reset) updates
BACKEND_DESIGN.mdfor these endpoints + table.🤖 Generated with Claude Code
https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr