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>
42 lines
2.2 KiB
Markdown
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.
|