Authentication
Overview
The iDARMS Back Office uses an OTP-based authentication system. Users log in with a User ID and password, then complete a 6-digit OTP verification step. Password recovery is also OTP-based (no security questions).
Navigate to: Application URL → /auth/login
Login Screen

The login screen presents a straightforward User ID + Password form — no social logins, no phone tab, no self-registration.
| Field | Required | Description |
|---|---|---|
| User ID | Yes | The username or email assigned to the back office user |
| Password | Yes | Show/hide toggle (eye icon) |
Actions:
| Element | Description |
|---|---|
| LOG IN button | Submits credentials for validation |
| Forgot Password? link | Navigates to the password reset flow |
Login Flow
Enter User ID + Password → Click LOG IN
↓
verified === 1? → YES → Dashboard
↓
NO (verified === 0)
↓
OTP Verification Screen
↓
Enter 6-digit code → Verify → Dashboard
!!! tip "Things to check" - Invalid User ID or password shows a clear error message, not a silent failure - Password field masks input by default and toggles visibility correctly - Forgot Password? link correctly navigates to the password reset flow - There is no self-registration or sign-up option — accounts are created by administrators via User Management
OTP Verification

After successful login, if the user's account is unverified
(verified === 0), an OTP verification screen appears.
| Element | Description |
|---|---|
| OTP input | 6-digit code input fields (individual boxes per digit) |
| Resend timer | 180-second countdown before resend is enabled |
| Resend link | Sends a new OTP code (disabled during countdown) |
| Verify button | Submits the OTP for verification |
OTP Flow
Login succeeds (verified === 0)
↓
OTP screen displayed
↓
Enter 6-digit code → Verify
↓
Success → Dashboard
Failure → Error message, can retry
↓
180s elapsed → Resend enabled → New OTP sent
!!! info "OTP Resend Cooldown" The resend button is disabled for 180 seconds after each OTP send. This prevents abuse and reduces server load. The countdown is displayed on screen.
!!! tip "Things to check" - The 6-digit input accepts only numeric characters - Entering the 6th digit auto-submits (or the user must tap Verify) - Invalid OTP shows a clear error and allows retry - Resend is disabled during the 180-second cooldown - Resend sends a new code and resets the timer - Correct OTP navigates to the Dashboard
Forgot Password

Navigate to: /auth/forgot-password or click Forgot Password? on the login screen
The forgot password flow is OTP-based — no security questions or email links.
Step 1: Enter User ID
| Field | Required | Description |
|---|---|---|
| User ID | Yes | The username or email to send the reset OTP to |
SEND OTP button submits the request.
Step 2: Enter OTP
| Field | Required | Description |
|---|---|---|
| OTP Code | Yes | 6-digit code sent to the user's registered email |
VERIFY button submits the OTP.
Step 3: Reset Password
| Field | Required | Description |
|---|---|---|
| New Password | Yes | Must meet password complexity requirements |
| Confirm Password | Yes | Must match New Password |
RESET PASSWORD button completes the flow and redirects to login.
Forgot Password Flow
/forgot-password → Enter User ID → SEND OTP
↓
OTP sent to registered email
↓
Enter OTP → VERIFY
↓
Success → New Password screen
↓
Enter + Confirm Password → RESET PASSWORD
↓
Redirect to Login
!!! tip "Things to check" - Entering a non-existent User ID shows a clear error, not a silent failure - OTP is sent to the correct email address associated with the User ID - The 180-second resend cooldown applies here as well - Password mismatch (New Password ≠ Confirm) is caught before submission - Password complexity requirements are enforced (min length, special chars, etc.) - After successful reset, the old password no longer works - Redirect to Login after reset is immediate
Session Management
| Feature | Behavior |
|---|---|
| Token storage | Encrypted in react-secure-storage (encrypted localStorage) |
| Session validation | On app load, authService.getSession() validates the token |
| Session expiry | Token expires after server-defined period; user is redirected to login |
| Logout | POST /auth/logout clears the token and session |
!!! tip "Things to check" - Refreshing the page preserves the session (token persists) - Expired session redirects to login, not a blank screen - Logout clears all stored tokens and redirects to login - Multiple browser tabs share the same session state
Security Notes
!!! warning "Known Issues"
- RBAC is disabled: All users have isAdmin: true. Role checks in
withRole are effectively bypassed. This must be enabled before production.
- Hardcoded secrets: API keys and OAuth secrets are present in
src/app/_utilities/config.ts. Do not commit additional secrets.