feat: migrate from username to email-only authentication #272

Merged
marcel merged 6 commits from feat/issue-270-email-only-auth into main 2026-04-18 23:36:56 +02:00

6 Commits

Author SHA1 Message Date
Marcel
8447f06f36 fix(auth): add @Email validation and @Valid to enforce email format on user creation
Some checks failed
CI / Unit & Component Tests (push) Failing after 3m13s
CI / OCR Service Tests (push) Successful in 50s
CI / Backend Unit Tests (push) Failing after 2m59s
CI / Unit & Component Tests (pull_request) Failing after 2m46s
CI / OCR Service Tests (pull_request) Successful in 32s
CI / Backend Unit Tests (pull_request) Failing after 2m50s
- Add @Email annotation to CreateUserRequest.email and AppUser.email
- Add @Valid to UserController.createUser to activate bean validation
- Add MigrationIntegrationTest cases for V44 NOT NULL and UNIQUE constraints
- Fix stale test comments (findByUsername → findByEmail)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 21:52:11 +02:00
Marcel
39163f06bf feat(auth): migrate frontend from username to email-only authentication
Some checks failed
CI / Backend Unit Tests (push) Failing after 3m5s
CI / Unit & Component Tests (pull_request) Failing after 2m26s
CI / OCR Service Tests (pull_request) Successful in 36s
CI / Backend Unit Tests (pull_request) Failing after 2m55s
CI / Unit & Component Tests (push) Failing after 2m49s
CI / OCR Service Tests (push) Successful in 48s
- Login page: email input replaces username field (type=email, name=email)
- Login server action: reads email, uses i18n error for missing credentials
- AccountSection: email input (type=email) replaces username text field
- New user server action: sends email as required field, drops username
- UsersListPanel: displays and searches by email instead of username
- Admin edit user page: heading and delete confirm use email
- Profile page: fullName fallback uses email, drops @username display
- app.d.ts: email required on User, username removed
- Generated API types: AppUser.email required, username removed; CreateUserRequest.email required, username removed
- i18n: login_label_email, login_error_missing_credentials, admin_col_login updated (de/en/es)
- errors.ts: MISSING_CREDENTIALS → login_error_missing_credentials

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 21:34:46 +02:00
Marcel
e8039bca5a feat(auth): remove username field, migrate identity to email
- AppUser entity: replace username with email (NOT NULL, UNIQUE,
  colon-pattern validated)
- AppUserRepository: remove findByUsername, rename search JPQL to
  searchByEmailOrName (searches email + firstName + lastName)
- CreateUserRequest: remove username, require email with colon guard
- UserService: rename findByUsername→findByEmail, createUserOrUpdate
  upserts by email, blank-email guard throws instead of setting null
- UserController + all other controllers: findByEmail(auth.getName())
- DataInitializer: email-based config and lookup, E2E users have email
- V44 migration: pre-check + email NOT NULL + drop username column
- All tests updated: .username() builders removed, mocks updated,
  NotificationRepositoryTest fixtures include email fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:49:15 +02:00
Marcel
10e980328d feat(users): reject blank email in updateProfile and adminUpdateUser
Previously a blank email string would silently set email to null,
which would cause a DB constraint violation after V44 migration.
Now throws DomainException.badRequest instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:35:03 +02:00
Marcel
c9f805688e feat(auth): configure form login to use 'email' as username parameter
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:32:52 +02:00
Marcel
cf9a8ea393 feat(auth): switch CustomUserDetailsService to email-based lookup
loadUserByUsername now calls findByEmail and returns email as the
Spring Security principal name. Tests updated to assert email identity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 20:31:32 +02:00