Authentication Flows
Authentication Flows
Type: Explanation
Audience: Admins and Developers
Related: docs/knowledge-base/page-guides/system/login.md, docs/knowledge-base/developer/architecture/authentication.md, docs/knowledge-base/developer/architecture/backend/jwt-authentication.md
Für Admins
Ziel dieses Dokuments
Dieses Dokument beschreibt den Login-Ablauf in Shifty, typische Fehlerbilder und konkrete Admin-Handlungen.
Was ist eine Session?
Eine Session ist der angemeldete Zustand eines Accounts in Shifty. Technisch wird sie durch zwei Token getragen:
- Access Token: Kurzlebig, für normale API-Zugriffe.
- Refresh Token: Wird genutzt, um Access Tokens zu erneuern.
In Shifty werden beide im Browser als Cookies gespeichert:
- shifty-access-token
- shifty-refresh-token
Referenz:
- Frontend Cookie-Namen: src/global-config.ts
- Token-Erzeugung und Verifikation: elbtalteamadmin-services/src/_utils/auth/jwt.ts
Happy Path: Login -> Team-Auswahl -> Dashboard
Happy Path (Mitarbeiter)
- Nutzer ruft die Login-Seite auf: /auth/login.
- Nutzer gibt E-Mail und Passwort ein.
- Backend validiert Credentials und aktive Mitgliedschaften.
- Backend gibt neue Tokens zurueck.
- Frontend speichert Access/Refresh Cookies.
- Falls nur ein aktiver Nutzer und ein aktives Team vorhanden sind, landet der Nutzer direkt im Dashboard.
- Falls mehrere Nutzer/Teams verfuegbar sind, erscheint zuerst die Benutzer-/Team-Auswahl.
- Danach wird das aktive Team gesetzt und die normale Arbeitsoberflaeche geladen.
Code-Referenzen:
- Login und Refresh im Frontend: src/auth/context/auth-provider.tsx
- Login-Service im Backend: elbtalteamadmin-services/src/auth/login/func.ts
- Route-Schutz/Weiterleitung: src/proxy.ts
Fehler-Szenarien und Admin-Handlungsanweisungen
1) Failed credentials
Symptom:
- Login wird abgelehnt (Invalid credentials).
Was intern passiert:
- Backend antwortet mit Berechtigungsfehler, wenn E-Mail/Passwort nicht passt oder kein aktiver Nutzer/Membership vorhanden ist.
Admin-Aktion:
- Pruefen, ob der Account korrekt angelegt wurde.
- Passwort-Reset ausloesen, falls unklar ist, welches Passwort genutzt wird.
- Pruefen, ob der Nutzer aktive Team-Mitgliedschaften hat.
Referenz:
- Credential-Checks: elbtalteamadmin-services/src/auth/login/func.ts
2) Locked account / locked membership
Symptom:
- Nutzer kann sich trotz korrekter Daten nicht anmelden.
Was intern passiert:
- Gesperrte Mitgliedschaften werden aus dem Login-Kontext entfernt.
- Wird eine Membership wirksam gesperrt, werden Refresh-Tokens invalidiert.
Admin-Aktion:
- In der Benutzerverwaltung die Membership pruefen.
- Feld lockedAt/Lock-Status kontrollieren.
- Falls Freigabe gewuenscht: Sperrung aufheben.
- Nutzer erneut einloggen lassen.
Referenz:
- Membership-Update und Token-Invalidierung: elbtalteamadmin-services/src/users/memberships/update/func.ts
3) Session expiry
Symptom:
- Nutzer wird auf Login umgeleitet, obwohl kurz zuvor alles funktioniert hat.
Was intern passiert:
- Access Token ist abgelaufen oder ungueltig.
- Frontend versucht zuerst einen Token-Refresh.
- Bei 400/401/403/404 im Refresh wird aus Sicherheitsgruenden abgemeldet.
Admin-Aktion:
- Nutzer erneut anmelden lassen.
- Falls haeufig: Uhrzeit/Systemzeit und Netzwerk- oder Cookie-Policies im Browser pruefen.
Referenz:
- Refresh und Redirect-Logik: src/auth/context/auth-provider.tsx
4) Token refresh fail
Symptom:
- Nutzer wird nach kurzer Zeit immer wieder abgemeldet.
Was intern passiert:
- Refresh Token fehlt, ist ungueltig oder Session ist nicht mehr vorhanden.
- Backend lehnt Refresh ab.
Admin-Aktion:
- Nutzer vollstaendig abmelden und neu anmelden lassen.
- Bei wiederholtem Auftreten Backend-Logs auf auth.invalidRefreshToken pruefen.
- Pruefen, ob Session-Restriktionen aktiv sind oder Sessions geloescht wurden.
Referenz:
- Refresh-Token-Pruefung: elbtalteamadmin-services/src/auth/login/func.ts
- Logout/Sessions loeschen: elbtalteamadmin-services/src/auth/logout/func.ts
5) Locked session (session_locked)
Symptom:
- Nutzer wird auf /auth/unlock-session geleitet.
Was intern passiert:
- Session wurde auf einen Pfad eingeschraenkt (pathRestriction).
- Frontend erkennt restriction und erzwingt Unlock-Flow.
Admin-Aktion:
- Restriktionsfall pruefen (z. B. PIN-/Unlock-Flow).
- Nutzer anweisen, Session ueber Unlock-Prozess freizugeben.
- Falls erforderlich, Session zuruecksetzen.
Referenz:
- Session Restriction API: elbtalteamadmin-services/src/auth/restrict-session/service.ts
- Unlock-Redirect im Frontend: src/auth/context/auth-provider.tsx
DSGVO- und Session-Management-Hinweise
- Tokens enthalten sicherheitsrelevante Sitzungsdaten und duerfen nicht in Support-Chats geteilt werden.
- Nur so lange angemeldet bleiben, wie fuer den Arbeitsprozess erforderlich.
- Bei Verdacht auf Missbrauch: Session sofort beenden (Logout) und Passwort neu setzen.
- Personenbezogene Daten in Fehlerreports minimieren.
Fallbeispiel
Mitarbeiter kann sich nicht anmelden - ich bin Admin, was mache ich?
- Pruefen, ob E-Mail korrekt und Account aktiv ist.
- Membership auf Sperrung (lockedAt) pruefen.
- Bei Bedarf Passwort-Reset ausloesen.
- Nutzer erneut anmelden lassen.
- Bei erneutem Fehler: Auth-Fehlerklasse (failed login, token refresh, session locked) bestimmen und zielgerichtet handeln.
Screenshot-Hinweis
Zum aktuellen Zeitpunkt sind fuer diesen Guide noch keine dedizierten Login- und Error-State-Screenshots im Security-Bereich versioniert. Empfohlen:
- Login UI
- Team-Auswahl Dialog
- Hinweis bei session_expired
- Hinweis bei session_locked
Ablagevorschlag:
- docs/knowledge-base/screenshots/page-guides/system/login/
For Developers
Architecture Summary
Shifty uses JWT sessions with jose and cookie-based token transport.
Core pieces:
- JWT signing/verification: elbtalteamadmin-services/src/_utils/auth/jwt.ts
- Login, switch user/team, refresh: elbtalteamadmin-services/src/auth/login/func.ts
- Logout/session cleanup: elbtalteamadmin-services/src/auth/logout/func.ts
- Frontend auth orchestration: src/auth/context/auth-provider.tsx
- Route protection and role gates: src/proxy.ts
JWT implementation (jose)
Backend token implementation uses jose SignJWT and jwtVerify.
Observed behavior from code:
- Algorithm: HS256
- Issuer: elbtalteam-services
- Audience: authenticated
- Access token expiration: 1h
Reference:
- elbtalteamadmin-services/src/_utils/auth/jwt.ts
Cookie-based token storage
Frontend stores both tokens via cookies-next under:
- shifty-access-token
- shifty-refresh-token
Cookie enum:
- src/global-config.ts
Write/delete operations:
- src/auth/context/auth-provider.tsx
Refresh token flow
Flow in practice:
- Frontend query bootstraps auth via REFRESH_TOKENS step.
- Backend hashes refresh token with sha256 and looks it up.
- Backend may keep access token if still fresh enough, otherwise rotates refresh token and issues a new access token.
- Frontend updates cookies.
- On client errors 400/401/403/404 during refresh, frontend clears cookies and redirects to login.
References:
- src/auth/context/auth-provider.tsx
- elbtalteamadmin-services/src/auth/login/func.ts
Logout flow
- Frontend calls logout endpoint.
- Backend deletes refresh tokens by sessionId and then removes the session.
- Frontend clears both cookies locally.
References:
- elbtalteamadmin-services/src/auth/logout/func.ts
- src/auth/context/auth-provider.tsx
Error handling and status mapping
Typical status semantics seen in this flow:
- 400: malformed auth request (for example missing refresh token)
- 401/403: invalid credentials or permission issues
- 404: resource/session context not found in some edge conditions
Frontend behavior:
- 400/401/403/404 on refresh => forced login redirect with reason=session_expired
Reference:
- src/auth/context/auth-provider.tsx
Role-based routing and route guards
The Next.js proxy middleware enforces route-level checks:
- unauthenticated requests to protected routes -> redirect to /auth/login
- invalid token -> delete cookies + redirect login
- role mismatch -> rewrite to /not-found
- public auth routes while logged in -> redirect to home (except specific exceptions)
Reference:
- src/proxy.ts
- src/routes/paths.ts
Threat vectors and mitigations
Token theft:
- Mitigation: cookie transport + backend signature verification + token expiry
Session abuse:
- Mitigation: explicit session restriction path via /auth/restrict-session and unlock workflow
Privilege escalation:
- Mitigation: role/teamRole checks in middleware
Refresh replay risk:
- Mitigation: refresh tokens are stored hashed and rotated on refresh
CORS and transport notes
Server currently configures CORS centrally for endpoints in server.ts. Keep frontend/backend origins aligned in deployments.
Reference:
- elbtalteamadmin-services/src/server.ts
Implementation checklist
- Use existing auth endpoints; do not invent parallel login routes.
- Keep token claims consistent with AccessTokenPayloadSchema.
- Keep route protection in src/proxy.ts as the first guard layer.
- Do not expose raw tokens in logs or error messages.
Reference:
- elbtalteamadmin-services/src/_schemas/auth.ts
Verification Quicklist
- Happy path described with team selection fallback: yes.
- failed login, session expiry, token refresh, locked account, locked session covered: yes.
- For Developers and Für Admins split: yes.
- Code references point to existing files only: yes.