UNPKG

@dax-crafta/auth

Version:

A powerful, flexible, and secure authentication plugin for the Crafta framework. Supports JWT, social login, 2FA, RBAC, audit logging, and enterprise-grade security features.

65 lines (50 loc) 2.22 kB
// packages/auth/src/utils/password-policy.js const zxcvbn = require('zxcvbn'); class PasswordPolicy { constructor(config = {}) { this.config = { minLength: config.minLength || 8, requireUppercase: config.requireUppercase !== false, requireLowercase: config.requireLowercase !== false, requireNumbers: config.requireNumbers !== false, requireSpecialChars: config.requireSpecialChars !== false, passwordHistory: config.passwordHistory || 5, expiryDays: config.expiryDays || 90, minStrength: config.minStrength || 3 }; } validate(password, userInfo = {}) { const errors = []; if (password.length < this.config.minLength) errors.push(`Password must be at least ${this.config.minLength} characters long`); if (this.config.requireUppercase && !/[A-Z]/.test(password)) errors.push('Password must contain at least one uppercase letter'); if (this.config.requireLowercase && !/[a-z]/.test(password)) errors.push('Password must contain at least one lowercase letter'); if (this.config.requireNumbers && !/\d/.test(password)) errors.push('Password must contain at least one number'); if (this.config.requireSpecialChars && !/[!@#$%^&*(),.?":{}|<>]/.test(password)) errors.push('Password must contain at least one special character'); const strength = zxcvbn(password, [userInfo.email, userInfo.name]); if (strength.score < this.config.minStrength) errors.push('Password is too weak. Please choose a stronger password'); return { isValid: errors.length === 0, errors, strength: strength.score }; } // History check moved to Model & AuthService allowsReuse(password, passwordHistory, bcrypt) { return Promise.all( passwordHistory.map(old => bcrypt.compare(password, old.hash)) ).then(matches => !matches.includes(true)); } isExpired(lastChange) { if (!this.config.expiryDays) return false; const expiryDate = new Date(lastChange.getTime() + this.config.expiryDays * 24 * 60 * 60 * 1000); return expiryDate < new Date(); } } module.exports = PasswordPolicy;