Features Apograph CMS on GitHub

Users plugin

Managing the people in a CMS — and the one thing this plugin deliberately does not do.

Documents 0.5.2 Updated Edit this page Report a problem

On this page

Member management: the API behind the admin’s Members page. It issues invites and password-reset links; the identity plugin owns the tokens table and the redemption halves of both flows.

Install

npm install @apograph/users-server @apograph/users-admin

Register

// apps/server/src/plugins.ts
import { UsersPlugin } from '@apograph/users-server';

UsersPlugin();
// apps/admin/src/plugins.ts
import { UsersPlugin } from '@apograph/users-admin';

UsersPlugin();

No configuration, no environment variables, and no tables of its own — it reads and writes identity’s.

What it does

Under /api/users: a searchable, paginated member list; one member’s detail; invite by email; edit name and role; enable and disable an account; rotate or revoke a pending invite; and mint a password-reset link.

Disabling an account also revokes its live sessions, which is what makes “disabled” mean disabled rather than “cannot sign in again”.

Each row carries a server-computed isLastAdmin flag, and the UI disables the controls that would remove the last administrator. That protection lives here and does not run on the SSO path — a role mapping can never demote an existing admin either, but for a different reason.

An invite token is revealed once

POST /users/invites returns the raw token in its response and stores only its hash. The list and detail reads never carry it. Rotating a pending invite kills the link the invitee may already hold, so handing the new one over is the rest of the operation, not a nicety.

No email is sent

There is no mail transport in Apograph. An admin copies the link and delivers it themselves — by whatever channel they already trust.

Accounts are not deleted

DELETE /users/:id/invites revokes a pending invite by deleting the placeholder row. Real accounts are never deleted through this API; they are disabled, so the audit log keeps naming somebody who exists.