← Auth / Security

Routes and redirects

auth / security · workzone

Routes and redirects: where the base URL leads and how roles are routed. The login mechanics (tokens, hashing, password change) live in authentication — this page is only the map.

Entry gate
GET / single entry point · base URL
1Database empty?
no · users exist
2Session present?
yes · signed in
3Account role?
Single SPA, routed by role: both shells — /admin and /chat — are one React app. The admin zone is a separate lazy chunk. Shared layer: auth / tokens, design system, i18n. The gate is a client-side redirect in the router.
Guarded transitions
GUARD Deep-link as guest
protected route /login?returnTo=<route> return to origin
A request for a protected route without a session → redirect to the login form, preserving the target → after login, return to the original route. ?returnTo takes priority, if the role is allowed there. ?returnTo is accepted only as a local path (starts with a single /, but not // or /\, no scheme or host) — otherwise it is ignored and the redirect goes to the role's home. Open-redirect protection: an external ?returnTo would send the user to a phishing clone after login.
GUARD Temporary password
must_change_password /change-password on by role
Right after login: if the account has must_change_password set (a temporary password was issued) → forced redirect to /change-password, with sign-out blocked until a permanent password is set. The redirect is client-side; the real boundary is held by the server — a direct API call bypassing the screen is rejected — the mechanics are in the data model. Once the flag is cleared → routing by role (Q3 above). The feature — Forced password change.
GUARD Guard /admin/*
Member on /admin/* 403 Forbidden /chat
/admin/*Owner / Admin only. A Member on an admin route → redirect to their own /chat: when the role's home is known, we avoid a dead end. The shared 403 “Access denied” screen is for other forbidden deep-links where there is no obvious redirect.
rejection terminal 403 Forbidden signed in, but without rights → redirect to /chat