feat: accounts v1, sign up with a Username, sign in on any device, reset a password by email #523
No reviewers
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
spec
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
amaurycoudr/chess-project!523
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "spec-364-accounts"
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?
Summary
A Player can create an Account (email, password, Username), sign in on any device, and reset a forgotten password by email. A signed-in browser holds Seats and owns Games as its Account, and every name shows as a Username or "Guest".
Delivered in tickets #378 (Sessions on the wire), #379 (sign-up and sign-in pages), #380 (password reset, Mailpit), #381 (rate limits), #382 (Seats and Games as an Account), #383 (account page), #384 (names by Username, switching devices end to end), then:
new-capandmax-paramsoff for Nest modules, controllers, services and guards;max-lines800 in source and off in tests;demo-account-a@chess.example/demo-account-a-password, same for B), with Games between Accounts, against a Demo Guest, and one with an ownerless side.Evidence
authoraccountrouter; a Player is a Guest on one browser.After: gate green on the tip (engine 742, api 710+, front 1206+ tests), browser suite 38/38 on a built stack with Postgres and Mailpit, including:
apps/api/test/rpc-*.integration.test.ts) cover each cookie and its attributes, refresh rotation, the 30-second grace and revocation on reuse, each Username rule, each rate limit one under and at its boundary with its retry-after, concurrent sign-in bursts, the reset link's single use and expiry, export contents, deletion cascades, and Seats held across devices.__Host-accessand__Secure-refreshon plain-HTTPlocalhostand127.0.0.1(Playwright Chromium 151): the refresh cookie travels only to its path,document.cookiestays empty,Max-Age=0clears both.Merge Danger
Door: one-way
Three migrations add
accounts,sessions,password_reset_tokensand the account-owner columns ongames. Once production has Accounts, rolling back the code strands their rows and their Sessions.Blast Radius: production
SESSION_SECRETandSMTP_URL. Before merging, rundeploy/owner-setup.shstages 4 and 6–9 (Session secret, Resend domain, DMARC, SMTP URL, preview Mailpit credentials), and stage 10 after the deploy.PREVIEW_MAILPIT_USERandPREVIEW_MAILPIT_PASSWORDexist (masked, not protected).pnpm env:syncthenpnpm db(session secret, mail settings, raised per-IP limits, Mailpit).account.me; every Room andgamecall goes through the guard, so a broken guard refuses everything.docker compose configand shellcheck only, not on the runner or the VPS.apps/api/src/auth/username.tsholds slurs, as a name filter must; worth a look.Proposed rule changes
Not edited here; each needs the owner's word.
apps/api/CODING_STANDARDS.md: reword "one feature module" to coverauth/,mail/and the guard; replace rule 5's Seat-token header line with the Guest header plus the access cookie the guard reads; namecommon/rate-limit.service.tsas a Nest service incommon/.apps/front/CODING_STANDARDS.md: review rule 1's vertical list missesgames/andauth/; rule 7 should allow a change of identity to reset the whole Query cache on success, as sign-in, sign-up, reset and deletion do.common/schema.tsandaccount.exportingames/, becausecommoncannot importauthandauthcannot importgames. Anaccount/folder aftergames/would give the export a natural home.MAILPIT_URL. Spec #394 listed Demo Accounts as out of scope; the owner brought them in under this spec.Closes #364
Closes #378
Closes #379
Closes #380
Closes #381
Closes #382
Closes #383
Closes #384
Screenshots
Before is production, after is this merge request's review app at
349270e.Desktop
Mobile
added 2 commits
605d73dd- chore(front): declare the auth vertical in the per-vertical import rules0b08e202- feat(front): sign-up and sign-in pages, the Account in the navigation, refresh on UNAUTHORIZEDCompare with previous version
added 2 commits
a9852fab- feat(api): take Seats and own decided Games as an Account, and name each occupante9801a33- Merge remote-tracking branch 'origin/spec-364-accounts' into ticket-382-seats-games-accountCompare with previous version
added 1 commit
b379bb71- feat(front): account page with an export download and deletion by passwordCompare with previous version
added 4 commits
2c7a9444- feat(front): name Seats and sides by Username, list an Account's Games, follow sign-in28225bbd- test(e2e): switch devices mid-Game as an Account, named by Username to a Guestc24a93ae- Merge remote-tracking branch 'origin/spec-364-accounts' into ticket-384-names-e2e6c498577- refactor(front): export a Game's PGN through lib's downloadCompare with previous version
added 8 commits
Compare with previous version
added 3 commits
Compare with previous version
added 6 commits
Compare with previous version
added 56 commits
main447c6e61- feat(front): tell a rate-limited Player when to try again on sign-up, sign-in and reset requests54f82a1a- fix(api): count sign-in failures atomically and revoke a Session on any old refresh tokene525470d- feat(engine): name a PGN side and date a PGN once, for every app that writes one4adadd10- refactor(api): write the export's PGN names and date through the engine's helpersb5e8c265- fix(front): name a side nobody owned ? in the PGN, as the account export does4fe09757- fix(front): follow a Room signed out once a lost Session refuses its streame0834c28- refactor(front): read who is signed in through one account query, and fire lib's signals once28ec752a- docs(repo): cite the Username and rate-limit ADRs as 0040 and 00410ab4a52d- fix(api): answer the devtools probe without reading the Session cookie8f876665- test(front): fit main's devtools tests to the account-aware games server and root callsCompare with previous version
added 4 commits
0042ac67- chore(repo): relax new-cap, max-params and max-lines as the owner decided9f3dd020- refactor(api): name the replaced token's grace check now the 500-line ceiling is gonef2f4eff5- test(front): let the devtools probe and who-is-signed-in through apart again87a43b72- test(front): smoke-test the /account route beside the other auth pagesCompare with previous version
mentioned in issue #398
added 6 commits
5e1b695a- feat(contracts): let the devtools probe answer Demo Accounts and the stack's Mailpit6c9ec5e9- feat(api): seed two Demo Accounts and their Games, and name them and Mailpit in the probecde2e5d1- feat(ci): name each preview's Mailpit to its app, for the devtools to link to3df5b3ad- feat(repo): name the dev Mailpit to each worktree's API, for the devtools to link to0cc8ff14- feat(front): sign in as a Demo Account from an Account panel in the devtools349270ed- docs(repo): define Demo Account, and stop the Demo Guest row calling itself oneCompare with previous version
marked this merge request as ready
changed the description
mentioned in issue #399
mentioned in issue #381
mentioned in issue #382
mentioned in issue #383
mentioned in issue #384
mentioned in issue #400
mentioned in commit
215cdba4c9mentioned in merge request !537