ERP Security Audit Report
==========================

Scope
-----

- Backend: Rust/Axum service in `backend` (authentication, authorization, superadmin APIs).
- Frontend: React/Vite app in `frontend` (JWT handling, local storage, account switching).
- Data: Non-destructive changes only; added isolated test artefacts for verification.

Backend Authentication
----------------------

- Confirmed JWT-based auth with access and refresh tokens backed by MongoDB `sessions` collection.
- Implemented and wired `GET /api/auth/me` so all panels can reliably fetch the current user.
- Ensured logout endpoint invalidates server-side session and the frontend clears tokens.
- Verified password-reset flow uses dedicated `password_reset_tokens` collection and does not expose raw tokens in logs.

Role-Based Access Control (RBAC)
--------------------------------

- Centralised SUPER_ADMIN check via helper that loads the user from `users` and enforces `role == "SUPER_ADMIN"`.
- Hardened the following sensitive superadmin endpoints to require SUPER_ADMIN:

  - Subscription plans and coupons
    - `GET /api/superadmin/plans` – list all subscription plans.
    - `POST /api/superadmin/plans` – create a plan.
    - `PATCH /api/superadmin/plans/:id/toggle` – activate/deactivate a plan.
    - `GET /api/superadmin/coupons` – list all discount coupons.
    - `POST /api/superadmin/coupons` – create a coupon.
    - `PUT /api/superadmin/coupons/:id` – update a coupon.
    - `DELETE /api/superadmin/coupons/:id` – delete a coupon.
    - `PATCH /api/superadmin/coupons/:id/toggle` – activate/deactivate a coupon.

  - Platform reports and analytics
    - `GET /api/superadmin/admins` – list all school admins and principals.
    - `PUT /api/superadmin/users/:id/assign-institute` – assign an admin to an institute.
    - `GET /api/superadmin/platform-users` – cross-institute user listing.
    - `GET /api/superadmin/reports/institutes` – institute-level summary.
    - `GET /api/superadmin/reports/user-activity` – login and activity metrics.
    - `GET /api/superadmin/reports/system-usage` – feature and time-based usage metrics.
    - `GET /api/superadmin/reports/financial` – platform revenue/expense/subscription overview.
    - `GET /api/superadmin/system-health` – overall system health dashboard.

  - System configuration and maintenance
    - `GET /api/superadmin/security-settings` – security configuration view.
    - `POST /api/superadmin/cleanup-users` – destructive cleanup that keeps only superadmin.
    - Announcement management APIs:
      - `GET /api/superadmin/announcements`
      - `POST /api/superadmin/announcements`
      - `PUT /api/superadmin/announcements/:id`
      - `DELETE /api/superadmin/announcements/:id`

- Verified that student, parent, teacher, accountant, librarian and other role-specific endpoints already enforce role checks and institute scoping as per panel features.

Superadmin Data Safety
----------------------

- All superadmin listing/report APIs that expose cross-institute data now require SUPER_ADMIN.
- Institute-scoped APIs for admins/teachers remain restricted to their own `school_id`/`institute_id`.
- Cleanup utility endpoint is strictly SUPER_ADMIN-only and not used in normal flows.

Unified Notifications
---------------------

- Unified notification endpoints are intentionally accessible to any authenticated user:

  - `GET /api/notifications/unified`
  - `POST /api/notifications/:id/read`
  - `POST /api/notifications/read-all`

- Each call is constrained by `user_id`:

  - Reads notifications filtered by the current user’s ObjectId.
  - Marks a notification as read only when it belongs to the current user.
  - `read-all` updates only the current user’s notifications.

Backend Build & Verification
----------------------------

- `cargo build` on `backend` now succeeds with all new auth/RBAC changes.
- No panics or obvious logic errors were introduced in modified handlers.
- Warnings remain for unused experimental modules (Keycloak, SQLx, Redis, advanced RBAC enums) but do not affect runtime.

Frontend Authentication & JWT Handling
-------------------------------------

- Authentication context (`frontend/src/contexts/AuthContext.tsx`):

  - Stores `access_token` and `refresh_token` in `localStorage`.
  - Persists `user`/`auth_user` for dashboard role-based routing.
  - Supports multiple account switching by keeping a `multiple_accounts` array in `localStorage` with id, email, role, and token.
  - On login:
    - Saves tokens and user profile to `localStorage`.
    - Updates `multiple_accounts` for account switcher.
    - Emits `user-authenticated` event for language preferences.
    - Redirects to dashboard based on `user.role`.

- API layer (`frontend/src/lib/api.ts`):

  - Attaches `Authorization: Bearer <access_token>` header using `getAuthHeaders`.
  - On 401:
    - Reads `refresh_token` from `localStorage`.
    - Calls backend token-refresh endpoint.
    - Updates stored tokens and retries the original request once.

- Logout:

  - Calls backend logout endpoint.
  - Clears `access_token`, `refresh_token`, `user`, `auth_user` and account state from `localStorage`.
  - Emits `user-logged-out` for language and other cross-tab handling.

Frontend Password & Secret Handling
-----------------------------------

- Frontend never hard-codes live API keys or secrets.
- Superadmin configuration screens (EmailConfig, PaymentGateways):

  - Treat API keys/secrets as opaque strings and send them to the backend via `apiRequest`.
  - Mask secret values in UI with password-type inputs and toggleable visibility.
  - Do not log secret values client-side.

- Environment variables:

  - Frontend uses Vite’s `import.meta.env` only for public configuration like API base URL.
  - Backend secrets (JWT secrets, DB URLs, Redis URL, Keycloak credentials) reside only in backend `.env`.

Known Trade-offs & Recommendations
----------------------------------

- JWT storage:

  - Access/refresh tokens are stored in `localStorage`, which is susceptible to XSS if an attacker can inject script.
  - Mitigation in place:
    - No tokens in query strings or URLs.
    - Tokens are never logged from frontend code.
  - Recommendation:
    - For higher security environments, migrate to HttpOnly, secure cookies and CSRF protection, which will require coordinated backend and frontend changes.

- Multiple account support:

  - `multiple_accounts` in `localStorage` includes a copy of access tokens for convenience.
  - Recommendation:
    - Limit token lifetime on the backend (short-lived access tokens with refresh) and monitor for suspicious multi-account activity.

- Experimental modules:

  - Backend contains unused modules for Postgres, Redis, advanced RBAC enums, and OAuth/Keycloak integration.
  - Recommendation:
    - Either wire these modules fully with end-to-end tests or remove them to reduce attack surface and maintenance overhead.

Test Data & Non-Production Artefacts
------------------------------------

- Test users (created via `/tmp/ensure_test_users.js`):

  - Users:
    - `superadmin@test.com` – SUPER_ADMIN – `TEST_SUPER_ADMIN`
    - `admin@test.com` – SCHOOL_ADMIN – `TEST_SCHOOL_ADMIN`
    - `teacher@test.com` – TEACHER – `TEST_TEACHER`
    - `accountant@test.com` – ACCOUNTANT – `TEST_ACCOUNTANT`
    - `student@test.com` – STUDENT – `TEST_STUDENT`
    - `parent@test.com` – PARENT – `TEST_PARENT`

  - All are marked `status: "ACTIVE"` and `is_active: true`.

- Test institute:

  - Inserted (idempotently) into `erp_school.institutes`:
    - `name`: `Test Institute - Security Audit`
    - `email`: `test-institute@example.com`
    - `code`: `TEST_SEC`
    - `is_active`: `true`
    - `status`: `ACTIVE`
  - Linked all six test users by setting their `school_id` to this institute’s `_id`.

- Safety:

  - No real data was deleted or modified; only records with test emails were updated.
  - Test institute is clearly identified by `code = "TEST_SEC"` for easy cleanup if needed.

Summary
-------

- Authentication:

  - Confirmed robust JWT-based auth with server-side sessions and refresh flow.
  - Implemented `GET /api/auth/me` for consistent user retrieval across dashboards.

- Authorization:

  - Hardened all sensitive superadmin and cross-institute endpoints with a central SUPER_ADMIN check.
  - Verified student/parent/teacher/admin panels respect role and institute boundaries.

- Frontend security posture:

  - JWT and user state stored in `localStorage`; safe for current environment but not ideal for high-security contexts.
  - No hard-coded secrets; secret configuration flows through backend-only storage.

- Data:

  - Added clearly labelled test institute and linked test users for safe end-to-end verification.

Overall, the platform is now significantly better protected against privilege escalation and unauthorized access, with clear next steps identified for environments that require stricter token handling and further hardening.

