Public: anyone can read this; the crew can change it.
Accounts: the owner sees who joined, hears of each, and can suspend or remove one #682
Check · Review · Land · Live done — Landed and live in production.
Closes #660
shipped production is serving it for issue #660 — its issue is already done deploy 127a6c2
commented
Review changes are in (6ad6ab6, rebased on main):
- Live SSH sessions: every signed-in SSH session (terminal, app tty, git) now listens for
account.suspendedandaccount.removedand exits there and then (endOnSuspensioninsrc/tui/ssh.ts). New test: an open terminal session for a fresh account ends with exit 1 and a plain message when the owner suspends it. The test fails with the call removed. - Migration 48, after #677's 47; #677's content-based fix to the OAuth migration test is kept.
- Address: the signup audit now uses main's
clientAddress(src/http/peer.ts) instead of a second copy of the peer map, so #697 (the real client address behind the proxy) fixes the audit with the rate limits. - The "verified" column: the accounts page has none yet. Email verification arrives with #659 (the crew is building it); its pull should add the column and an owner "mark verified" action here.
- Gate: one failure, the crew stand-in test, which also fails on main.
🤖 Generated with Claude Code
Sign in to join this conversation.
new above
offline
Closes #660
The owner can see every account, hears of each new one, and can suspend or remove one. Signups are audited.
What changed
/settings/accountsandGET /api/v1/admin/accountslist each account newest first: when and how it joined (signuporedge, and the address), its repositories, apps and crew spend, and its standing.POST …/admin/accounts/:username/suspend, or the page with a confirm step). Every credential stops at once: session, token, password, edge sign-in and SSH key all go through oneisActivecheck. What the account's repositories had queued is cancelled and their apps are stopped (the data stays). Nothing runs, deploys, wakes or restarts at boot for a suspended or removed owner: the crew dispatcher, checks, deploys, wake and the boot loop each check the owner's standing. Unsuspend restores sign-in; old tokens stay dead.DELETE …/admin/accounts/:username; the page asks you to type the name). It does what suspend does, then deletes the account's repositories and their apps, drops its keys, settings, memberships and connected forges, and scrubs its email and display name. The row stays, so the name stays taken and what it said on others' threads keeps its author. An account with nothing in it can be removed the same way.user.createdcarriesviaandaddressfor both ways in, plusaccount.suspended,account.unsuspendedandaccount.removed.suspended_atandremoved_atwithADD COLUMN, never a table rebuild.Tests:
test/accounts.test.ts(in the gate) uses fresh outsider accounts. A non-admin and an anonymous caller see nothing and can do nothing. The list showsviaand holdings. Suspension kills token, cookie, password, edge and SSH access and blocks creation. A suspended owner's queued run is cancelled and the crew queues nothing. Unsuspend restores password sign-in. Removal deletes repos and credentials, keeps the name taken and keeps others' threads. An empty account can be removed. Self, another admin and an agent are refused. The admin hears of a new account exactly once. A trigger refusal answers 403 and leaves no directory.tsc --noEmitis clean apart from an error already on main intest/apps.test.ts.🤖 Generated with Claude Code