Skip to main content

EP-001: Authentication & Access Control

Business Objective​

Secure, role-based access is foundational to every hotel operation. Front desk agents, housekeeping staff, managers, and administrators all need different levels of access to the platform. A robust auth system protects guest PII (Aadhaar, passport data), financial data, and ensures audit compliance. Multi-factor authentication meets PCI-DSS and SOC 2 requirements.

Audience​

  • Primary: All staff (Front Desk Agent, Housekeeping Staff, F&B Staff, Manager, Admin)
  • Secondary: Super Admin (SaaS platform), Third-party API consumers

Scope​

In Scope​

  • User login (email/password) with JWT access + refresh tokens
  • Multi-Factor Authentication (TOTP via authenticator app)
  • Role-Based Access Control (9 roles with permissions)
  • Password management (history, complexity, reset, force-change)
  • SSO integration (OIDC/SAML for enterprise chains)
  • Session management (concurrent sessions, forced logout)
  • Brute-force protection (account lockout after N attempts)
  • API key management for third-party integrations
  • User CRUD (invite, activate, deactivate, delete)
  • Profile management (name, avatar, preferences)

Out of Scope​

  • Biometric authentication (fingerprint, face ID) — deferred to mobile app phase
  • Social login (Google, Facebook) — not applicable for staff portal
  • Hardware security keys (FIDO2/WebAuthn) — future consideration

Current Implementation Status​

  • Backend: Auth service fully built with controllers, DTOs, guards, strategies. JWT + refresh token flow. MFA via otplib/TOTP. RBAC with 9 roles defined in Prisma enum (SUPER_ADMIN, ADMIN, MANAGER, FRONT_DESK, HOUSEKEEPING, FNB, ACCOUNTS, RESERVATIONS, STAFF). Password history (last 5). Brute-force detection. Billing controller. Session management.
  • Dashboard: Login page with NextAuth v5 integration. User management pages in Settings. Role assignment. Password reset flow.
  • Mobile: Token-based auth in React Native apps
  • Tests: Auth guard tests, JWT strategy tests exist

Gap Analysis​

  • SSO (OIDC/SAML): Backend DTOs/controllers exist but no actual identity provider integration tested. Enterprise chains need this for SSO with their corporate directory.
  • API Key Management: Schema and basic endpoints exist but no dashboard UI for third-party developers to manage keys.
  • Audit Trail for Auth Events: Login/logout events logged but not surfaced in a dedicated security audit dashboard.
  • Password Expiry Policy: Password history exists but no configurable expiry enforcement (e.g., force change every 90 days).
  • IP Whitelisting: No support for restricting admin access to specific IP ranges — needed for enterprise security policies.

User Stories​

Story IDTitlePriorityPointsStatusSprint
US-001-001User Login with Email/PasswordP03Built1
US-001-002JWT Token RefreshP03Built1
US-001-003User Logout & Session InvalidationP02Built1
US-001-004MFA Setup (TOTP)P05Built1
US-001-005MFA Verification on LoginP03Built1
US-001-006Role-Based Access Control (9 Roles)P08Built1
US-001-007Password Reset via EmailP03Built1
US-001-008Force Password ChangeP12Built1
US-001-009Password History EnforcementP13Built1
US-001-010Brute-Force Account LockoutP03Built1
US-001-011User CRUD (Invite, Activate, Deactivate)P05Partial1
US-001-012SSO — OIDC IntegrationP28Partial14
US-001-013SSO — SAML IntegrationP28Partial14
US-001-014API Key Management for Third PartiesP25Partial14
US-001-015Password Expiry Policy ConfigurationP23Not Started14
US-001-016Security Audit Log DashboardP15Not Started8

Dependencies​

  • None (foundational epic — all other epics depend on this)

Acceptance Criteria (Epic Level)​

  • Staff can log in with email/password and receive JWT tokens
  • MFA can be enabled and enforced per user or per role
  • 9 roles with distinct permissions control access to all endpoints
  • Password policies (history, complexity, reset) are enforced
  • Account locks after 5 failed login attempts with configurable cooldown
  • All auth events are audit-logged with IP, user agent, timestamp
  • Session can be invalidated remotely by admin

KPIs / Success Metrics​

  • Login success rate > 99%
  • MFA enrollment > 80% for admin/manager roles
  • Account lockout false positive rate < 1%
  • Token refresh latency < 100ms
  • Zero unauthorized access incidents

Detailed User Stories​

US-001-001: User Login with Email/Password​

As a hotel staff member, I want to log in with my email and password, So that I can access the HMP dashboard with my assigned role.

Priority: P0 | Points: 3 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: POST /api/v1/auth/login — AuthController.login(). LoginDto with email/password validation. Returns { accessToken, refreshToken, user }.
  • Frontend: /login page with NextAuth v5. Credentials provider configured. Login form with email/password fields.
  • Tests: Auth guard tests, JWT strategy tests exist.

Acceptance Criteria​

Scenario 1: Successful login

  • Given the user has a valid account with email "frontdesk@hotel.com"
  • When the user submits correct email and password
  • Then the system returns a JWT access token (15-min expiry) and refresh token (7-day expiry)
  • And the user is redirected to the dashboard

Scenario 2: Invalid credentials

  • Given the user submits an incorrect password
  • When the login request is processed
  • Then the system returns 401 Unauthorized with message "Invalid credentials"
  • And the failed attempt is logged with IP address

Scenario 3: Deactivated account

  • Given the user's account has been deactivated by admin
  • When the user attempts to log in
  • Then the system returns 403 Forbidden with message "Account is deactivated. Contact your administrator."

Scenario 4: Missing tenant

  • Given the user's email is not associated with any tenant
  • When the user attempts to log in
  • Then the system returns 404 Not Found with message "Account not found"

US-001-002: JWT Token Refresh​

As a logged-in staff member, I want my session to refresh automatically, So that I don't get logged out during my shift while actively using the system.

Priority: P0 | Points: 3 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: POST /api/v1/auth/refresh — Uses refresh token to issue new access token. Refresh token rotation implemented.
  • Frontend: NextAuth handles automatic token refresh via JWT callback.

Acceptance Criteria​

Scenario 1: Automatic refresh

  • Given the access token is within 2 minutes of expiry
  • When the frontend detects the approaching expiry
  • Then a new access token is requested using the refresh token
  • And the user's session continues uninterrupted

Scenario 2: Expired refresh token

  • Given the refresh token has expired (> 7 days)
  • When a token refresh is attempted
  • Then the system returns 401 and the user is redirected to the login page

US-001-003: User Logout & Session Invalidation​

As a staff member, I want to log out of the system, So that my session is securely terminated, especially on shared front desk computers.

Priority: P0 | Points: 2 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: POST /api/v1/auth/logout — Invalidates refresh token.
  • Frontend: Logout button in sidebar. NextAuth signOut().

Acceptance Criteria​

Scenario 1: Successful logout

  • Given the user clicks "Logout"
  • When the logout request is processed
  • Then the refresh token is invalidated in the database
  • And the user is redirected to the login page
  • And subsequent API calls with the old access token are rejected after expiry

US-001-004: MFA Setup (TOTP)​

As an admin or manager, I want to set up two-factor authentication using an authenticator app, So that my account is protected against credential theft (PCI-DSS requirement).

Priority: P0 | Points: 5 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: POST /api/v1/auth/mfa/setup — generates TOTP secret, returns QR code URI. POST /api/v1/auth/mfa/verify — verifies TOTP code and enables MFA. Uses otplib.
  • Frontend: MFA setup flow in user profile settings. QR code display. Verification code input.

Acceptance Criteria​

Scenario 1: MFA setup flow

  • Given the user navigates to Security settings
  • When they click "Enable Two-Factor Authentication"
  • Then a QR code is displayed for scanning with Google Authenticator / Authy
  • And backup codes are displayed for emergency access
  • And the user must enter a valid 6-digit code to confirm setup

Scenario 2: Invalid verification code

  • Given the user enters an incorrect 6-digit code during setup
  • When the code is submitted
  • Then the system shows "Invalid code. Please try again."
  • And MFA is not enabled

US-001-005: MFA Verification on Login​

As a user with MFA enabled, I want to be prompted for my authenticator code after entering my password, So that an attacker with my password alone cannot access the system.

Priority: P0 | Points: 3 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: Login flow checks if MFA is enabled. If yes, returns mfaRequired: true and a temporary token. POST /api/v1/auth/mfa/validate completes login.
  • Frontend: MFA challenge screen shown when mfaRequired is true.

Acceptance Criteria​

Scenario 1: MFA challenge on login

  • Given the user has MFA enabled
  • When they successfully enter email and password
  • Then a second screen prompts for the 6-digit TOTP code
  • And upon valid code entry, the full JWT tokens are issued

Scenario 2: Invalid MFA code

  • Given the user enters an incorrect TOTP code
  • When submitted
  • Then "Invalid authentication code" is shown
  • And the user can retry (up to 5 attempts before lockout)

US-001-006: Role-Based Access Control (9 Roles)​

As a hotel admin, I want to assign specific roles to staff members, So that a front desk agent cannot access financial reports, and housekeeping staff cannot modify reservations.

Priority: P0 | Points: 8 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: 9 roles in Prisma enum: SUPER_ADMIN, ADMIN, MANAGER, FRONT_DESK, HOUSEKEEPING, FNB, ACCOUNTS, RESERVATIONS, STAFF. RolesGuard decorator. @Roles() annotations on controllers.
  • Frontend: Role assignment in user management. Route-level protection via middleware. Menu items filtered by role.

Acceptance Criteria​

Scenario 1: Role-based menu visibility

  • Given a user is assigned the FRONT_DESK role
  • When they log in to the dashboard
  • Then they see: Dashboard, Reservations, Front Desk, Guests, Housekeeping (view-only)
  • And they do NOT see: POS, Reports (financial), Settings, Super Admin

Scenario 2: API-level enforcement

  • Given a user with HOUSEKEEPING role
  • When they call POST /api/v1/reservations
  • Then the system returns 403 Forbidden
  • And an unauthorized access attempt is logged

US-001-007: Password Reset via Email​

As a staff member who forgot their password, I want to reset my password via email, So that I can regain access without contacting the admin.

Priority: P0 | Points: 3 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: POST /api/v1/auth/forgot-password — sends reset link. POST /api/v1/auth/reset-password — accepts token + new password.
  • Frontend: Forgot password page with email input. Reset password page with token validation.

Acceptance Criteria​

Scenario 1: Password reset flow

  • Given the user clicks "Forgot Password" on the login page
  • When they enter their registered email
  • Then a password reset email is sent with a time-limited link (30 minutes)
  • And the link leads to a "Set New Password" page

Scenario 2: Expired reset token

  • Given the reset link was generated more than 30 minutes ago
  • When the user clicks the link
  • Then "This link has expired. Please request a new password reset." is shown

US-001-008: Force Password Change​

As an admin, I want to force a user to change their password on next login, So that I can enforce security after a suspected breach or for new hires.

Priority: P1 | Points: 2 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: forcePasswordChange flag on user model. Checked during login. PATCH /api/v1/users/:id/force-password-change.
  • Frontend: Redirect to password change screen when flag is true.

Acceptance Criteria​

Scenario 1: Force change on login

  • Given the admin has set "Force Password Change" for a user
  • When the user logs in with their current password
  • Then they are redirected to a "Change Password" screen
  • And they cannot navigate to any other page until the password is changed

US-001-009: Password History Enforcement​

As a security-conscious admin, I want the system to prevent users from reusing recent passwords, So that compromised passwords are not recycled.

Priority: P1 | Points: 3 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: Last 5 password hashes stored. Checked during password change. Validation in auth service.
  • Frontend: Error message shown when password matches history.

Acceptance Criteria​

Scenario 1: Password reuse blocked

  • Given a user attempts to change their password to one of their last 5 passwords
  • When the new password is submitted
  • Then the system rejects it with "You cannot reuse your last 5 passwords"

US-001-010: Brute-Force Account Lockout​

As a security system, I want to lock accounts after repeated failed login attempts, So that brute-force attacks are prevented.

Priority: P0 | Points: 3 | Sprint: 1 | Status: Built

Implementation Status​

  • Backend: Failed attempt counter in Redis. Lockout after 5 failures. Configurable cooldown (default 15 minutes). IP-based tracking.
  • Frontend: "Account temporarily locked" message with countdown.

Acceptance Criteria​

Scenario 1: Account lockout after 5 failures

  • Given a user has failed login 5 times consecutively
  • When they attempt a 6th login (even with correct password)
  • Then the system returns "Account temporarily locked. Try again in 15 minutes."
  • And the lockout event is logged with IP address

Scenario 2: Lockout reset after cooldown

  • Given 15 minutes have passed since lockout
  • When the user attempts to log in with correct credentials
  • Then login succeeds and the failed attempt counter resets

US-001-011: User CRUD (Invite, Activate, Deactivate)​

As a hotel admin, I want to invite new staff, activate/deactivate their accounts, and manage their profiles, So that I can control who has access to the platform.

Priority: P0 | Points: 5 | Sprint: 1 | Status: Partial

Implementation Status​

  • Backend: User CRUD endpoints exist. Create user with role assignment. Activate/deactivate endpoints. List users with pagination.
  • Frontend: User management page in Settings with list view, create form, edit form. Role assignment dropdown.
  • Gap: Email invitation flow not fully wired (invite token generation exists but email sending not connected). Bulk user import not available.

Acceptance Criteria​

Scenario 1: Invite new staff member

  • Given the admin navigates to Settings > Users
  • When they click "Invite User" and fill in email, name, and role
  • Then an invitation email is sent with a link to set their password
  • And the user appears in the list as "Invited" status

Scenario 2: Deactivate staff member

  • Given an admin selects an active user
  • When they click "Deactivate"
  • Then the user's status changes to "Inactive"
  • And the user's active sessions are invalidated
  • And the user cannot log in

US-001-012: SSO — OIDC Integration​

As a hotel chain IT admin, I want to configure OIDC-based Single Sign-On, So that staff can log in using their corporate identity provider (Azure AD, Okta, Google Workspace).

Priority: P2 | Points: 8 | Sprint: 14 | Status: Partial

Implementation Status​

  • Backend: OIDC strategy skeleton exists in auth service. DTOs for OIDC configuration.
  • Frontend: No SSO configuration UI in settings.
  • Gap: No actual identity provider integration tested. No callback handling. No account linking.

Acceptance Criteria​

Scenario 1: OIDC login flow

  • Given the hotel has configured Azure AD as OIDC provider
  • When a staff member clicks "Sign in with Corporate Account"
  • Then they are redirected to Azure AD login
  • And upon successful authentication, they are logged into HMP with their mapped role

US-001-013: SSO — SAML Integration​

As a hotel chain IT admin, I want to configure SAML-based SSO for properties that use SAML identity providers, So that all chain properties share a single authentication system.

Priority: P2 | Points: 8 | Sprint: 14 | Status: Partial

Implementation Status​

  • Backend: SAML strategy skeleton exists. DTOs for SAML configuration.
  • Gap: No SAML metadata parsing, no assertion consumer service, no account linking UI.

Acceptance Criteria​

Scenario 1: SAML login flow

  • Given the hotel has uploaded a SAML metadata XML
  • When a staff member initiates SSO login
  • Then they are redirected to the SAML IdP, authenticate, and return with a SAML assertion
  • And HMP creates/links the user account based on SAML attributes

US-001-014: API Key Management for Third Parties​

As a hotel admin, I want to generate and manage API keys for third-party integrations, So that external systems (POS terminals, door locks, accounting) can authenticate with HMP APIs.

Priority: P2 | Points: 5 | Sprint: 14 | Status: Partial

Implementation Status​

  • Backend: API key model in schema. Basic generation and validation.
  • Gap: No dashboard UI for managing API keys. No scoping (all-or-nothing access). No usage tracking.

Acceptance Criteria​

Scenario 1: Generate API key

  • Given the admin navigates to Settings > API Keys
  • When they click "Generate New Key" and select permissions/scopes
  • Then a new API key is displayed (shown only once)
  • And the key appears in the list with creation date, last used, and status

US-001-015: Password Expiry Policy Configuration​

As a hotel admin, I want to configure password expiry policies (e.g., force change every 90 days), So that our security posture meets SOC 2 and PCI-DSS requirements.

Priority: P2 | Points: 3 | Sprint: 14 | Status: Not Started

Implementation Status​

  • Backend: Not implemented. Password history exists but no expiry tracking.
  • Frontend: No configuration UI.

Acceptance Criteria​

Scenario 1: Configure password expiry

  • Given the admin navigates to Settings > Security
  • When they set password expiry to 90 days
  • Then users who haven't changed their password in 90 days are forced to change on next login

US-001-016: Security Audit Log Dashboard​

As a hotel admin or security officer, I want to view a dashboard of all authentication events (logins, failed attempts, lockouts, role changes), So that I can monitor for suspicious activity and meet compliance audit requirements.

Priority: P1 | Points: 5 | Sprint: 8 | Status: Not Started

Implementation Status​

  • Backend: Auth events are logged but not exposed via a dedicated API endpoint for dashboard consumption.
  • Frontend: No security audit log page.

Acceptance Criteria​

Scenario 1: View security audit log

  • Given the admin navigates to Settings > Security Audit Log
  • When the page loads
  • Then a searchable, filterable table shows: timestamp, user, event type (login/logout/failed/lockout/mfa), IP address, user agent
  • And events can be filtered by date range, user, and event type
  • And CSV export is available