veza/apps/web/src/lib/passwordValidator.ts

100 lines
2.3 KiB
TypeScript
Raw Normal View History

/**
* Password Validator
* T0197: Validates password strength with minimum 8 characters, uppercase, lowercase, number, and special character
*/
export interface PasswordValidationResult {
isValid: boolean;
errors: string[];
strength: {
length: boolean;
upper: boolean;
lower: boolean;
number: boolean;
special: boolean;
};
}
/**
* Validates password strength according to security rules
* @param password - The password to validate
* @returns Validation result with isValid flag, errors array, and strength checks
*/
export function validatePasswordStrength(
password: string
): PasswordValidationResult {
const errors: string[] = [];
const strength = {
length: false,
upper: false,
lower: false,
number: false,
special: false,
};
// Length check (minimum 8 characters)
if (password.length < 8) {
errors.push('password must be at least 8 characters');
} else {
strength.length = true;
}
// Maximum length check
if (password.length > 128) {
errors.push('password must be less than 128 characters');
}
// Upper case check
if (!/[A-Z]/.test(password)) {
errors.push('password must contain at least one uppercase letter');
} else {
strength.upper = true;
}
// Lower case check
if (!/[a-z]/.test(password)) {
errors.push('password must contain at least one lowercase letter');
} else {
strength.lower = true;
}
// Number check
if (!/[0-9]/.test(password)) {
errors.push('password must contain at least one number');
} else {
strength.number = true;
}
// Special character check
if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
errors.push('password must contain at least one special character');
} else {
strength.special = true;
}
return {
isValid: errors.length === 0,
errors,
strength,
};
}
/**
* Calculates password strength score (0-5)
* @param password - The password to score
* @returns Score from 0 to 5
*/
export function calculatePasswordStrength(password: string): number {
const result = validatePasswordStrength(password);
let score = 0;
if (result.strength.length) score++;
if (result.strength.upper) score++;
if (result.strength.lower) score++;
if (result.strength.number) score++;
if (result.strength.special) score++;
return score;
}