- classes.FrontendPermissionCatalog: the seeded rows, then codes activated
plugins declare through pact.HasFrontendPermissions (seeded row wins);
both permission editors offer it
- classes.MCPUserGuard (guard "user"): reads user.api_token, user.scope:*
and user.permission:*, allows with the route's checks (session scopes,
group grants, every code), dispatches with an in-memory token credential,
resolves usr_ personal tokens; registered in *pact.MCPGuards and published
as pact.MCPPersonalTokenResolver
- GET /_user/api/v1/token/me (user.api_token, user.scope:read) and the MCP
tool me (user_me)
- pact.MCPSubjectChanged on token revoke, Users saves and User Groups saves
and deletes
Boot runs before summer serve publishes the database, so the plugin's GORM
hooks, the Postgres jwt_blacklist store and its sweep now go through
lagoon.OnDatabase, and the jwt guard resolves the published store on every
request. A logged-out token is refused on jwt.auth, /fetch and /refresh.
The jwt guard reads the cookie names from classes.SessionCookieNames().
- password with confirmation on create, optional reset on update that
ends the user's sessions; the hash is never returned
- send_invite sends one invitation with an activation link after the
create commits
- organisation picker, avatar upload shared with the user API and the
frontend permission editor on the user form
- an email held by a deactivated user answers 422 instead of failing
on the unique constraint
- the privileged-member guard now also refuses a submitted password
- the list opens the preview, which shows one status hint (banned,
deactivated, not activated, suspended) and the IP address fields
- bulk actions activate, deactivate, restore, ban and unban; record
actions activate, unban and unsuspend, offered while they apply
- delete (form button and bulk) removes the user for good with the
throttle rows, group memberships and attachments in one transaction;
blobs go after the commit
- a privileged-group member is still refused, a bulk delete as a whole
- admin harness: boots the plugin with the admin API mounted and
mints backend administrators with chosen permissions
- TestAdminUsersTracer and TestAdminPrivilegedMember