Files
bbeandCursor 70e3e0633d feat: roles/permissions system and Nostr profile display on admin users
Introduce granular role-based permissions with SuperAdmin env override, admin roles UI, and permission-gated API routes. Fix admin user Nostr metadata by batching relay profile fetches, normalizing npub pubkeys to hex, and adding reusable NostrAvatar/useNostrProfile components.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 08:46:56 +02:00

42 lines
2.2 KiB
Markdown

# Changelog
## Unreleased
### Roles and permissions system
Replaced the single moderator promote/demote toggle with a full role hierarchy
and a runtime-editable, granular permission system.
- **Role hierarchy**: SuperAdmin (env-only) > Admin > Moderator > Writer > Guest
(absence of a role). SuperAdmin always holds every permission and can never be
edited, demoted, or removed through the UI.
- **New env var `SUPERADMIN_PUBKEYS`** (comma-separated hex or npub) replaces the
old env-admin concept. Falls back to `ADMIN_PUBKEYS` when unset so existing
deployments keep working.
- **Permission registry**: a central list of granular keys in
`backend/src/constants/permissions.ts` is the single source of truth. Adding a
key there surfaces it automatically in the API and the Roles matrix page.
- **Authorization**: a single `requires(permission)` guard replaces the old
role-name middleware and is applied to every protected endpoint. Roles and
permissions are resolved live per request, so a stale JWT no longer drives
access. SuperAdmin bypasses all checks.
- **Data model**: `User.role` is now nullable (null means Guest) and uses the
lowercase enum `admin`, `moderator`, `writer`. A new `RolePermission` table
maps roles to permission keys. A migration backfills legacy uppercase roles and
seeds default permission sets; it is idempotent and safe on a live database.
- **New endpoints**: `GET /api/auth/me`, `GET /api/admin/permissions`,
`GET /api/admin/roles`, `PUT /api/admin/roles/:role/permissions`, and
`PUT /api/users/:pubkey/role` (replacing `POST /api/users/promote` and
`POST /api/users/demote`).
- **Dashboard**: User Management now uses a per-user role selector with hierarchy
enforcement and a locked SuperAdmin badge. A new SuperAdmin-only Roles page
renders a permission-by-role matrix. Nav items are gated on resolved
permissions. The NIP-05 reserved-username assignment is unchanged.
#### Migration notes
After pulling, from `backend` run `npm run migrate:deploy` (or, for databases
created with `db push`, `npm run db:baseline-and-migrate`). Set
`SUPERADMIN_PUBKEYS` in your `.env`. Existing moderators become `moderator`,
existing database admins become `admin`, and prior env admins become SuperAdmin.