@startuml
title Authentication Flow (behind Caddy reverse proxy)

actor User
participant Browser
participant "Caddy (TLS termination)" as Caddy
participant "Frontend (SvelteKit)" as Frontend
participant "Backend (Spring Boot)" as Backend
participant PostgreSQL as DB

User -> Browser: Enter email + password
Browser -> Caddy: HTTPS POST /login (form action)
note right of Caddy
  Caddy terminates TLS and forwards
  to Frontend over HTTP with:
    X-Forwarded-Proto: https
    X-Forwarded-For: <client IP>
    X-Forwarded-Host: archiv.raddatz.cloud
end note
Caddy -> Frontend: HTTP POST /login\n+ X-Forwarded-Proto: https
Frontend -> Frontend: Base64 encode "email:password"
Frontend -> Backend: GET /api/users/me\nAuthorization: Basic <token>\n+ X-Forwarded-Proto: https
note right of Backend
  server.forward-headers-strategy: native
  Jetty's ForwardedRequestCustomizer
  reads X-Forwarded-Proto so
  request.getScheme() returns "https".
end note
Backend -> Backend: Spring Security parses Basic Auth
Backend -> DB: SELECT user WHERE email=?
DB --> Backend: AppUser + groups + permissions
Backend -> Backend: BCrypt.matches(password, hash)
Backend --> Frontend: 200 OK — UserDTO
Frontend -> Caddy: Set-Cookie: auth_token=<base64>\n(httpOnly, **Secure**, SameSite=strict, maxAge=86400)
note right of Frontend
  Secure flag is set because the
  request scheme observed by the
  app is https (forwarded by Caddy).
end note
Caddy -> Browser: HTTPS 200 + Set-Cookie
Browser -> Caddy: HTTPS GET / (next request)
Caddy -> Frontend: HTTP GET / + X-Forwarded-Proto: https
Frontend -> Frontend: hooks.server.ts reads auth_token cookie
Frontend -> Backend: GET /api/users/me\nAuthorization: Basic <token>
Backend --> Frontend: 200 OK — user in event.locals
Frontend --> Caddy: rendered page
Caddy --> Browser: HTTPS 200

@enduml
