2026-08-17 12:25:42 +08:00
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 统一输入校验规则集(基于 egg-validate / parameter)
|
|
|
|
|
|
*
|
|
|
|
|
|
* 对应各接口请求体的字段级校验。校验失败由控制器以
|
|
|
|
|
|
* `ctx.helper.error(400, '参数校验失败:' + validateErr.errors[0].message)`
|
|
|
|
|
|
* 统一封装为应用错误信封,与 admin 控制器既有模式保持一致。
|
|
|
|
|
|
*
|
|
|
|
|
|
* 规则说明:
|
|
|
|
|
|
* - type: 'string' + required: true + allowEmpty: false:字段必填且不可为空串/纯空白
|
|
|
|
|
|
* - trim: true:校验前去除首尾空白
|
2026-09-30 11:56:35 +08:00
|
|
|
|
* - min / max:字符串长度区间(口令口径 6-20,与前端 el-form 规则保持一致)
|
2026-08-17 12:25:42 +08:00
|
|
|
|
* - message:为每个校验项提供中文错误文案,parameter 会在 errors[] 中携带对应 message
|
2026-09-30 11:56:35 +08:00
|
|
|
|
*
|
|
|
|
|
|
* ⚠️ 口令的**强度**(弱口令黑名单 / 纯重复字符 / 连续序列 / 账号派生值)**不在本文件**。
|
|
|
|
|
|
* 本文件只负责「必填 + 长度格式」这一层;强度规则由 app/lib/passwordPolicy.js
|
|
|
|
|
|
* 单源提供,调用点在 controller/auth.js 的 activate() 与 resetPassword()。
|
|
|
|
|
|
* 分层理由:同一份强度规则需被多个口令写入口共用,并须能被运维脚本复用
|
|
|
|
|
|
* (脚本要扫描存量账号是否命中弱口令),散落实现必然出现「一处拦、一处放」。
|
2026-08-17 12:25:42 +08:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
const required = (msg) => ({
|
|
|
|
|
|
type: 'string',
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
allowEmpty: false,
|
|
|
|
|
|
trim: true,
|
|
|
|
|
|
message: { required: msg, empty: msg },
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
|
// 选手登录:手机号 + 密码
|
|
|
|
|
|
login: {
|
|
|
|
|
|
phone: required('请输入手机号'),
|
|
|
|
|
|
password: required('请输入密码'),
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 管理员登录:用户名 + 密码
|
|
|
|
|
|
adminLogin: {
|
|
|
|
|
|
username: required('请输入管理员用户名'),
|
|
|
|
|
|
password: required('请输入密码'),
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 发送短信验证码:身份证号 + 图形验证码
|
|
|
|
|
|
sms: {
|
|
|
|
|
|
phone: required('请输入身份证号'),
|
|
|
|
|
|
captcha: required('请输入图形验证码'),
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 账号激活:身份证号 + 手机号 + 短信验证码 + 密码(>=6)
|
|
|
|
|
|
activate: {
|
|
|
|
|
|
id_number: required('请输入身份证号'),
|
|
|
|
|
|
phone: required('请输入手机号'),
|
|
|
|
|
|
smsCode: required('请输入短信验证码'),
|
|
|
|
|
|
password: {
|
|
|
|
|
|
type: 'string',
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
allowEmpty: false,
|
|
|
|
|
|
trim: true,
|
|
|
|
|
|
min: 6,
|
2026-09-30 11:56:35 +08:00
|
|
|
|
max: 20,
|
2026-08-17 12:25:42 +08:00
|
|
|
|
message: {
|
|
|
|
|
|
required: '请输入密码',
|
|
|
|
|
|
empty: '请输入密码',
|
|
|
|
|
|
min: '密码长度不能少于 6 位',
|
2026-09-30 11:56:35 +08:00
|
|
|
|
max: '密码长度不能超过 20 位',
|
2026-08-17 12:25:42 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 忘记密码-发码:身份证号 + 图形验证码
|
|
|
|
|
|
forgotPassword: {
|
|
|
|
|
|
id_number: required('请输入身份证号'),
|
|
|
|
|
|
captcha: required('请输入图形验证码'),
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 重置密码:身份证号 + 短信验证码 + 密码(>=6)
|
|
|
|
|
|
resetPassword: {
|
|
|
|
|
|
id_number: required('请输入身份证号'),
|
|
|
|
|
|
smsCode: required('请输入短信验证码'),
|
|
|
|
|
|
password: {
|
|
|
|
|
|
type: 'string',
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
allowEmpty: false,
|
|
|
|
|
|
trim: true,
|
|
|
|
|
|
min: 6,
|
2026-09-30 11:56:35 +08:00
|
|
|
|
max: 20,
|
2026-08-17 12:25:42 +08:00
|
|
|
|
message: {
|
|
|
|
|
|
required: '请输入密码',
|
|
|
|
|
|
empty: '请输入密码',
|
|
|
|
|
|
min: '密码长度不能少于 6 位',
|
2026-09-30 11:56:35 +08:00
|
|
|
|
max: '密码长度不能超过 20 位',
|
2026-08-17 12:25:42 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|