The platform uses role-based access control with two roles: admin and user. Roles are defined in userRole.enum.ts and enforced by middleware in auth.middleware.ts.

Role comparison

The dashboard route splits admin vs user via a role check in MainRoutes.tsx. Both roles authenticate with the same login flow (email/password + optional MFA).

pageAccess

Non-admin users do not see every index on the dashboard. Access is controlled by pageAccess — an array of IndexSetting ObjectId references on the User document.

How it works

When onboarding a new trader, create their account under Users, assign the indices they should monitor, and leave settings management to admins.

Admin auto-grant

Admins are automatically granted pageAccess to every active index. When a new index setting is created or activated, indexSetting.controller.ts updates all admin users with $addToSet: { pageAccess: _id }. Regular users must be explicitly assigned indices by an admin.

Authentication middleware

Routes are protected by composable middleware in auth.middleware.ts: Admin-only routes (user CRUD, index settings CRUD, schedule order cancellation) use isAdmin. Trading and dashboard APIs typically use isAuth so both roles can operate within their scope.

Single-session JWT

The platform enforces one active session per user. On login, the backend stores the issued JWT in the user’s loginToken field:
On every authenticated request, isToken middleware compares the Authorization: Bearer … header against the stored loginToken. If they do not match, the request is rejected.
Logging in from a second browser or device immediately invalidates the previous session. This is intentional — it prevents concurrent sessions from placing conflicting orders.

MFA

Users can enable TOTP-based multi-factor authentication via speakeasy. When MFA is active, login requires a valid TOTP code in addition to email and password. See MFA.