validatePassword.js

import devWarn from './utils/devWarn';
var regNumber = /[\d]/;
var regLowerCaseLetter = /[a-z]/;
var regUpperCaseLetter = /[A-Z]/;
var regAllNumberAndLetter = /[\d|a-z]/gi;
/**
 * 是否包含数字
 *
 * @private
 * @param {string} val 检查的值
 * @returns {boolean} 是否包含数字
 */
function hasNumber(val) {
    return regNumber.test(val);
}
/**
 * 是否包含小写字母
 *
 * @private
 * @param {string} val 检测的值
 * @returns {boolean} 是否包含小写字母
 */
function hasLowerCaseLetter(val) {
    return regLowerCaseLetter.test(val);
}
/**
 * 是否包含大写字母
 *
 * @private
 * @param {string} val 检测的值
 * @returns {boolean} 是否包含大写字母
 */
function hasUpperCaseLetter(val) {
    return regUpperCaseLetter.test(val);
}
/**
 * 是否为十六进制
 *
 * @private
 * @param {string} val 检测的值
 * @returns {boolean} 是否为十六进制
 */
function hasHex(val) {
    return val.indexOf('\\x') > -1 || val.indexOf('\\u') > -1;
}
/**
 * 是否包含特殊字符
 *
 * @private
 * @param {string} val 检测的值
 * @param {string} chars 特殊字符
 * @returns {boolean} 是否包含特殊字符
 */
function hasSpecialCharacter(val, chars) {
    if (!chars || !val) {
        return false;
    }
    var specialChars = val.replace(regAllNumberAndLetter, '');
    if (!specialChars) {
        return false;
    }
    var regChars = hasHex(chars) ? new RegExp("[".concat(chars, "]")) : null;
    if (regChars) {
        return regChars.test(specialChars);
    }
    var ret = false;
    specialChars.split('').some(function (charItem) {
        if (chars.indexOf(charItem) > -1) {
            ret = true;
        }
        return ret;
    });
    return ret;
}
/**
 * 是否包含非法字符
 *
 * @private
 * @param {string} val 检测的值
 * @param {string} chars 特殊字符
 * @returns {boolean} 是否包含非法字符
 */
function hasUnallowableCharacter(val, chars) {
    if (!val) {
        return false;
    }
    var specialChars = val.replace(regAllNumberAndLetter, '');
    if (!specialChars) {
        return false;
    }
    else if (!chars) {
        return true;
    }
    var regChars = hasHex(chars) ? new RegExp("[^".concat(chars, "]")) : null;
    if (regChars) {
        return regChars.test(specialChars);
    }
    var ret = false;
    specialChars.split('').some(function (charItem) {
        if (chars.indexOf(charItem) === -1) {
            ret = true;
        }
        return ret;
    });
    return ret;
}
/**
 * @typedef {Object} PasswordContaines - 验证密码的包含内容
 * @property {boolean} number - 包含数字
 * @property {boolean} lowerCaseLetter - 包含小写字母
 * @property {boolean} upperCaseLetter - 包含大写字母
 * @property {boolean} specialCharacter - 包含特殊字符
 * @property {boolean} unallowableCharacter - 包含非法字符
 */
/**
 * @typedef {Object} ValidatePasswordReturn - 验证结果
 * @property {boolean} validated - 验证结果,根据密码强度、是否包含非法字符得出
 * @property {number} level - 强度级别,包含数字/大小写字母/特殊字符
 * @property {PasswordContaines} containes - 包含内容
 */
/**
 * 验证密码(数字、大小写字母、特殊字符、非法字符)
 *
 * @static
 * @alias module:Validator.validatePassword
 * @since 3.7.0
 * @see {@link https://baike.baidu.com/item/ASCII#3 | ASCII}
 * @param {string} value 要检测的值
 * @param {Object} [options] 配置项
 * @param {number} [options.level=2] 密码强度 1-包含一种字符 2-包含两种字符 3-包含三种字符。(大写字母、小写字母、数字、特殊字符)
 * @param {boolean} [options.ignoreCase=false] 是否忽略大小写,为 ture 时,大小写字母视为一种字符
 * @param {string} [options.special="!@#$%^&*()-=_+[]\|{},./?<>~"] 支持的特殊字符
 * @returns {ValidatePasswordReturn} 验证结果
 * @example
 *
 * validatePassword('a12345678');
 * // =>
 * {
 *   validated: true, // 验证结果,根据密码强度、是否包含非法字符得出
 *   level: 2, // 强度级别
 *   containes: {
 *     number: true, // 包含数字
 *     lowerCaseLetter: true, // 包含小写字母
 *     upperCaseLetter: false, // 包含大写字母
 *     specialCharacter: false, // 包含特殊字符
 *     unallowableCharacter: false // 包含非法字符
 *   }
 * }
 *
 * validatePassword('a12345678', { level: 3 });
 * // =>
 * {
 *   validated: false,
 *   level: 2,
 *   containes: {
 *     number: true,
 *     lowerCaseLetter: true,
 *     upperCaseLetter: false,
 *     specialCharacter: false,
 *     unallowableCharacter: false
 *   }
 * }
 *
 * validatePassword('_Aa一二三45678', { level: 3, ignoreCase: true });
 * // =>
 * {
 *   validated: false,
 *   level: 3,
 *   containes: {
 *     number: true,
 *     lowerCaseLetter: true,
 *     upperCaseLetter: true,
 *     specialCharacter: true,
 *     unallowableCharacter: true
 *   }
 * }
 *
 * // 自定义特殊字符
 * validatePassword('_Aa一二三45678', { level: 3, ignoreCase: true, special: '_一二三' });
 * // =>
 * {
 *   validated: true,
 *   level: 3,
 *   containes: {
 *     number: true,
 *     lowerCaseLetter: true,
 *     upperCaseLetter: true,
 *     specialCharacter: true,
 *     unallowableCharacter: false
 *   }
 * }
 */
function validatePassword(value, options) {
    if (options === void 0) { options = {}; }
    var _a = options.level, level = _a === void 0 ? 2 : _a, _b = options.ignoreCase, ignoreCase = _b === void 0 ? false : _b, _c = options.special, special = _c === void 0 ? '\\x21-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7B-\\x7E' : _c;
    var valStr = value;
    if (typeof value !== 'string') {
        devWarn("[validatePassword] value must be a string.");
        valStr = '';
    }
    var currentLevel = 0;
    // 包含数字
    var containesNumber = hasNumber(valStr);
    // 包含小写字母
    var containesLowerCaseLetter = hasLowerCaseLetter(valStr);
    // 包含大写字母
    var containesUpperCaseLetter = hasUpperCaseLetter(valStr);
    // 包含特殊字符
    var containesSpecialCharacter = hasSpecialCharacter(valStr, special);
    // 包含非法字符,即含有非数字字母特殊字符以外的其他字符
    var containesUnallowableCharacter = hasUnallowableCharacter(valStr, special);
    if (containesNumber) {
        currentLevel += 1;
    }
    // 不区分大小写
    if (ignoreCase) {
        if (containesLowerCaseLetter || containesUpperCaseLetter) {
            currentLevel += 1;
        }
    }
    else {
        // 区分大小写
        if (containesLowerCaseLetter) {
            currentLevel += 1;
        }
        if (containesUpperCaseLetter) {
            currentLevel += 1;
        }
    }
    if (containesSpecialCharacter) {
        currentLevel += 1;
    }
    // 验证结果
    var validated = currentLevel >= level && !containesUnallowableCharacter;
    return {
        validated: validated,
        level: currentLevel,
        containes: {
            number: containesNumber,
            lowerCaseLetter: containesLowerCaseLetter,
            upperCaseLetter: containesUpperCaseLetter,
            specialCharacter: containesSpecialCharacter,
            unallowableCharacter: containesUnallowableCharacter
        }
    };
}
export default validatePassword;