Public: anyone can read this; the crew can change it.
Remove on a cloud account goes through the confirm page, which names the account and says its sealed token goes with it #8014
Check · Review · Land · Live done — Landed and live in production.
Removing a cloud account on Settings › Cloud now asks first, as the terminal already does. The confirm page names the account and says its sealed token is deleted.
shipped production is serving it deploy 3b6d43c
Removing a cloud account on Settings › Cloud now asks first, as the terminal already does. The confirm page names the account and says its sealed token is deleted.
src/web/pages/cloud.ts: the Remove form with hidden fields is replaced byconfirmAction({ action: "/settings/cloud/remove?provider=…&name=…", verb: "Remove", size: "sm" }). The confirm page posts to itstopath exactly, so the account travels in the query.cloudRemovereadsproviderandnamefrom the form first and falls back toctx.url.searchParamswhen the form has none. The admin gate,readForm(ctx, "admin")andremoveAccountare unchanged.src/web/pages/search.ts: one newDESTRUCTIVEentry, directly after thesettings/originsentry, for^/settings/cloud/remove\?provider=([a-z0-9_-]+)&name=([a-z][a-z0-9_]{0,31})$. Its title is "Remove the <provider> account <name>?", followed by the detail text from the issue. Because the pattern is anchored, atowith an extra parameter matches nothing and gets a 404.test/confirm-cloud-remove.test.ts(new) proves three things:
- /settings/cloud links Remove to /-/confirm?to=…, and the old form action is gone.
- The confirm page answers 200 with the title and posts to the escaped target; a crafted to with &back=… gets a 404.
- The empty-body POST to the confirm target removes the account.
All three tests fail without the change.
The route in src/http/server.ts is untouched, as the issue asked.
Checks run before the push: bun scripts/gate.ts, bun x tsc --noEmit and bun scripts/design-lint.ts are clean. bun test test/confirm-cloud-remove.test.ts test/cloud.test.ts passes, 14 tests. scripts/fast.ts named 992 test files (too broad to run here), so I picked the covering suites myself: the cloud settings, doors, gate and timing tests, every confirm-* test, account unlink, search, cross-origin mutations, the security floor and the design audit. All 71 pass.
To try it: as an admin, open Settings › Cloud, press Remove on an account, read the confirm page, then press Remove account.
🤖 Generated with Claude Code
Works in the preview (confirm page answers 200 for the account target), no JS needed: Remove is an <a> to /-/confirm, the mutation is a POST, the admin gate and same-origin readForm are unchanged, the anchored pattern 404s a crafted target, and the three tests exercise each step. Two things I would do next: (1) the old button carried aria-label "Remove <name>"; confirmAction takes no label, so several accounts now expose identical "Remove" links to a screen reader. Give confirmAction an optional label and pass the account name. (2) The query fallback in cloudRemove makes the form fields dead for this route; drop the hidden() form fields path once nothing else posts them.
Removing a cloud account on Settings › Cloud now asks first, as the terminal already does. The confirm page names the account and says its sealed token is deleted.
src/web/pages/cloud.ts: the Remove form with hidden fields is replaced byconfirmAction({ action: "/settings/cloud/remove?provider=…&name=…", verb: "Remove", size: "sm" }). The confirm page posts to itstopath exactly, so the account travels in the query.cloudRemovereadsproviderandnamefrom the form first and falls back toctx.url.searchParamswhen the form has none. The admin gate,readForm(ctx, "admin")andremoveAccountare unchanged.src/web/pages/search.ts: one newDESTRUCTIVEentry, directly after thesettings/originsentry, for^/settings/cloud/remove\?provider=([a-z0-9_-]+)&name=([a-z][a-z0-9_]{0,31})$. Its title is "Remove the <provider> account <name>?", followed by the detail text from the issue. Because the pattern is anchored, atowith an extra parameter matches nothing and gets a 404.test/confirm-cloud-remove.test.ts(new) proves three things:- /settings/cloud links Remove to
/-/confirm?to=…, and the old form action is gone. - The confirm page answers 200 with the title and posts to the escaped target; a craftedtowith&back=…gets a 404. - The empty-body POST to the confirm target removes the account.All three tests fail without the change.
The route in
src/http/server.tsis untouched, as the issue asked.Checks run before the push:
bun scripts/gate.ts,bun x tsc --noEmitandbun scripts/design-lint.tsare clean.bun test test/confirm-cloud-remove.test.ts test/cloud.test.tspasses, 14 tests.scripts/fast.tsnamed 992 test files (too broad to run here), so I picked the covering suites myself: the cloud settings, doors, gate and timing tests, everyconfirm-*test, account unlink, search, cross-origin mutations, the security floor and the design audit. All 71 pass.To try it: as an admin, open Settings › Cloud, press Remove on an account, read the confirm page, then press Remove account.
🤖 Generated with Claude Code
Closes #7982