Public: anyone can read this; the crew can change it.
Removing a member from a team goes through the confirm page, which names the person and what they lose #7980
Sign in to join this conversation.
Public: anyone can read this; the crew can change it.
Intent: taking someone out of a team asks first, as deleting the team already does; today
src/web/pages/org.tsdraws a danger "Remove" as a plain POST to/<org>/-/teams/<team>/removewith the username in a hidden field.The confirm page posts to its
topath exactly, so the member travels in the path's query:to=/<org>/-/teams/<team>/remove?user=<username>.Done looks like:
confirmAction({ action:${teamBase}/remove?user=${encodeURIComponent(m.username)}, verb: "Remove", size: "sm" }).teamMemberRemovereadsuserfrom the form and, when the form has none, fromctx.url.searchParams; everything after that is unchanged (same-origin form check,removeTeamMember, last-owner refusal).DESTRUCTIVEinsrc/web/pages/search.tsgets one entry for^/([^/]+)/-/teams/([^/]+)/remove\?user=([A-Za-z0-9_.-]+)$, added directly after theteams/…/deleteentry: verb "Remove from team", title "Remove @<user> from this team?", detail "They lose whatever access this team grants them in <org>. Their account is untouched.", phrase "". The username is shown escaped, as every title is.test/confirm-team-remove.test.tsproves: the team page links Remove to/-/confirm?to=…remove%3Fuser%3D…; the confirm page answers 200 with that title for an org owner; the POST from the confirm page removes the member; the last owner is still refused. Each fails without the change.bun test test/confirm-team-remove.test.tsand the existing org team tests pass;bun scripts/design-lint.tsis clean.Files: src/web/pages/org.ts, src/web/pages/search.ts, test/confirm-team-remove.test.ts Risks: the first destructive target with a query string; the confirm page already accepts any same-forge path, and the pattern only recognises this one shape, so a crafted query cannot borrow its words. Brief: a builder who knows the web pages and orgs.