diff --git a/docs/architecture/c4-diagrams.md b/docs/architecture/c4-diagrams.md index ea7483db..9b82347b 100644 --- a/docs/architecture/c4-diagrams.md +++ b/docs/architecture/c4-diagrams.md @@ -327,11 +327,11 @@ C4Component ## Level 3 — Components: Web Frontend -The internal structure of the SvelteKit frontend, split into two focused views. +The internal structure of the SvelteKit frontend, split into four focused views. ### 3a — Middleware, Auth & Layout -Per-request middleware: session validation, i18n, and auth cookie handling. +Per-request middleware: session validation, i18n, auth cookie handling, and auth pages. ```mermaid C4Component @@ -341,11 +341,14 @@ C4Component Container(backend, "API Backend", "Spring Boot") System_Boundary(frontend, "Web Frontend (SvelteKit / SSR)") { - Component(hooks, "hooks.server.ts", "SvelteKit Server Hook", "Two responsibilities: (1) userGroup handle — reads auth_token cookie, fetches /api/users/me, stores user in event.locals. (2) handleFetch — intercepts all outgoing fetch() calls, injects Authorization header from cookie. Redirects to /login if token absent.") + Component(hooks, "hooks.server.ts", "SvelteKit Server Hook", "Four handle layers: (1) handleAuth — redirects unauthenticated users to /login; (2) userGroup — reads auth_token cookie, fetches /api/users/me, stores user in event.locals; (3) handleFetch — injects Authorization header on all outgoing /api/ calls; (4) handleLocaleDetection — sets language cookie from Accept-Language header.") Component(i18n, "hooks.ts (Paraglide)", "SvelteKit Client Hook", "Client-side i18n middleware. Detects language from URL and sets the active locale for Paraglide.js translation functions.") Component(layout, "+layout.server.ts", "SvelteKit Layout Loader", "Passes event.locals.user down to all child pages so every route has access to the authenticated user.") Component(loginPage, "/login", "SvelteKit Route", "Form action: encodes username:password as Base64 Basic Auth token, POSTs to /api/users/me to validate, sets auth_token httpOnly cookie (SameSite=strict, maxAge=86400), redirects to /.") Component(logoutPage, "/logout", "SvelteKit Route (server-only)", "Clears the auth_token cookie and redirects to /login.") + Component(registerPage, "/register", "SvelteKit Route", "Loader validates invite code via GET /api/auth/invite/{code}. Form action: POST /api/auth/register to create the user account.") + Component(forgotPw, "/forgot-password", "SvelteKit Route", "Form action: POST /api/auth/forgot-password. Always responds with success to prevent email enumeration.") + Component(resetPw, "/reset-password", "SvelteKit Route", "Form action: POST /api/auth/reset-password with the token from the query string.") } Rel(user, hooks, "Every browser request", "HTTPS") @@ -353,6 +356,9 @@ C4Component Rel(hooks, loginPage, "Redirect if no token", "") Rel(hooks, layout, "Stores authenticated user in event.locals", "") Rel(loginPage, backend, "POST /api/users/me (auth check)", "HTTP / Basic Auth") + Rel(registerPage, backend, "GET /api/auth/invite/{code}, POST /api/auth/register", "HTTP / JSON") + Rel(forgotPw, backend, "POST /api/auth/forgot-password", "HTTP / JSON") + Rel(resetPw, backend, "POST /api/auth/reset-password", "HTTP / JSON") ``` ### 3b — Pages & Shared Components