waitForURL('/') resolves as soon as the URL changes but before SvelteKit
finishes hydrating — the avatar button's onclick is not yet registered,
so the click has no effect and the dropdown never opens.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers dev (Mailpit), production SMTP, all env vars with defaults,
common provider settings, and how to disable mail entirely.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a Mailpit container that catches all outgoing emails locally so
password reset links can be tested without a real SMTP server.
- Backend defaults to MAIL_HOST=mailpit / MAIL_PORT=1025 in compose
- SMTP auth and STARTTLS disabled for Mailpit (no credentials needed)
- Web inbox available at http://localhost:8025
- Production SMTP still works by overriding MAIL_HOST, MAIL_PORT,
MAIL_USERNAME, MAIL_SMTP_AUTH, and MAIL_STARTTLS_ENABLE in .env
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the e2e profile is active, initE2EData (which creates a reader user)
can run before initAdminUser. The old count() == 0 guard then skips admin
creation entirely, causing every login test to fail with 401.
Switch to findByUsername(adminUsername).isEmpty() so the admin is created
regardless of which CommandLineRunner runs first.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /forgot-password: email form → sends POST /api/auth/forgot-password → success banner
- /reset-password: password form reads token from URL → sends POST /api/auth/reset-password
- Login page: add "Passwort vergessen?" link
- hooks.server.ts: add /forgot-password and /reset-password to PUBLIC_PATHS; skip auth
injection for public auth API endpoints
- errors.ts: add INVALID_RESET_TOKEN error code
- i18n: add all new message keys in de/en/es
- playwright.config.ts: use E2E_BASE_URL for webServer check URL (allows reusing docker
dev server at port 5173 locally)
- ci.yml: pass E2E_BACKEND_URL=http://localhost:8080 to E2E test step
- e2e/password-reset.spec.ts: 5 tests (4 pass locally, full flow requires e2e profile in CI)
- Regenerated OpenAPI types including new /api/auth/* endpoints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add PasswordResetToken entity, repository (Flyway V8 migration)
- PasswordResetService: token generation, validation, nightly cleanup
- AuthController: POST /api/auth/forgot-password and /api/auth/reset-password (both permitAll)
- AuthE2EController (@Profile("e2e")): GET /api/auth/reset-token-for-test for CI testing
- spring-boot-starter-mail dependency; JavaMailSender optional (@Autowired required=false)
- mail health indicator disabled; mail config via MAIL_HOST/PORT/USERNAME/PASSWORD env vars
- 5 unit tests written TDD-style (all pass)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>