import zxcvbn from "zxcvbn"; export interface PasswordValidationResult { valid: boolean; feedback: string[]; score: number; } /** * Validate password strength using zxcvbn * @param password - The password to validate * @param userInputs - User-specific inputs to penalize (email, display name) * @returns Validation result with feedback if invalid */ export const validatePassword = ( password: string, userInputs: string[] = [], ): PasswordValidationResult => { const result = zxcvbn(password, userInputs); if (result.score < 3) { const feedback = result.feedback.suggestions.length > 0 ? result.feedback.suggestions : [ "Password is too weak. Try a longer phrase or add numbers and symbols.", ]; return { valid: false, feedback, score: result.score, }; } return { valid: true, feedback: [], score: result.score, }; }; /** * Hash a password using Bun's built-in argon2id * @param password - The plaintext password to hash * @returns The hashed password */ export const hashPassword = async (password: string): Promise => { return Bun.password.hash(password, { algorithm: "argon2id", memoryCost: 65536, // 64 MiB timeCost: 3, }); }; /** * Verify a password against a stored hash * @param password - The plaintext password to verify * @param hash - The stored password hash * @returns True if the password matches the hash */ export const verifyPassword = async ( password: string, hash: string, ): Promise => { return Bun.password.verify(password, hash); };