Public: anyone can read this; nobody can change it.
An invite link opens signup once while signup is invite: the form, the passkey door and the API take its token, and the account and the invite's use are one write #49
Check · Review · Land done · Live — Landed; nothing deploys from this branch, so this is the end of its path.
**Depends on #43.** This branch is on top of #43 (`createUser` takes a required `origin`). Its first commit is #43's commit. Review only the top commit, c146f52b. Merge #43 first.
shipped merged
Sign in to join this conversation.
Depends on #43. This branch is on top of #43 (
createUsertakes a requiredorigin). Its first commit is #43's commit. Review only the top commit, c146f52b. Merge #43 first.Problem. Invite links did nothing. The admin can make, list and revoke them (#2353, #2377, #2361). But signup never read an invite. In
invitemode,/signup?invite=…said "Signup is closed".used_atandused_bywere never written.Root cause. The signup gate had no invite input.
newAccountsClosedtreatedinvitethe same asclosed("until #1143").Fix.
signupandpasskeyorigins ofcreateUsercan carry an invite token beside theirSignupSlot.parentandedgecannot. The gate increateUserlets a stranger in while signup isinviteonly with an open invite. The invite is not used, not revoked and not expired. The forge finds it by its sha256 hash, so no code compares the secret.redeemInviteis one conditionalUPDATE ... WHERE token_hash = ? AND used_at IS NULL AND revoked_at IS NULL AND expires_at > now. It runs in the same transaction as the user INSERT. Two sign-ups with one link make one account. A taken name gives the invite back. A passkey sign-up whose key is refused also gives it back (discardFreshUser).?invite=from their own URL. The form action keeps it.POST /api/v1/usersreadsinvitefrom the body. The sign-up window still applies. Inopenmode the forge does not use an invite. Inclosedmode an invite opens nothing.settings/signup.tssay this. The terminal has no invite input.Test.
test/invite-redeem.test.ts: the form, the API (two requests at the same time) and the passkey door each use a link one time. Used, revoked, expired and unknown links make nothing. A taken name does not use the link. Inclosedmode nothing is made. Inopenmode the link is not used. On #43: 4 of 7 fail (the 3 guard tests pass). With the fix: 7 of 7 pass.Validate (fast). Result: flaky, no new failure.
contain.test.tsis baseline.tui-sentinel,returnsandog-pngfailed one time under box load. They are not red on main 833e7f51, and they pass when run alone. tsc passes.After this lands, the MCP
signuptool text in #46 ("invite links are not redeemed yet") must change.