Skip to content

resendRegistrationToken always returns 400: it validates the full registration UserDto #361

Closed

Description

@devondragon

Summary

POST /user/resendRegistrationToken can never succeed. UserAPI.resendRegistrationToken binds the same UserDto used for full registration, and that DTO carries @NotBlank on firstName, lastName, password, and matchingPassword. A resend request only has an email address to send, so validation always fails and the endpoint returns HTTP 400 without sending mail.

Found in ds-spring-user-framework:5.3.0 while verifying the demo app's Docker stacks against a real mail catcher (devondragon/SpringUserFrameworkDemoApp#87). The flow had gone unexercised because no documented demo run path had working SMTP.

Reproduce

  1. Run the demo app with user.registration.sendVerificationEmail: true and a reachable SMTP server.
  2. Register an account, but do not click the verification link.
  3. Open /user/request-new-verification-email.html, enter that email, submit.

Expected: a new verification email.
Actual: the page shows "Unable to resend verification email." No mail is sent.

Server log

DEBUG ... RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to
  [UserDto(firstName=null, lastName=null, email=resend-check@example.com, role=null)]
WARN  ... GlobalValidationExceptionHandler : Validation error occurred: Validation failed for
  argument [0] in public ResponseEntity<JSONResponse> UserAPI.resendRegistrationToken(UserDto,
  HttpServletRequest) with 4 errors:
  [Field error in object 'userDto' on field 'matchingPassword': rejected value [null];
    default message [Password confirmation is required]]
  [Field error in object 'userDto' on field 'password': rejected value [null];
    default message [Password is required]]
  [Field error in object 'userDto' on field 'lastName': rejected value [null];
    default message [Last name is required]]
  [Field error in object 'userDto' on field 'firstName': rejected value [null];
    default message [First name is required]]

The client is not at fault: the framework's own resend-verification.js posts { email }, which is the only field a resend needs.

Suggested fix

Bind a request type that carries just the email, e.g. a small ResendVerificationDto/EmailDto with @NotBlank @Email String email, rather than reusing the registration UserDto. POST /user/resetPassword has the same shape and is worth checking for the same problem.

Whatever the shape, the endpoint should keep its existing generic response so it does not leak whether an address is registered.

Activity

  1. devondragon commented on Aug 18, 2026

    @devondragon
    OwnerAuthor

    PR ready for review: #362

  2. devondragon commented on Aug 18, 2026

    @devondragon
    OwnerAuthor

    Work Complete — PR Merged

    PR: fix: bind email-only DTO on resendRegistrationToken (#361)
    Merged into: main (squash, commit 106d011)
    Branch: bugfix/361-resend-verification-email-only-dto (deleted)

    Summary of changes

    • POST /user/resendRegistrationToken now binds a new ResendVerificationDto carrying only email (@NotBlank @Email @Size(max=100)) instead of the registration UserDto, so an email-only body no longer fails validation with HTTP 400.
    • The anti-enumeration behavior is unchanged: the same generic 200 response for unknown, already-verified, and unverified accounts, with the true outcome still recorded via audit events.
    • POST /user/resetPassword was checked as the issue suggested and needed no change: it already binds a dedicated PasswordResetRequestDto. Extending that check across every @RequestBody binding in src/main/java (UserAPI, GdprAPI, WebAuthnManagementAPI) found no other endpoint reusing a DTO with fields it does not need.
    • Test coverage added for the email-only body, blank and malformed emails (400, no mail sent), and a legacy full registration payload, which is still accepted since the extra properties are ignored rather than rejected. No client change is required.

    Files changed

    • src/main/java/com/digitalsanctuary/spring/user/dto/ResendVerificationDto.java (new)
    • src/main/java/com/digitalsanctuary/spring/user/api/UserAPI.java
    • src/test/java/com/digitalsanctuary/spring/user/api/UserAPIUnitTest.java
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions