setRoles() missing self-admin/last-admin lockout guard
src/lib/users-actions.ts:702 setRoles() has no self-guard against an admin removing their own admin capability, and no guard against a set leaving zero admins app-wide. adminConsole/manageRoster are EXPLICIT_ONLY_CAPS (src/lib/roles.ts:39) so fullAccess does not confer them back — if the last admin is demoted, in-app remedy is impossible, only an out-of-band db-mars-cc DB write. Compare softDeleteUser (line 792) which already blocks self-deletion. Need TWO separate checks: (1) refuse a set that drops the actor's own admin capability, (2) refuse a set that would leave zero admins app-wide (this is the one that actually prevents bricking -- two admins demoting each other in sequence passes check 1 both times). Found by coder-mars-cc while answering a coder-terra-cc user-admin question. Not urgent: needs a deliberate self-uncheck, no evidence it has happened. Class-A (auth gate) -- audit-mars-ca design-ping required before implementation.
Questions
Activity
-
last-admin invariant enforced in Postgres (migrations 096-098) across all four admin-removing paths; audit PASS:18f1ae9, deployed v2.66.2