Эх сурвалжийг харах

fix: 门户网站注册/找回密码增加弱密码检测

周玉环 1 долоо хоног өмнө
parent
commit
b366712e1f

+ 5 - 1
xinkeaboard-web/assets/language/en.js

@@ -849,7 +849,11 @@ export const lang_en = {
         '您已注册成功': 'You have registered successfully.',
         '立即登录': 'Log in now',
         '重置成功': 'Reset successful',
-        '密码重置成功, 5s内跳转至登录页': 'The password reset was successful. You will be redirected to the login page within 5 seconds'
+        '密码重置成功, 5s内跳转至登录页': 'The password reset was successful. You will be redirected to the login page within 5 seconds',
+        '密码长度不能小于8位': 'The password length cannot be less than 8 characters',
+        '密码长度不能超过20位': 'The password length cannot exceed 20 characters',
+        '密码必须同时包含数字、字母、特殊字符中的两种': 'The password must contain two of the following: numbers, letters, and special characters',
+        '密码不能包含空格': 'The password cannot contain Spaces'
     },
 
     // 人机验证

+ 5 - 1
xinkeaboard-web/assets/language/zh.js

@@ -879,7 +879,11 @@ export const lang_zn = {
     //   '您已注册成功, 5s内跳转到登录页': '您已注册成功, 5s内跳转到登录页',
       '立即登录': '立即登录',
       '重置成功': '重置成功',
-      '密码重置成功, 5s内跳转至登录页': '密码重置成功, 5s内跳转至登录页'
+      '密码重置成功, 5s内跳转至登录页': '密码重置成功, 5s内跳转至登录页',
+      '密码长度不能小于8位': '密码长度不能小于8位',
+      '密码长度不能超过20位': '密码长度不能超过20位',
+      '密码必须同时包含数字、字母、特殊字符中的两种': '密码必须同时包含数字、字母、特殊字符中的两种',
+      '密码不能包含空格': '密码不能包含空格'
     },
 
     // 人机验证

+ 9 - 8
xinkeaboard-web/components/register/RegisterAccount.vue

@@ -234,13 +234,14 @@ const checkPwdMatched = () => {
 };
 
 const checkPwdValidate = () => {
-  const regex = /^[A-Za-z0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]{6,20}$/;
-  if (regex.test(password.value)) {
-    checkPwdErrorMsg.value = "";
-    return true;
+  const res = unifyValidatePassword(password.value); 
+  if (!res.ok) {
+    checkPwdErrorMsg.value = res.reasons[0];
+    return false;
   }
-  checkPwdErrorMsg.value = L['请输入6~20位英文、数字、符号'];
-  return false;
+
+  checkPwdErrorMsg.value = ''
+  return true;
 };
 
 watch(name, (val) => {
@@ -320,10 +321,10 @@ watch(name, (val) => {
   }
 
   .error {
-    margin-top: 10px;
+    margin-top: 5px;
     position: relative;
     color: #e2231a;
-    height: 16px;
+    height: 22px;
     line-height: 16px;
 
     .iconfont {

+ 10 - 9
xinkeaboard-web/components/retrieve/RetrievePassword.vue

@@ -188,13 +188,14 @@ const isShowPwd = () => {
 };
 
 const checkPwdValidate = () => {
-  const regex = /^[A-Za-z0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]{6,20}$/;
-  if (regex.test(password.value)) {
-    checkPwdErrorMsg.value = "";
-    return true;
+  const res = unifyValidatePassword(password.value); 
+  if (!res.ok) {
+    checkPwdErrorMsg.value = res.reasons[0];
+    return false;
   }
-  checkPwdErrorMsg.value = L["请输入6~20位英文、数字、符号"];
-  return false;
+
+  checkPwdErrorMsg.value = ''
+  return true;
 };
 
 //开启人机校验
@@ -298,7 +299,7 @@ const getVerifyCode = () => {
 };
 
 const forgetPwd = () => {
-  if (!validateEmail() || !validateEmailCode()) return;
+  if (!validateEmail() || !validateEmailCode() || !checkPwdValidate() || !checkPwdMatched()) return;
   forgetPwdLoading.value = true;
   post("v3/member/front/active/email/reset/pwdNew", {
     confirmPassWord: confirmPassword.value,
@@ -413,10 +414,10 @@ watch(emailCode, (val) => {
   }
 
   .error {
-    margin-top: 10px;
+    margin-top: 5px;
     position: relative;
     color: #e2231a;
-    height: 16px;
+    height: 22px;
     line-height: 16px;
 
     .iconfont {

+ 10 - 9
xinkeaboard-web/components/retrieve/RetrievePwdByPhone.vue

@@ -186,13 +186,14 @@ const isShowPwd = () => {
 };
 
 const checkPwdValidate = () => {
-  const regex = /^[A-Za-z0-9!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]{6,20}$/;
-  if (regex.test(password.value)) {
-    checkPwdErrorMsg.value = "";
-    return true;
+  const res = unifyValidatePassword(password.value); 
+  if (!res.ok) {
+    checkPwdErrorMsg.value = res.reasons[0];
+    return false;
   }
-  checkPwdErrorMsg.value = L["请输入6~20位英文、数字、符号"];
-  return false;
+
+  checkPwdErrorMsg.value = ''
+  return true;
 };
 
 //开启人机校验
@@ -296,7 +297,7 @@ const getVerifyCode = () => {
 };
 
 const forgetPwd = () => {
-  if (!validatePhone() || !validateMobileCode()) return;
+  if (!validatePhone() || !validateMobileCode() || !checkPwdValidate() || !checkPwdMatched()) return;
   forgetPwdLoading.value = true;
   post("v3/member/front/active/email/reset/pwdNew", {
     confirmPassWord: confirmPassword.value,
@@ -409,10 +410,10 @@ watch(mobileCode, (val) => {
   }
 
   .error {
-    margin-top: 10px;
+    margin-top: 5px;
     position: relative;
     color: #e2231a;
-    height: 16px;
+    height: 22px;
     line-height: 16px;
 
     .iconfont {

+ 53 - 0
xinkeaboard-web/composables/common.js

@@ -505,3 +505,56 @@ export function calcMallUrlCatName(val){
     let current = a[0]
     return current
 }
+
+
+const SPECIAL_CHAR_CLASS = /[~!@#$%^&*()_+`\-={}\[\]\|:;\"'<,>.?\/]/;
+const DIGIT_CLASS = /[0-9]/;
+const LOWER_CLASS = /[a-z]/;
+const UPPER_CLASS = /[A-Z]/;
+// 检查所有空格字符(半角/全角)
+// - \s 会捕获常见的空格、制表符、换行符等
+// - \u3000 是全角空格
+const SPACE_REG = /[\s\u3000]/;
+
+
+// 如果想限制“只能使用上述字符(不允许空格、中文等)”,可启用下行:
+// const ALLOWED_ALL = /^[0-9A-Za-z~!@#$%^&*()_+`\-={}\[\]\|:;\"'<,>.?\/]+$/;
+
+export function unifyValidatePassword(pwd) {
+  const L = getCurLanguage();
+  const reasons = [];
+
+  // 1) 长度校验:8-20
+  if (pwd.length < 8) {
+    reasons.push(L['register']["密码长度不能小于8位"]);
+  } else if (pwd.length > 20) {
+    reasons.push(L['register']['密码长度不能超过20位']);
+  }
+
+  // 2) 统计字符类别命中数(四类中至少两类)
+  const hasDigit = DIGIT_CLASS.test(pwd);
+  const hasLower = LOWER_CLASS.test(pwd);
+  const hasUpper = UPPER_CLASS.test(pwd);
+  const hasSpecial = SPECIAL_CHAR_CLASS.test(pwd);
+
+  const typeCount = [hasDigit, hasLower, hasUpper, hasSpecial].filter(Boolean).length;
+
+  if (typeCount < 2) {
+    reasons.push(L['register']['密码必须同时包含数字、字母、特殊字符中的两种']);
+  }
+
+  if (SPACE_REG.test(pwd)) {
+    reasons.push(L['register']['密码不能包含空格']);
+  }
+
+  // 4) 可选:若只想限定在“允许字符集合”内,打开 ALLOWED_ALL 后使用以下判断
+  // if (!ALLOWED_ALL.test(pwd)) {
+  //   reasons.push("密码包含不被允许的字符。");
+  // }
+
+  return {
+    ok: reasons.length === 0,
+    reasons,
+  };
+}
+