|
| 1 | +## [4.2.1] - 2026-02-27 |
| 2 | +### Features |
| 3 | +- Passwordless passkey-only accounts |
| 4 | + - New user flows to go fully passwordless when WebAuthn is enabled: |
| 5 | + - GET /user/auth-methods: Returns which auth methods a user has configured and server capabilities. Response fields: |
| 6 | + - hasPassword, hasPasskeys, passkeysCount (now long), webAuthnEnabled, provider |
| 7 | + - POST /user/registration/passwordless: Register a new account without a password (passkey-only). Publishes the same registration events and supports auto-login/redirects if the account is enabled. |
| 8 | + - Note: If your app uses user.security.defaultAction=deny, add /user/registration/passwordless to user.security.unprotectedURIs |
| 9 | + - Guarded to return an error if WebAuthn is not available |
| 10 | + - POST /user/setPassword: Allows a previously passwordless user to set their first password |
| 11 | + - Validates password policy and confirmPassword; rejects if user already has a password |
| 12 | + - DELETE /user/webauthn/password: Removes a user’s password (makes the account passkey-only) |
| 13 | + - Only allowed if the user has at least one registered passkey |
| 14 | + - Publishes an AuditEvent and invalidates all user sessions for security |
| 15 | + - Service and repository enhancements: |
| 16 | + - UserService: hasPassword, removeUserPassword (clears history, invalidates sessions), setInitialPassword (saves history), registerPasswordlessAccount |
| 17 | + - PasswordHistoryRepository: deleteByUser(User) to clear history on password removal |
| 18 | + - WebAuthnCredentialManagementService: used to calculate passkey counts in auth-methods |
| 19 | + - API-level improvements: |
| 20 | + - UserAPI now uses ObjectProvider<WebAuthnCredentialManagementService> to work even when WebAuthn is disabled |
| 21 | + - WebAuthnManagementAPI adds DELETE /user/webauthn/password with audit logging |
| 22 | +- Dev Login for local development |
| 23 | + - A built-in controller to quickly “login as” any enabled user locally, so consuming apps don’t need custom dev-login controllers |
| 24 | + - Endpoints (require both the local profile and user.dev.auto-login-enabled=true): |
| 25 | + - GET /dev/login-as/{email}: Passwordless login-as that returns a 302 redirect to the configured URL (user.dev.login-redirect-url, defaults to /) |
| 26 | + - GET /dev/users: Lists enabled user emails to help pick an account |
| 27 | + - Security hardening: |
| 28 | + - Endpoints are only exposed when the local profile is active and the property flag is true |
| 29 | + - WebSecurityConfig automatically adds /dev/** to unprotected and CSRF-ignored URIs only under those conditions |
| 30 | + - Startup emits a prominent WARN banner when active |
| 31 | + - Configuration properties: |
| 32 | + - user.dev.auto-login-enabled (default false) |
| 33 | + - user.dev.login-redirect-url (default /) |
| 34 | + |
| 35 | +### Fixes |
| 36 | +- Authentication event publishing for passwordless dev login |
| 37 | + - authWithoutPassword() now publishes InteractiveAuthenticationSuccessEvent after storing the security context, ensuring: |
| 38 | + - Session profile listeners run |
| 39 | + - Brute-force counters get reset |
| 40 | + - Tests added to assert the event is published on success and not published on failure paths |
| 41 | +- Passwordless registration and security hardening |
| 42 | + - POST /user/registration/passwordless now returns a clear error when WebAuthn is unavailable |
| 43 | + - Password removal now invalidates all active sessions via SessionInvalidationService, in addition to deleting password history |
| 44 | +- Standard registration correctness |
| 45 | + - UserService.registerNewUserAccount now rejects null passwords and enforces password equality checks; use registerPasswordlessAccount for no-password registrations |
| 46 | +- API robustness and cleanup |
| 47 | + - Removed unreachable code in registerNewUserAccount |
| 48 | + - Clarified docs about adding /user/registration/passwordless to unprotectedURIs when defaultAction is deny |
| 49 | + - Dev login controller refinements: |
| 50 | + - Returns 302 redirect without using HttpServletResponse directly |
| 51 | + - Lists enabled users using a repository method (filters in DB) |
| 52 | + - WebSecurityConfig only exposes /dev/** when both the property is enabled and the local profile is active (matches the controller’s own guards) |
| 53 | + |
| 54 | +### Breaking Changes |
| 55 | +- API DTOs and responses |
| 56 | + - PasswordlessRegistrationDto: removed the role field (clients sending it must remove it) |
| 57 | + - AuthMethodsResponse: |
| 58 | + - passkeysCount type changed from int to long |
| 59 | + - Added webAuthnEnabled flag |
| 60 | +- Service behavior |
| 61 | + - UserService.registerNewUserAccount now requires a non-null password; registering without a password must go through POST /user/registration/passwordless |
| 62 | +- Security configuration nuance |
| 63 | + - /dev/** is now added to unprotected and CSRF-ignored URIs only when user.dev.auto-login-enabled=true and the local profile is active. If you previously relied on the property alone (not recommended), you must also enable the local profile. |
| 64 | + |
| 65 | +### Refactoring |
| 66 | +- Configuration properties registration |
| 67 | + - Migrated @ConfigurationProperties beans to be registered via @EnableConfigurationProperties: |
| 68 | + - New DevLoginConfiguration (profile local + property-gated) |
| 69 | + - New WebAuthnConfiguration (always active; loads defaults from classpath:config/dsspringuserconfig.properties) |
| 70 | + - DevLoginConfigProperties and WebAuthnConfigProperties no longer use @Component/@PropertySource, aligning with Spring Boot conventions |
| 71 | +- WebAuthn setup cleanups |
| 72 | + - Extracted the WebAuthn ObjectPostProcessor into a helper method in WebSecurityConfig for readability and consistency |
| 73 | +- WebSecurityConfig readability |
| 74 | + - Minor renames and extracted lists (e.g., baseDisableCSRFURIs) to simplify CSRF ignore handling |
| 75 | + |
| 76 | +### Documentation |
| 77 | +- Expanded docs for dev login and passwordless flows |
| 78 | + - README: new Dev Login section; added to “Developer-Friendly” features list |
| 79 | + - CONFIG.md: Dev Login settings reference, endpoint table, and usage notes |
| 80 | + - CLAUDE.md: Added dev/ package in structure and user.dev.* properties; documented demo app testing workflow (publishLocal, profiles, Playwright tests) |
| 81 | +- Clarified that apps using defaultAction=deny must add /user/registration/passwordless to user.security.unprotectedURIs |
| 82 | + |
| 83 | +### Testing |
| 84 | +- Extensive new test coverage |
| 85 | + - Dev login: |
| 86 | + - Unit tests (DevLoginControllerTest) cover success, 404, 403, and redirect behavior |
| 87 | + - Integration tests: |
| 88 | + - DevLoginIntegrationTest validates endpoint availability and redirects under local+enabled |
| 89 | + - DevLoginDisabledTest ensures endpoints are not available when disabled and verifies security behavior |
| 90 | + - Passwordless features: |
| 91 | + - WebAuthnManagementAPITest validates new password removal endpoint |
| 92 | + - UserServiceTest: |
| 93 | + - Verifies session invalidation on password removal |
| 94 | + - Verifies password history is saved on setInitialPassword |
| 95 | + - Verifies InteractiveAuthenticationSuccessEvent is published on authWithoutPassword |
| 96 | +- General cleanup of obsolete test code and stronger assertions |
| 97 | + |
| 98 | +### Other Changes |
| 99 | +- Dependency updates |
| 100 | + - Spring Boot: 4.0.2 → 4.0.3 (patch update) |
| 101 | + - com.webauthn4j:webauthn4j-core: 0.30.2.RELEASE → 0.31.0.RELEASE (minor) |
| 102 | +- Version |
| 103 | + - Bumped to 4.2.1-SNAPSHOT |
| 104 | + |
| 105 | +Notes for adopters |
| 106 | +- To enable passwordless account flows, ensure user.webauthn.enabled=true and configure relying party properties. Add /user/registration/passwordless to unprotectedURIs if your default action is deny. |
| 107 | +- If you expose the dev login feature, do so only under the local profile and keep user.dev.auto-login-enabled=false in all non-local configurations. A WARN banner is logged when enabled. |
| 108 | +- If you parse AuthMethodsResponse, update clients for the new long passkeysCount and webAuthnEnabled field, and remove role from PasswordlessRegistrationDto payloads. |
| 109 | + |
1 | 110 | ## [4.2.0] - 2026-02-21 |
2 | 111 | ### Features |
3 | 112 | - WebAuthn/Passkeys (opt-in, disabled by default) |
|
0 commit comments