pediatric-ai-scribe-v3/src
Daniel 6dffdf91e5 Sliding 24h idle timeout (web) + persistent mobile + 2FA backup codes
Session model:
  Web     — 24h sliding idle timeout enforced server-side via
             user_sessions.last_activity. 30-day JWT + cookie are a
             safety net; middleware is the real clock. Cookie is
             re-set on active use so browsers match the sliding window.
  Mobile  — 365-day JWT, no idle timeout (stays persistent via Keychain
             / Keystore). Detected via User-Agent ("PedScribe" /
             "Capacitor") or X-Client: mobile header.

2FA backup codes:
  - 10 single-use codes generated when 2FA is first enabled
  - Stored as bcrypt hashes in new users.totp_backup_codes column
  - Consumed atomically on successful login fallback (when TOTP fails)
  - Regenerate endpoint (POST /api/auth/2fa/backup-codes) requires
    current password; invalidates prior codes
  - Count endpoint (GET /api/auth/2fa/backup-codes/count) powers a
    "N codes remaining" indicator on the 2FA settings card
  - Modal shows codes exactly once with Copy + Download .txt actions
  - Codes cleared when 2FA is disabled

New files:
  src/utils/platform.js — isMobileClient() helper

Schema migration (idempotent):
  ALTER TABLE users ADD COLUMN IF NOT EXISTS totp_backup_codes TEXT
2026-04-14 04:24:54 +02:00
..
db Sliding 24h idle timeout (web) + persistent mobile + 2FA backup codes 2026-04-14 04:24:54 +02:00
middleware Sliding 24h idle timeout (web) + persistent mobile + 2FA backup codes 2026-04-14 04:24:54 +02:00
routes Sliding 24h idle timeout (web) + persistent mobile + 2FA backup codes 2026-04-14 04:24:54 +02:00
utils Sliding 24h idle timeout (web) + persistent mobile + 2FA backup codes 2026-04-14 04:24:54 +02:00