Files
Charon/frontend/src/utils/passwordStrength.ts

81 lines
1.6 KiB
TypeScript

export interface PasswordStrength {
score: number; // 0-4
label: string;
color: string; // Tailwind color class prefix (e.g., 'red', 'yellow', 'green')
feedback: string[];
}
export function calculatePasswordStrength(password: string): PasswordStrength {
let score = 0;
const feedback: string[] = [];
if (!password) {
return {
score: 0,
label: 'Empty',
color: 'gray',
feedback: [],
};
}
// Length check
if (password.length < 8) {
feedback.push('Too short (min 8 chars)');
} else {
score += 1;
}
if (password.length >= 12) {
score += 1;
}
// Complexity checks
const hasLower = /[a-z]/.test(password);
const hasUpper = /[A-Z]/.test(password);
const hasNumber = /\d/.test(password);
const hasSpecial = /[^A-Za-z0-9]/.test(password);
const varietyCount = [hasLower, hasUpper, hasNumber, hasSpecial].filter(Boolean).length;
if (varietyCount >= 3) {
score += 1;
}
if (varietyCount === 4) {
score += 1;
}
// Penalties
if (varietyCount < 2 && password.length >= 8) {
feedback.push('Add more variety (uppercase, numbers, symbols)');
}
// Cap score at 4
score = Math.min(score, 4);
// Determine label and color
let label = 'Very Weak';
let color = 'red';
switch (score) {
case 0:
case 1:
label = 'Weak';
color = 'red';
break;
case 2:
label = 'Fair';
color = 'yellow';
break;
case 3:
label = 'Good';
color = 'green';
break;
case 4:
label = 'Strong';
color = 'green';
break;
}
return { score, label, color, feedback };
}