- 组织/人员/委派对齐:费用类型、部门、员工别名、配置只读与回归脚本(F2/F3/F26/F27/F29/F31/F40) - 报销单 PATCH/DELETE 与 items CRUD(事务内重算 total_amount)(F4/F5) - 行政代提交/代上传后端校验与审计(F7/F8) - 认证安全基线:首次登录改密、失败锁定、弱密码拦截与回归脚本(F36/F37/F39/F41)
33 行
896 B
JavaScript
33 行
896 B
JavaScript
const zxcvbn = require("zxcvbn");
|
|
|
|
function validatePassword(password) {
|
|
const errors = [];
|
|
|
|
if (typeof password !== "string" || password.length < 12) {
|
|
errors.push("密码长度必须 ≥ 12");
|
|
}
|
|
if (!/[a-z]/.test(password)) {
|
|
errors.push("密码必须包含小写字母");
|
|
}
|
|
if (!/[A-Z]/.test(password)) {
|
|
errors.push("密码必须包含大写字母");
|
|
}
|
|
if (!/[0-9]/.test(password)) {
|
|
errors.push("密码必须包含数字");
|
|
}
|
|
|
|
const weakCheckEnabled = process.env.WEAK_PASSWORD_CHECK_ENABLED !== "false";
|
|
const weakMinScore = Number(process.env.WEAK_PASSWORD_MIN_SCORE ?? 2);
|
|
|
|
if (weakCheckEnabled && typeof password === "string" && password.length >= 1) {
|
|
const score = zxcvbn(password).score ?? 0;
|
|
if (score < weakMinScore) {
|
|
errors.push("密码过于常见/弱");
|
|
}
|
|
}
|
|
|
|
return errors;
|
|
}
|
|
|
|
module.exports = { validatePassword };
|