← Building the Game — one site, the Builder, and the building blocks · all tasks
Sign in on the site with a game account; Kris is admin
building-the-game/003 · created 2026-09-03 · updated 2026-09-03 · blocked by building-the-game/002
What to do
POST /builder/auth/login (email + password checked against the game DB’s auth_identities
through the read-only role, with the Builder’s own copy of the scrypt verify — the game’s
tables gain no columns), minting a web_sessions row (token hash, 7-day expires_at,
revocable); POST /builder/auth/logout; GET /builder/auth/me. Authorization: Bearer only,
never a query token. Token buckets on every auth and write route. roles table
(account id → admin | player), seeded by npm run set-role -- <email> admin on the droplet.
Site: components/SignIn.astro modelled on RepoLinkDialog.astro; session in
lor:session (the footer’s “clear site settings” wipe doubles as sign-out); a header chip with
name and role. Admin-only UI is hidden client-side, and every write is enforced server-side.
Definition of done
Tests: login, expiry, revoked, wrong role 403, 429. Kris signs in on spellgrove.com and
/builder/auth/me says admin.
Built (2026-09-03)
Live. POST /builder/auth/login (game email + password, checked read-only against the game’s
auth_identities with the Builder’s own scrypt verify; 10 tries per 10 minutes per IP, 20 per
hour per email), POST /auth/logout, GET /auth/me; bearer web sessions, 7 days; roles
table; npm run set-role -- <email> admin. Kris’s account (Papa, kris.randall@gmail.com) is
admin. The site: a “Sign in” chip in the header opens the dialog; the token lives in
lor:session; <html data-role> gates editing controls client-side while the Builder enforces
every write. 10 tests. Not yet exercised with a real password — that is Kris’s own check.
Review artifact: builder/README.md
View source in repository · also available as raw markdown.