permissions.ts — admin abilities
Path: src/config/permissions.ts
Not every admin can do everything. This file is the single registry of admin capability strings and the role → permission matrix. Routes call hasPermission(...) or use requirePermission(...) middleware instead of hard-coding role checks.
Identity types the server recognises
| Identity | Detected by | Default permissions |
|---|---|---|
| Super admin | User.isAdmin === true (not a member of ADMIN_ROLES) | ALL_PERMISSIONS — every key in PERMISSIONS |
| manager | User.adminRole === 'manager' | full content + user management, no MANAGE_ADMINS and no MANAGE_RATE_LIMITS |
| creator | User.adminRole === 'creator' | content creation / editing, manage media + questions + PYQ + CA, no user / stats / admin / rate-limit power |
| Regular user | adminRole null and isAdmin !== true | [] |
Permission constants
| Constant | String value | Used by |
|---|---|---|
VIEW_USERS | view_users | Admin user list / detail |
DELETE_USERS | delete_users | Hard delete user (+ refresh tokens) |
VIEW_STATS | view_stats | Signup chart, top exams/states, notification metrics, rate-limit reads, marketing list/read |
VIEW_CONTENT | view_content | Announcements / exam-info read |
CREATE_CONTENT | create_content | Announcement / exam-info create |
EDIT_CONTENT | edit_content | Announcement / exam-info update |
DELETE_CONTENT | delete_content | Announcement / exam-info delete |
MANAGE_VIDEOS | manage_videos | Videos CRUD |
MANAGE_QUESTIONS | manage_questions | Video timestamps + MCQs + bulk import |
MANAGE_PLAYLISTS | manage_playlists | Playlist CRUD |
MANAGE_MOCK_TESTS | manage_mock_tests | Mock test CRUD |
MANAGE_PRACTICE_PYQS | manage_practice_pyqs | PYQ bank taxonomy / questions |
MANAGE_CURRENT_AFFAIRS | manage_current_affairs | CA issues, items, MCQs, flashcards, entities |
MANAGE_ADMINS | manage_admins | Promote/demote staff (super admin workflow) |
MANAGE_RATE_LIMITS | manage_rate_limits | Live edits to /api/v1/admin/rate-limits policies (super admin only) |
Role matrix
| super admin | manager | creator | |
|---|---|---|---|
VIEW_USERS | ✓ | ✓ | |
DELETE_USERS | ✓ | ✓ | |
VIEW_STATS | ✓ | ✓ | |
VIEW_CONTENT | ✓ | ✓ | ✓ |
CREATE_CONTENT | ✓ | ✓ | ✓ |
EDIT_CONTENT | ✓ | ✓ | ✓ |
DELETE_CONTENT | ✓ | ✓ | |
MANAGE_VIDEOS | ✓ | ✓ | ✓ |
MANAGE_QUESTIONS | ✓ | ✓ | ✓ |
MANAGE_PLAYLISTS | ✓ | ✓ | ✓ |
MANAGE_MOCK_TESTS | ✓ | ✓ | ✓ |
MANAGE_PRACTICE_PYQS | ✓ | ✓ | ✓ |
MANAGE_CURRENT_AFFAIRS | ✓ | ✓ | ✓ |
MANAGE_ADMINS | ✓ | ||
MANAGE_RATE_LIMITS | ✓ |
How it’s used
authMiddlewareloads the user and stashesisAdmin+adminRoleonc.get('user').adminMiddlewarerejects non-admins (must be super admin or have anadminRole).- Per-route
requirePermission(PERMISSIONS.X)consultshasPermission(isAdmin, adminRole, X). - If not allowed → 403 Forbidden.
// Inside admin.route.ts (example)
adminRouter.delete(
'/users/:id',
requirePermission(PERMISSIONS.DELETE_USERS),
async (c) => { /* … */ },
)When you add a new admin feature
- Add a string constant under
PERMISSIONS. - Add it to the relevant role arrays in
ROLE_PERMISSIONS(or leave it super-admin-only). - Guard the new route with
requirePermission(PERMISSIONS.YOUR_NEW_ONE). - Update this page and
routes/admin.mdxif it changes who sees the surface.
When you add a new role
- Add to the
ADMIN_ROLEStuple. - Add a full entry in
ROLE_PERMISSIONS. - Make sure the new role string is allowed in the
POST /api/v1/admin/adminsschema (assignRoleSchemainadmin.route.ts). - Update this matrix.
Last updated on