52 lines
1.2 KiB
TypeScript
52 lines
1.2 KiB
TypeScript
const COMMON_WEAK_PASSWORDS = new Set([
|
|
'123456',
|
|
'12345678',
|
|
'123456789',
|
|
'1234567890',
|
|
'password',
|
|
'password123',
|
|
'admin123',
|
|
'admin888',
|
|
'88888888',
|
|
'qwerty123',
|
|
'abc123456',
|
|
'flnxi123',
|
|
])
|
|
|
|
export const PASSWORD_POLICY_DESCRIPTION = '密码至少 10 位,并包含大写字母、小写字母、数字、符号中的至少 3 类'
|
|
|
|
export function validatePasswordStrength(password: string | undefined | null): {
|
|
valid: boolean
|
|
error?: string
|
|
} {
|
|
if (!password) {
|
|
return { valid: false, error: '请提供密码' }
|
|
}
|
|
|
|
if (password.length < 10) {
|
|
return { valid: false, error: '密码长度至少为 10 位' }
|
|
}
|
|
|
|
const normalized = password.toLowerCase()
|
|
if (COMMON_WEAK_PASSWORDS.has(normalized)) {
|
|
return { valid: false, error: '密码过于常见,请换一个更安全的密码' }
|
|
}
|
|
|
|
if (/^(.)\1+$/.test(password)) {
|
|
return { valid: false, error: '密码不能全部使用同一个字符' }
|
|
}
|
|
|
|
const categories = [
|
|
/[a-z]/.test(password),
|
|
/[A-Z]/.test(password),
|
|
/\d/.test(password),
|
|
/[^a-zA-Z0-9]/.test(password),
|
|
].filter(Boolean).length
|
|
|
|
if (categories < 3) {
|
|
return { valid: false, error: PASSWORD_POLICY_DESCRIPTION }
|
|
}
|
|
|
|
return { valid: true }
|
|
}
|