← Server architecture · all tasks

Password reset by hand — a support address, not self-service

backlog priority 3 estimate S

server-architecture/017 · created 2026-08-13 · updated 2026-08-13

What this is

Kris’s call, 2026-08-13: there is no self-service password reset. Email login stays (it’s how the web build signs in), but a player who forgets their password emails a support address, Kris confirms it’s really them, and Kris resets it by hand.

This replaces both earlier attempts at the problem: the emailed reset link (blocked on DNS at a panel with no API — task 012) and an automated recovery code (built 2026-08-13, then reverted the same day; a code written down at signup is a second secret handed to someone who just demonstrated they lose secrets, so for this game’s players the realistic recovery rate is near zero).

Doing it by hand is the honest answer at this scale. There are no players yet; when there are, a human reply is better service than a broken robot, and it can be automated later if the volume ever justifies it.

Step 2 is done — the server no longer lies (2026-08-13)

request_password_reset used to ack and silently do nothing, so a client could say “check your email” for a mail that would never arrive. It now returns RESET_UNAVAILABLE with a message read from the new SUPPORT_EMAIL env var: with an address set it says “email X and we’ll sort it out”; with none set (the current state) it says plainly that passwords cannot currently be reset and names no channel at all — inventing a contact route the player can’t use is the exact failure being fixed. Deployed and verified live.

Turning this on is one env-file line plus game/update_game_env.sh — no code change, no rebuild.

Worth knowing: nothing in the Godot client ever called request_password_reset (there’s a helper in account_session.gd and no UI), so no player was ever actually shown the false promise.

What to do

  1. Pick the address (Kris) — the open item. It needs a mailbox that actually RECEIVES mail; this is unrelated to task 012’s Resend sending setup and does not require it. What was ruled out on 2026-08-13: @cocreations.com.au addresses don’t work, and the reason is worth recording — the domain’s MX points at sv1.byethost1.org (the Byethost free-hosting web server), whose Exim accepts mail for every address at the domain (kris@ and a deliberately fake address both answered 250 Accepted) and then has no mailbox to deliver into. Mail arrives somewhere that can’t store it. Fixing that needs real hosting, which is the same wall task 012’s DNS work hit.

    ai-task-runner.com is explicitly ruled out (Kris, 2026-08-13) — it was floated only because its DNS sits somewhere with a working API, but it is the task-runner platform’s domain and has no business carrying game mail.

    The intended answer is spellgrove.com (Kris, 2026-08-13): register the working title’s domain and use it for both the public site and email, set up deliberately and simply, with DNS under an API key an agent can actually use. That’s 018. Until it exists, a plain new Gmail forwarded to Kris’s inbox is the stopgap — and since SUPPORT_EMAIL is just an env var, swapping the stopgap for the real address later costs one line.

  2. Make the server honest — done, see above.

  3. Give Kris a reset command — resetting by hand currently means hand-rolled SQL against auth_identities, which is exactly how a wrong row gets updated at 11pm. identities.ts already exports updateIdentityPassword; a small one-shot admin script (email in, new password out, refuses on no-match) wrapping it is the whole job. It should also revoke that account’s sessions, per 014’s reasoning that a forgotten password may be a stolen one.

  4. Client copy — the “forgot password” surface says to email the address.

Definition of done

Assumptions

That email+password login itself stays exactly as it is — Kris confirmed the web build still needs it. Nothing here changes signup, login, link codes, or the provider paths.

View source in repository · also available as raw markdown.