feat(registry): claim an operator-made account through a sign-in #282
Loading…
Reference in a new issue
No description provided.
Delete branch "loop/276-registry-account-claim"
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?
Closes #276
An account the operator made has no identity, so its person can never sign in or enrol a second factor, and its tokens stay unbound. This PR lets such an account be claimed.
The claim link
POST /api/1/accounts/<name>/claim, operator only, answers201 {message, account, url, expires}.403for an account token or no token,404for an unknown account,409for an account with an identity or a passkey, or when no provider is configured.claimstable: one hour, one per account, and a new link replaces the old one in the same transaction.create-claimevent names the account only.The claim page
GET /account/claim?token=shows a button per provider and uses nothing up.no-referrer,no-store, and the account page's CSP with the providers inform-action.403.Redeeming
POST /account/claim {token, provider}begins the ordinary provider flow (state, PKCE, flow cookie) with the claim's digest on it, in the new columnsign_in_flows.claim.Sec-Fetch-Site: same-origin. A browser that sends no such header is refused too, because the form carries no session secret and a forged POST would link an identity to someone else's account for good.claim-accountevent is written. Then a session starts.409that keeps the claim. An account that gained a way in meanwhile is a409that ends the claim.Operator tokens
POST /api/1/tokensfor an account that can sign in and has no factor is now a403.Tests
tools/registry/tests/claim.test.trb, using the stand-in provider. It covers:Sec-Fetch-Site, a missing or malformed token, wrong or used state, another browser, injected PKCE, an identity linked elsewhere, a flow begun before the claim was used, a flow begun on a replaced link, an expired claim, two redeems at once, an account that gained an identityTorb-Codeis requiredfactor-before-tokensandstep-upare adjusted for the operator's403.Docs
tools/registry/README.md: call table, the #274 bullet, a new claim bullet with its known limits, and "Not built yet".releasing.mdstep 6: the claim link and itscurl.skills/is unchanged:releasing.mdisskill: omit, and the other two files are not skill sources.An architect review found no blockers. Its minor points were addressed: same-origin-only POST, the claim page and README now say to revoke the operator's tokens, the operator should keep query strings out of the access log, the flagged-passkey state is documented as a known limit, and more negative tests were added.
I couldn't compile or test locally (no
torbbinary on this host), so CI is the first compile. The SQL was checked against SQLite separately.CI red on
37e6d4d:ci / tier A (linux-x64)(and soci / gates) - theformat --checkgate fails:./tools/registry/tests/claim.test.trb("1 of 1232 files would change"). Runtorb formaton that file and push; every other check on this head is green. No review yet - it follows once CI is green.torb deprecate: flag a whole package as deprecated #279torb owner --step-up: approve owner changes with a passkey #280torb deprecate: flag a whole package as deprecated #279login,logout,ownerandyankcommands #22Review of
d0a18a5(CI green on this head).Findings
mainhas moved to6f9d340since this branch's merge base (a183078), and the PR reportsmergeable: false. The files changed onmainsince then overlap this PR:tools/registry/README.md,docs/design/RELEASE.mdand.pdisc-sidecar.yaml(plusINDEX.md/skill reference regeneration that follows from them). Rebase onto currentmain, resolve those, re-runpdiscstamp/index so the sidecar and INDEX match, and push. CI then runs again on the new head and I review that head.Checklist (what I read; no further blockers found)
claim.test.trbcovers the issue's acceptance list (statuses, digest-only storage, page headers, full claim then sign-in, cross-site/no-header POST, wrong/used state, other browser, PKCE, identity linked elsewhere, replaced/expired link, concurrent redeem, account gaining an identity, TOTP after claim, migration);factor-before-tokensandstep-upadjusted for the operator's403.claimed()decides found/linked/ways in one transaction and deletes the claim only when redeemable, so of two redeems one wins and a linked identity keeps the claim; a claim flow can never reach sign-in or sign-up; the claim page andstartClaimgive one generic403for every unredeemable link;createClaimis operator-only, replaces atomically and cleans up expired rows.Sec-Fetch-Site: same-originrequired on the POST;no-referrer/no-store/CSP on the page; no new ports, secrets or dependencies.migrate()addssign_in_flows.claimandclaimsadditively.Once it is rebased and green I expect to approve and merge without another round.
d0a18a525bd419080ecdReview of
d419080(CI green on this head; checked against my review ofd0a18a5).Findings
mainmoved on to22eed51after your rebase (merge base is6f9d340; the PR reportsmergeable: false). The four new commits onmain(std/toml,torb ownerstep-up, registry answer kept out of the work directory) touch files this PR also changes:tools/registry/README.md,docs/design/RELEASE.mdand.pdisc-sidecar.yaml(plus the INDEX/skill-reference regeneration that follows). Rebase onto currentmain, resolve those, re-runpdiscstamp/index so sidecar and INDEX match, and push. The README call table and the RELEASE.md 7.6 rows are the likely conflict spots, sinceowner-step-uplanded there.What I re-checked
d0a18a5only by the rebase onto6f9d340and thetorb formatcommit (claim.test.trb, call parentheses only). My earlier read of tests, correctness, security, data, docs and scope stands: no further blockers.Nothing else is outstanding. Once the PR is rebased onto the then-current
mainand CI is green I will approve and merge without another round.d419080ecdade02e83e2Review of
ade02e8(CI green on this head; mergeable). Checked against my reviews ofd0a18a5andd419080.Earlier blockers: the "not mergeable" finding is resolved. The branch is rebased onto
22eed51and no longer conflicts;mainhas since moved only incompiler/src/ir/devirtualize.trb, its test anddocs/PERFORMANCE.md, which this PR does not touch. The format gate that failed on37e6d4dnow passes (c8b9c5e), and pdisc is green after the README restamp (ade02e8).Checklist
claim.test.trbcovers the issue's list (link statuses and replace, digest-only storage, page headers, full claim then sign-in, cross-site/same-site/no-header POST, bad token/state, other browser, PKCE, identity linked elsewhere, replaced/expired link, concurrent redeem, account gaining an identity, TOTP after claim, migration);factor-before-tokensandstep-upadjusted for the operator's 403.claimed()decides found/linked/ways and deletes the claim in one transaction, so of two redeems one wins; a linked identity keeps the claim, an account that gained a way in ends it; a claim flow never reaches sign-in or sign-up; every unredeemable link gets the same 403.migrate()addsclaimsandsign_in_flows.claimadditively.No blockers. Approving and merging by rebase.
torb deprecate: flag a whole package as deprecated #279torb deprecate: flag a whole package as deprecated #279