5.3.1 — Resend Verification Email Fix
This release fixes POST /user/resendRegistrationToken so consuming apps can actually resend registration verification emails. It also corrects README examples and tidies repo layout and tooling without changing any runtime APIs or configuration.
SemVer classification: patch — bug fix and documentation-only changes; no new public API, configuration keys, or behavior that would require consumer code changes beyond test expectations for the resend endpoint.
Installation
Gradle:
implementation 'com.digitalsanctuary:ds-spring-user-framework:5.3.1'Maven:
<dependency>
<groupId>com.digitalsanctuary</groupId>
<artifactId>ds-spring-user-framework</artifactId>
<version>5.3.1</version>
</dependency>Built and verified against Spring Boot 4.1.0 (compatible with 4.0.x), Java 21+.
Behavior changes (client impact)
- POST /user/resendRegistrationToken now accepts an email-only JSON body and returns HTTP 200 on valid input. Previously it bound UserDto (requiring name and password fields), so all resend attempts failed fast with HTTP 400 validation errors. The JSON response body format and numeric response code are unchanged; only the HTTP status on valid requests is corrected to 200. Action: update any client/tests asserting HTTP 400 for successful resend attempts to expect HTTP 200.
- Anti-enumeration semantics are unchanged: the endpoint always returns the same generic success response whether the email is unknown, already verified, or unverified.
- Clients still posting the legacy full registration payload continue to work; extra properties are ignored rather than rejected.
- Blank or malformed emails continue to return HTTP 400.
- POST /user/resetPassword already bound PasswordResetRequestDto correctly; no change.
Fixes
- Bind ResendVerificationDto (single
@NotBlank @Email @Size(max = 100)email) inUserAPI.resendRegistrationTokeninstead of UserDto, so an email-only request body passes validation and triggers the resend flow. Handler logic and response shape (including the numeric JSON response code) are unchanged.
Documentation
- README: corrected UserPreDeleteEvent accessors — the event exposes
getUserId()andgetUserEmail()(notgetUser()); the example listener now compiles against the actual API. - Post-release alignment for the prior 5.3.0 notes: README install snippets and compatibility matrix updated; CHANGELOG wording corrected (registration retry count is 5 with jittered backoff; the remember-me kebab-case fix was not a regression; removed an intra-branch accessor note that never affected released APIs). No runtime changes.
Testing
- Expanded UserAPIUnitTest coverage for resendRegistrationToken: email-only body succeeds (HTTP 200), legacy full payload still accepted, blank/malformed emails rejected with HTTP 400, and the uniform 200 response preserved for unknown/already-verified cases (no existence leak). Test payloads are built with ObjectMapper to avoid JSON escaping pitfalls.
Other Changes
Repository hygiene and tooling, with no impact on consuming applications:
- Moved release/testing/profile docs under
docs/and updated references; CONFIG.md and MIGRATION.md remain at repo root for stable deep links. - Moved Python release tooling to
scripts/and updated Gradle task wiring. - Dropped the vestigial
.hintrcand untracked IDE state; addedlogs/and.idea/to.gitignore.
Full Changelog: 5.3.0...5.3.1