Shifty Dokumentation
Sicherheit

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)

  1. Nutzer ruft die Login-Seite auf: /auth/login.
  2. Nutzer gibt E-Mail und Passwort ein.
  3. Backend validiert Credentials und aktive Mitgliedschaften.
  4. Backend gibt neue Tokens zurueck.
  5. Frontend speichert Access/Refresh Cookies.
  6. Falls nur ein aktiver Nutzer und ein aktives Team vorhanden sind, landet der Nutzer direkt im Dashboard.
  7. Falls mehrere Nutzer/Teams verfuegbar sind, erscheint zuerst die Benutzer-/Team-Auswahl.
  8. 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:

  1. Pruefen, ob der Account korrekt angelegt wurde.
  2. Passwort-Reset ausloesen, falls unklar ist, welches Passwort genutzt wird.
  3. 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:

  1. In der Benutzerverwaltung die Membership pruefen.
  2. Feld lockedAt/Lock-Status kontrollieren.
  3. Falls Freigabe gewuenscht: Sperrung aufheben.
  4. 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:

  1. Nutzer erneut anmelden lassen.
  2. 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:

  1. Nutzer vollstaendig abmelden und neu anmelden lassen.
  2. Bei wiederholtem Auftreten Backend-Logs auf auth.invalidRefreshToken pruefen.
  3. 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:

  1. Restriktionsfall pruefen (z. B. PIN-/Unlock-Flow).
  2. Nutzer anweisen, Session ueber Unlock-Prozess freizugeben.
  3. 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?

  1. Pruefen, ob E-Mail korrekt und Account aktiv ist.
  2. Membership auf Sperrung (lockedAt) pruefen.
  3. Bei Bedarf Passwort-Reset ausloesen.
  4. Nutzer erneut anmelden lassen.
  5. 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

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:

  1. Frontend query bootstraps auth via REFRESH_TOKENS step.
  2. Backend hashes refresh token with sha256 and looks it up.
  3. Backend may keep access token if still fresh enough, otherwise rotates refresh token and issues a new access token.
  4. Frontend updates cookies.
  5. 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

  1. Frontend calls logout endpoint.
  2. Backend deletes refresh tokens by sessionId and then removes the session.
  3. 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.

On this page