Platform & Access · Staff login
Email + password authentication for back-office staff. On success a bearer token is stored in the ember-simple-auth session and the current user, their centers and their dashboards are loaded.
| Area | Platform & Access |
| Routes | user.login |
| Centre modules | always available |
| Staff levels | any staff level |
| Models | staff-member |
| UI label | menu.navbar.logout / form-login |
| Coverage | 3 use cases · 1 happy · 4 failure |
Known issues (1)
How it works
Auth state lives in the auth service: the token is aliased from session.data.authenticated.token, while the active centre is persisted as a cid cookie (max-age 86400) rather than in the session. auth.load() hydrates user + centers + dashboards and is re-run in routes/index.js#beforeModel because right after login those relationships are not yet in the store. The user is also pushed to Sentry (sentrySetUser).
Use cases
Why someone opens this (3)
- A centre manager signs in at the start of a shift to work on sales, proposals or customers.
- An admin with several centres signs in and then picks which centre to operate on.
- An external/API-level account authenticates to obtain a token.
Path map
flowchart LR F(["Staff login"]):::feat F --> H1["Successful sign-in"]:::ok F -.-> X1["Wrong credentials"]:::bad F -.-> X2["Centre cookie unavailable"]:::bad F -.-> X3["Role not recognised"]:::bad F -.-> X4["Session invalidated mid-use"]:::bad classDef feat fill:#4a5c8a,stroke:#4a5c8a,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
Successful sign-in
- Staff member opens /user/login and enters email + password.
- Credentials are posted to the API authenticator; a bearer token comes back.
auth.load()resolves the user, the list of accessible centres and the dashboards.- The
cidcookie is set to the default centre and the app transitions to the desktop (index).- The side menu is rebuilt from the user’s role and the centre’s enabled modules.
Failure paths
Wrong credentials
Cause — API rejects the email/password pair.
What happens — The login form stays on screen and surfaces the authenticator’s error; no token is stored.
Centre cookie unavailable
Cause — Cookies blocked or
cidmissing —auth.getCookiethrowsNoCookieError.What happens —
centerId/centerGidgetters swallow the error and return an empty string, so centre-scoped queries silently run without a centre filter. Worth treating as a known weak spot: the UI does not warn the user.
Role not recognised
Cause —
auth.user.roleis not one of the values inenums/staff-levels.What happens —
nf-navbar#menureturns[], so the user lands on an app with an empty navigation menu instead of an explicit error.
Session invalidated mid-use
Cause — Token expired or rejected by the API.
What happens —
routes/application.jscatches the failure and callssession.invalidate(), returning the user to login.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ Successful sign-in
- ⛔ Wrong credentials
- ⛔ Centre cookie unavailable
- ⛔ Role not recognised
- ⛔ Session invalidated mid-use
Implementation
Translation keys (3)
Key English menu.navbar.logoutLogout pass-requiredUse 10 or more letters, with at least 1 number, 1 capital letter and 1 lower letter match-passThe password fields do not match
Related
- Same area — Password reset request · Password update from reset link · Change own password · Idle auto-logout · Centre switching & multi-centre scoping · Server-incident banner · Desktop (home dashboard) · Runtime environment & white-label boot · Back-office interface language · In-app help & support chat (Froged)
- Shares data with — Intranet communications (threads, confirmations, authorisations) · Staff member list, deletion & restore · Staff member editor (levels, scope, API token) · Role & module permission layer · Customer action log (dormant)
Generated from doc/feature-inventory.json · id platform-login · commit 276788ca6