(
password: string,
_config?: unknown,
_userInfo?: { email?: string; username?: string; name?: string },
)
| 83 | * Password validation using Zod |
| 84 | */ |
| 85 | export function validatePassword( |
| 86 | password: string, |
| 87 | _config?: unknown, |
| 88 | _userInfo?: { email?: string; username?: string; name?: string }, |
| 89 | ): PasswordValidationResult { |
| 90 | if (!password || typeof password !== 'string') { |
| 91 | return { |
| 92 | valid: false, |
| 93 | errors: ['Password is required'], |
| 94 | score: 0, |
| 95 | requirements: { |
| 96 | minLength: false, |
| 97 | hasLowercase: false, |
| 98 | hasUppercase: false, |
| 99 | hasNumbers: false, |
| 100 | hasSpecialChars: false, |
| 101 | notCommon: false, |
| 102 | noSequential: false, |
| 103 | }, |
| 104 | }; |
| 105 | } |
| 106 | |
| 107 | const result = passwordSchema.safeParse(password); |
| 108 | |
| 109 | const requirements = { |
| 110 | minLength: password.length >= 8, |
| 111 | hasLowercase: /[a-z]/.test(password), |
| 112 | hasUppercase: /[A-Z]/.test(password), |
| 113 | hasNumbers: /[0-9]/.test(password), |
| 114 | hasSpecialChars: /[^a-zA-Z0-9]/.test(password), |
| 115 | notCommon: true, |
| 116 | noSequential: true, |
| 117 | }; |
| 118 | |
| 119 | // Calculate score based on strength |
| 120 | let score = 0; |
| 121 | if (requirements.minLength) score++; |
| 122 | if (requirements.hasLowercase && requirements.hasUppercase) score++; |
| 123 | if (requirements.hasNumbers) score++; |
| 124 | if (requirements.hasSpecialChars) score++; |
| 125 | if (password.length >= 12) score = Math.min(4, score + 1); |
| 126 | |
| 127 | // Generate suggestions |
| 128 | const suggestions: string[] = []; |
| 129 | if (password.length < 12) { |
| 130 | suggestions.push('Use at least 12 characters for better security'); |
| 131 | } |
| 132 | if (!requirements.hasSpecialChars) { |
| 133 | suggestions.push('Add special characters for enhanced security'); |
| 134 | } |
| 135 | |
| 136 | if (!result.success) { |
| 137 | return { |
| 138 | valid: false, |
| 139 | errors: result.error.errors.map(e => e.message), |
| 140 | score, |
| 141 | requirements, |
| 142 | suggestions: suggestions.length > 0 ? suggestions : undefined, |
no test coverage detected