mirror of https://github.com/halo-dev/halo
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
parent
1947a544f2
commit
83109d0568
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,3 +83,5 @@ problemDetail.attachment.upload.fileTypeNotSupported=Unsupported upload of {0} t
|
||||||
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.
|
|
@ -55,3 +55,5 @@ 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=邮箱验证码无效。
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in New Issue