Frontend: design system, navigation, auth guard, signup screen #33

Merged
marcel merged 25 commits from feat/issue-16-design-system into master 2026-04-02 19:00:19 +02:00

25 Commits

Author SHA1 Message Date
09333ccc0a test(auth): verify security context is stored in session after login and signup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 18:55:25 +02:00
93ce1eaeac refactor(auth): add comments, clearContext on logout, explain session auth
- Add comment to SecurityConfig explaining why CSRF is disabled
- Add SecurityContextHolder.clearContext() to logout for clean thread state
- Add Javadoc on authenticateInSession() explaining manual session setup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 18:52:16 +02:00
61249af086 feat(auth): add secure flag to JSESSIONID cookie and test JSESSIONID cookie setting
- Add secure: true to cookies.set() in login and signup actions
- Add tests verifying JSESSIONID is forwarded to browser on successful
  login and signup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 18:50:34 +02:00
16f0feb8d5 fix(auth): fix mock responses in tests and block open redirect in login
- Add response object to mockSuccess() in login and signup tests so
  response.headers.get() no longer throws
- Validate ?redirect= param: must start with / and not // to prevent
  redirecting users to external domains

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 18:48:48 +02:00
0aa65214fc fix(auth): resolve broken signup/login flow end-to-end
Three root causes fixed:

1. CSRF blocked all backend POSTs — Spring Security's CSRF filter ran
   before permitAll() authorization, returning 401 for signup and login.
   Disabled CSRF since SvelteKit is the only client (never the browser
   directly) and handles its own CSRF via Origin header checks.

2. Login/signup didn't establish Spring Security authentication — they
   stored email in the HTTP session manually but never set the
   SecurityContext, so Principal in /v1/auth/me was always null and
   hooks.server.ts redirected every authenticated request to /login.
   Fixed with authenticateInSession() helper that sets and persists
   the SecurityContext under SPRING_SECURITY_CONTEXT_KEY. Login also
   now invalidates the old session before creating a new one to prevent
   session fixation.

3. redirect() missing throw in hooks.server.ts, signup action, and
   login action — SvelteKit never saw the redirect, so pages silently
   reloaded with no navigation. Also forward JSESSIONID from backend
   response to browser explicitly, since SvelteKit does not
   auto-forward Set-Cookie for cross-origin server-side fetches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 17:31:29 +02:00
ab3363eeec refactor(auth): use shared BrandPanel on login page
Login page now uses the same BrandPanel component as signup
instead of an inline brand panel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 16:45:22 +02:00
999e54de86 feat(auth): build login page with LoginForm, brand panel, and title
Replaces placeholder with full login page: brand panel left,
LoginForm right, svelte:head title, signup link, no-nav-chrome.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 16:21:31 +02:00
73acc0c638 feat(auth): add login server action with validation and redirect
POSTs to /v1/auth/login, validates email/password server-side,
redirects to ?redirect param or /planner on success.
Returns generic error on bad credentials to prevent enumeration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 16:20:02 +02:00
c27c97ff7d feat(auth): add LoginForm component with validation and password toggle
Email/password fields, client-side validation, password show/hide,
server error display via form prop, signup link.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 16:18:49 +02:00
b3607ca47a test(auth): add password length boundary tests (7 fails, 8 passes)
Parameterized test verifying the exact boundary of the 8-character
minimum password requirement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:07:42 +02:00
7de18740f2 test(auth): add multi-error test for empty form submission
Verifies all three validation errors (name, email, password) appear
simultaneously when submitting a completely empty form.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:07:07 +02:00
6d0f00c8fb feat(auth): add use:enhance and server error display to signup form
SignupForm now uses use:enhance for progressive enhancement.
Accepts form prop for server-side error display. Shows general
form errors in a banner and field-specific errors inline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:06:21 +02:00
bd9e1334e0 feat(auth): add server-side validation to signup form action
Validates displayName, email, password server-side before calling
the backend API. Handles null from formData.get() safely.
Returns structured field errors via fail(400, { errors }).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:02:33 +02:00
82840bb420 fix(auth): center signup form on wide desktop screens
Form container now horizontally centered on md+ viewports,
left-aligned on mobile for full-width usage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:01:03 +02:00
845e669cde feat(auth): add page title to signup screen
Sets <title>Konto erstellen — Mealprep</title> via svelte:head
for browser tab and accessibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:00:02 +02:00
afcea6590d feat(auth): add autocomplete attributes to signup form inputs
name, email, new-password for better browser/password-manager support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:58:59 +02:00
75a13d9df1 fix(auth): style login link green/font-medium per spec
Spec shows green text with font-weight 500, no underline by default.
Was dark text with underline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:57:47 +02:00
b71c98662b fix(auth): use --green-dark on submit button for WCAG AA contrast
--green (#3D8C4A) gives 4.16:1 against white — fails AA.
--green-dark (#2E6E39) passes comfortably.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:56:49 +02:00
bfa8f20fe3 test(auth): add no-nav-chrome regression test for signup page
Verifies signup page renders form and brand panel but no
navigation elements (tabs, sidebar, links to app routes).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:48:23 +02:00
596652d6e4 feat(auth): add signup page with form action
Composes BrandPanel + SignupForm in responsive split layout.
Server action POSTs to /v1/auth/signup and redirects to
/household/setup on success.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:47:36 +02:00
d3a8518298 feat(auth): add SignupForm component with validation and password toggle
Form with name/email/password fields, client-side validation,
inline error messages, and password show/hide toggle.
Uses native form action for progressive enhancement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:45:54 +02:00
d5d85d1156 rename backend service 2026-04-02 14:45:11 +02:00
e8fe69a543 feat(auth): add BrandPanel component for signup screen
Renders brand identity with logo, app name, tagline, and feature icons
on green-dark background. Responsive: banner on mobile, 440px column
on desktop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:41:10 +02:00
56fc7e6052 feat(auth): add /signup to public routes
Allow unauthenticated access to the signup page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:39:17 +02:00
66cf538454 refactor(auth): make (public) layout bare, move brand panel into login page
The signup page needs its own brand panel, so the shared layout
becomes a simple slot. Login page now owns its brand panel markup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 14:38:30 +02:00