Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

09 — User Behaviour (Auth Module)

Expected behaviour (derived from server semantics + shared interaction rules), the common mistakes users make with these screens, and the UX countermeasures. Purpose: hand the UI designer a playbook of what the user does so the flow never surprises.


1. Expected behaviour (server-contract-driven)

  • Login failure never distinguishes unknown email vs wrong password → UI must keep the message generic to avoid teaching users "accounts exist" (auth.service.ts 125/131/141).
  • Refresh is seamless: within the 15 min access TTL the app refreshes quietly; a 401 on any request triggers single-flight POST /auth/refresh; a second failure → SessionExpired.
  • After password reset all sessions die → user is logged out everywhere; from the client the only state is "session invalid"; UI: reason banner "Password was changed on another device" (so it reads as intentional).
  • After logout, client clears local tokens, so the refresh never succeeds → login screen.

2. Common mistakes & countermeasures

MistakeRelatedUX countermeasure
Typing wrong/` casecaps-lock for passwordLoginshow error; ensure a visible hint "Caps Lock is on" would help (proposed); reveal toggle; keep team away from password manager-fighting
Forgetting which tenant/school idRegisterplaceholder + example; hint autofilled from invite
Losing / reusing the verify-email token (email link fired twice / link lost)verifyserver returns "already verified" → benign; resend link (rate-limited)
Resend obnoxious spamresend-verificationrate 5/120s, cap UX "Wait 1 min"
Tapping "log out all" then leaving the devicelogout-allconfirm dialog; after action show "logged out everywhere" result
Losing 2FA device & can't get in2farecovery codes (planned) + clear warning at setup: "save these recovery codes"
Revoking a device you're currently on → locked out of that sessionsessionsidentify current row (badge "This device"); warn on revoke of current

3. Power & new users

  • Power user: global shortcuts Ctrl+L focus login field; fast tabbing; API key creation with pasted name; batch revoke pattern; saves assert favs.
  • New user (register): walk first-run task list ("Verify email", "Set up 2FA", "Invite staff") after token auto-login.

4. Mobile & a11y users

  • One-thumb phone: resty single required CTA, min 48 target.
  • TalkBack/VoiceOver: login flow fully walkable; errors announced on focus; TOTP sheet single-field semantics; copy buttons labeled.
  • Dynamic type 200%: pre-auth forms reflow (no fixed widths).
  • Reduced motion: no shake/animation; error = color+icon+text.

5. Password managers

  • Correct autofillHints everywhere; serverside: password min 8 BUT login min 6 → managers may propose 8-char passwords that pass register but then get 6-char validation... Actually login is a verifier; managers generate ≥12; UI should accept managers' output.
  • In-app Autofill: on web, <input autocomplete>; Flutter TextInputAction.

6. Interrupted sessions & retries

  • Suspend/resume: app killed mid-session: secure-storage tokens intact → quiet refresh → home.
  • Mid-login interruption (app kill): form state lost; return → fresh.
  • Retry after rate limit: countdown; auto-resubmit only when the user re-taps.
  • Server 5xx after login: show generic error + requestId, keep form, suggest retry; tokens not committed.

7. Abandonment

  • Where people quit and what to do:
    • register mid-way → email capture for invite context; UX: one-tap "resume".
    • reset token not clicked within 1 h → expired banner, one tap re-send.
    • 2fa enable after obtaining secret → incomplete → show "Finish 2FA setup" reminder row on Security hub (client memoized).

8. Frustration points → UX treatments (summary table)

FrustrationTreatment
"Account locked. Try again later."Show remaining seconds from server lockedUntil (client can't compute; show "after MM:SS" only if known) — else generic + retry timer
429 on logincountdown chip + "no auto-retry"
Device access after revokeconfirm; state icon change
Unknown key prefixno "secret" leaks in UI; only prefix shown

9. Cross-device & conflict

  • Concurrent login on two devices → two sessions (user_sessions per device). Conflicting change (e.g., reset on one) → other device receives "session expired" on next action.
  • Revocation of the wallet's current session → immediate force logout of the app (sessionExpired).

10. Adoption path (holistic)

P0 release: register→login→verify→password reset→logout. P1: sessions/devices, 2FA, api-keys. P2 (planned): recovery codes, impersonation, unlock, revoke-others, 2FA challenge step (IMPLEMENTATION_PLAN.md).