Remove duplicated private authenticateInSession from AuthController and
HouseholdController. Add a single public implementation on AuthService
with session fixation protection built in. HouseholdController now
injects AuthService and passes role "user" for invite-accepted accounts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SecurityConfig: /** covers /v1/invites/{code}/accept (two path segments);
/* only matched one segment so the accept endpoint was returning 401
- HouseholdIdentityPanel + page: use --green-dark bg (matching BrandPanel
on login) instead of --green-tint; text updated to white/--green-light
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
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>
Each domain had a single-implementation interface (e.g. AdminService
interface + AdminServiceImpl). Merged implementation into the service
class and deleted the redundant interfaces per KISS principle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>