73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
export interface EditableAccountProfile {
|
||
realName: string
|
||
email: string
|
||
}
|
||
|
||
export interface LoginIdentifierChangePayload {
|
||
username: string
|
||
phone: string
|
||
currentPassword: string
|
||
}
|
||
|
||
export interface PasswordChangePayload {
|
||
currentPassword: string
|
||
newPassword: string
|
||
confirmPassword: string
|
||
}
|
||
|
||
const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||
const USERNAME_PATTERN = /^[A-Za-z][A-Za-z0-9_.@-]{3,63}$/
|
||
const MAINLAND_MOBILE_PATTERN = /^1[3-9]\d{9}$/
|
||
|
||
export function validateEditableAccountProfile(profile: EditableAccountProfile): string[] {
|
||
const errors: string[] = []
|
||
const realName = profile.realName.trim()
|
||
const email = profile.email.trim()
|
||
|
||
if (realName.length < 1 || realName.length > 64) errors.push('姓名需为 1–64 个字符')
|
||
if (email && !EMAIL_PATTERN.test(email)) errors.push('请输入有效的邮箱地址')
|
||
|
||
return errors
|
||
}
|
||
|
||
export function validateLoginIdentifierChange(payload: LoginIdentifierChangePayload): string[] {
|
||
const errors: string[] = []
|
||
if (!USERNAME_PATTERN.test(payload.username.trim())) {
|
||
errors.push('用户名须以字母开头,并由 4–64 位字母、数字或 _.@- 组成')
|
||
}
|
||
if (!MAINLAND_MOBILE_PATTERN.test(payload.phone.trim())) errors.push('请输入有效的中国大陆手机号')
|
||
if (!payload.currentPassword) errors.push('请输入当前密码')
|
||
return errors
|
||
}
|
||
|
||
export function validatePasswordChange(payload: PasswordChangePayload): string[] {
|
||
const errors: string[] = []
|
||
|
||
if (!payload.currentPassword) errors.push('请输入当前密码')
|
||
if (payload.newPassword.length < 8 || payload.newPassword.length > 64) {
|
||
errors.push('新密码需为 8–64 个字符')
|
||
}
|
||
if (payload.newPassword.length >= 8 && (!/[a-zA-Z]/.test(payload.newPassword) || !/\d/.test(payload.newPassword))) {
|
||
errors.push('新密码必须同时包含字母和数字')
|
||
}
|
||
if (payload.newPassword && payload.newPassword === payload.currentPassword) {
|
||
errors.push('新密码不能与当前密码相同')
|
||
}
|
||
if (payload.confirmPassword !== payload.newPassword) errors.push('两次输入的新密码不一致')
|
||
|
||
return errors
|
||
}
|
||
|
||
export type PasswordStrength = 'weak' | 'medium' | 'strong'
|
||
|
||
export function getPasswordStrength(password: string): PasswordStrength {
|
||
let categoryCount = 0
|
||
if (/[a-zA-Z]/.test(password)) categoryCount += 1
|
||
if (/\d/.test(password)) categoryCount += 1
|
||
if (/[^a-zA-Z\d]/.test(password)) categoryCount += 1
|
||
|
||
if (password.length >= 12 && categoryCount >= 3) return 'strong'
|
||
if (password.length >= 8 && categoryCount >= 2) return 'medium'
|
||
return 'weak'
|
||
}
|