Fix the inaccessible problem of signup page (#6730)

#### What type of PR is this?

/kind bug
/area core
/milestone 2.20.x

#### What this PR does / why we need it:

This PR adds confirmPassword field into SignUpData for validation. So the signup page can be rendered correctly.

See https://github.com/halo-dev/halo/issues/6718 for more.

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/6718

#### Special notes for your reviewer:

#### Does this PR introduce a user-facing change?

```release-note
None
```
pull/6689/head^2
John Niang 2024-09-29 18:01:47 +08:00 committed by GitHub
parent 1947a544f2
commit 83109d0568
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 61 additions and 10 deletions

View File

@ -1,7 +1,16 @@
package run.halo.app.core.user.service; package run.halo.app.core.user.service;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import lombok.Data; import lombok.Data;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
@ -14,6 +23,7 @@ import org.springframework.util.StringUtils;
* @since 2.20.0 * @since 2.20.0
*/ */
@Data @Data
@SignUpData.SignUpDataConstraint
public class SignUpData { public class SignUpData {
@NotBlank @NotBlank
@ -30,6 +40,9 @@ public class SignUpData {
@NotBlank @NotBlank
private String password; private String password;
@NotBlank
private String confirmPassword;
public static SignUpData of(MultiValueMap<String, String> formData) { public static SignUpData of(MultiValueMap<String, String> formData) {
var form = new SignUpData(); var form = new SignUpData();
Optional.ofNullable(formData.getFirst("username")) Optional.ofNullable(formData.getFirst("username"))
@ -52,6 +65,41 @@ public class SignUpData {
.filter(StringUtils::hasText) .filter(StringUtils::hasText)
.ifPresent(form::setEmailCode); .ifPresent(form::setEmailCode);
Optional.ofNullable(formData.getFirst("confirmPassword"))
.filter(StringUtils::hasText)
.ifPresent(form::setConfirmPassword);
return form; return form;
} }
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {SignUpDataConstraintValidator.class})
public @interface SignUpDataConstraint {
String message() default "";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
private static class SignUpDataConstraintValidator
implements ConstraintValidator<SignUpDataConstraint, SignUpData> {
@Override
public boolean isValid(SignUpData signUpData, ConstraintValidatorContext context) {
var isValid = Objects.equals(signUpData.getPassword(), signUpData.getConfirmPassword());
if (!isValid) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(
"{signup.error.confirm-password-not-match}"
)
.addPropertyNode("confirmPassword")
.addConstraintViolation();
}
return isValid;
}
}
} }

View File

@ -103,8 +103,7 @@ class PreAuthSignUpEndpoint {
"emailCode", "emailCode",
signUpData.getEmailCode(), signUpData.getEmailCode(),
true, true,
// TODO Refine i18n new String[] {"signup.error.email-code.invalid"},
new String[] {"signup.error.email-captcha.invalid"},
null, null,
"Invalid Email Code")); "Invalid Email Code"));
} }

View File

@ -82,4 +82,6 @@ problemDetail.attachment.upload.fileSizeExceeded=Make sure the file size is less
problemDetail.attachment.upload.fileTypeNotSupported=Unsupported upload of {0} type files. problemDetail.attachment.upload.fileTypeNotSupported=Unsupported upload of {0} type files.
problemDetail.comment.waitingForApproval=Comment is awaiting approval. problemDetail.comment.waitingForApproval=Comment is awaiting approval.
title.visibility.identification.private=(Private) title.visibility.identification.private=(Private)
signup.error.confirm-password-not-match=The confirmation password does not match the password.
signup.error.email-code.invalid=Invalid email code.

View File

@ -54,4 +54,6 @@ problemDetail.attachment.upload.fileSizeExceeded=最大支持上传 {0} 大小
problemDetail.attachment.upload.fileTypeNotSupported=不支持上传 {0} 类型的文件。 problemDetail.attachment.upload.fileTypeNotSupported=不支持上传 {0} 类型的文件。
problemDetail.comment.waitingForApproval=评论审核中。 problemDetail.comment.waitingForApproval=评论审核中。
title.visibility.identification.private=(私有) title.visibility.identification.private=(私有)
signup.error.confirm-password-not-match=确认密码与密码不匹配。
signup.error.email-code.invalid=邮箱验证码无效。

View File

@ -141,13 +141,13 @@
<div class="form-item"> <div class="form-item">
<label for="confirmPassword" th:text="#{form.confirmPassword.label}"></label> <label for="confirmPassword" th:text="#{form.confirmPassword.label}"></label>
<th:block <th:block
th:replace="~{gateway_modules/input_fragments :: password(id = 'confirmPassword', name = null, required = 'true', minlength = 6, enableToggle = true)}" th:replace="~{gateway_modules/input_fragments :: password(id = 'confirmPassword', name = 'confirmPassword', required = 'true', minlength = 6, enableToggle = true)}"
></th:block> ></th:block>
<!-- <p --> <p
<!-- class="alert alert-error" --> class="alert alert-error"
<!-- th:if="${#fields.hasErrors('confirmPassword')}" --> th:if="${#fields.hasErrors('confirmPassword')}"
<!-- th:errors="*{confirmPassword}" --> th:errors="*{confirmPassword}"
<!-- ></p> --> ></p>
</div> </div>
<div class="form-item"> <div class="form-item">