EVOLUTION-MANAGER
Edit File: password.js
/** * @author Òscar Casajuana a.k.a. elboletaire <elboletaire at underave dot net> * @link https://github.com/elboletaire/password-strength-meter * @license GPL-3.0 */ // eslint-disable-next-line ;(function($) { 'use strict'; var Password = function ($object, options) { var defaults = { enterPass: 'Type your password', shortPass: 'The password is too short', containsField: 'The password contains your username', steps: { 13: 'Really insecure password', 33: 'Weak; try combining letters & numbers', 67: 'Medium; try using special characters', 94: 'Strong password', }, showPercent: false, showText: true, animate: true, animateSpeed: 'fast', field: false, fieldPartialMatch: true, minimumLength: 4, closestSelector: 'div', useColorBarImage: false, customColorBarRGB: { red: [0, 240], green: [0, 240], blue: 10 }, }; options = $.extend({}, defaults, options); /** * Returns strings based on the score given. * * @param {int} score Score base. * @return {string} */ function scoreText(score) { if (score === -1) { return options.shortPass; } if (score === -2) { return options.containsField; } score = score < 0 ? 0 : score; var text = options.shortPass; var sortedStepKeys = Object.keys(options.steps).sort(); for (var step in sortedStepKeys) { var stepVal = sortedStepKeys[step]; if (stepVal < score) { text = options.steps[stepVal]; } } return text; } /** * Returns a value between -2 and 100 to score * the user's password. * * @param {string} password The password to be checked. * @param {string} field The field set (if options.field). * @return {int} */ function calculateScore(password, field) { var score = 0; // password < options.minimumLength if (password.length < options.minimumLength) { return -1; } if (options.field) { // password === field if (password.toLowerCase() === field.toLowerCase()) { return -2; } // password contains field (and fieldPartialMatch is set to true) if (options.fieldPartialMatch && field.length) { var user = new RegExp(field.toLowerCase()); if (password.toLowerCase().match(user)) { return -2; } } } // password length score += password.length * 4; score += checkRepetition(1, password).length - password.length; score += checkRepetition(2, password).length - password.length; score += checkRepetition(3, password).length - password.length; score += checkRepetition(4, password).length - password.length; // password has 3 numbers if (password.match(/(.*[0-9].*[0-9].*[0-9])/)) { score += 5; } // password has at least 2 symbols var symbols = '.*[!,@,#,$,%,^,&,*,?,_,~]'; symbols = new RegExp('(' + symbols + symbols + ')'); if (password.match(symbols)) { score += 5; } // password has Upper and Lower chars if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) { score += 10; } // password has number and chars if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) { score += 15; } // password has number and symbol if (password.match(/([!@#$%^&*?_~])/) && password.match(/([0-9])/)) { score += 15; } // password has char and symbol if (password.match(/([!@#$%^&*?_~])/) && password.match(/([a-zA-Z])/)) { score += 15; } // password is just numbers or chars if (password.match(/^\w+$/) || password.match(/^\d+$/)) { score -= 10; } if (score > 100) { score = 100; } if (score < 0) { score = 0; } return score; } /** * Checks for repetition of characters in * a string * * @param {int} length Repetition length. * @param {string} str The string to be checked. * @return {string} */ function checkRepetition(length, str) { var res = "", repeated = false; for (var i = 0; i < str.length; i++) { repeated = true; for (var j = 0; j < length && (j + i + length) < str.length; j++) { repeated = repeated && (str.charAt(j + i) === str.charAt(j + i + length)); } if (j < length) { repeated = false; } if (repeated) { i += length - 1; repeated = false; } else { res += str.charAt(i); } } return res; } /** * Calculates background colors from percentage value. * * @param {int} perc The percentage strength of the password. * @return {object} Object with colors as keys */ function calculateColorFromPercentage(perc) { var minRed = 0; var maxRed = 240; var minGreen = 0; var maxGreen = 240; var blue = 10; if (Object.prototype.hasOwnProperty.call(options.customColorBarRGB, 'red')) { minRed = options.customColorBarRGB.red[0]; maxRed = options.customColorBarRGB.red[1]; } if (Object.prototype.hasOwnProperty.call(options.customColorBarRGB, 'green')) { minGreen = options.customColorBarRGB.green[0]; maxGreen = options.customColorBarRGB.green[1]; } if (Object.prototype.hasOwnProperty.call(options.customColorBarRGB, 'blue')) { blue = options.customColorBarRGB.blue; } var green = (perc * maxGreen / 50); var red = (2 * maxRed) - (perc * maxRed / 50); return { red: Math.min(Math.max(red, minRed), maxRed), green: Math.min(Math.max(green, minGreen), maxGreen), blue: blue } } /** * Adds color styles to colorbar jQuery object. * * @param {jQuery} $colorbar The colorbar jquery object. * @param {int} perc The percentage strength of the password. * @return {jQuery} */ function addColorBarStyle($colorbar, perc) { if (options.useColorBarImage) { $colorbar.css({ backgroundPosition: "0px -" + perc + "px", width: perc + '%' }); } else { var colors = calculateColorFromPercentage(perc); $colorbar.css({ 'background-image': 'none', 'background-color': 'rgb(' + colors.red.toString() + ', ' + colors.green.toString() + ', ' + colors.blue.toString() + ')', width: perc + '%' }); } return $colorbar; } /** * Initializes the plugin creating and binding the * required layers and events. * * @return {Password} Returns the Password instance. */ function init() { var shown = true; var $text = options.showText; var $percentage = options.showPercent; var $graybar = $('<div>').addClass('pass-graybar'); var $colorbar = $('<div>').addClass('pass-colorbar'); var $insert = $('<div>').addClass('pass-wrapper').append( $graybar.append($colorbar) ); $object.closest(options.closestSelector).addClass('pass-strength-visible'); if (options.animate) { $insert.css('display', 'none'); shown = false; $object.closest(options.closestSelector).removeClass('pass-strength-visible'); } if (options.showPercent) { $percentage = $('<span>').addClass('pass-percent').text('0%'); $insert.append($percentage); } if (options.showText) { $text = $('<span>').addClass('pass-text').html(options.enterPass); $insert.append($text); } $object.closest(options.closestSelector).append($insert); $object.keyup(function() { var field = options.field || ''; if (field) { field = $(field).val(); } var score = calculateScore($object.val(), field); $object.trigger('password.score', [score]); var perc = score < 0 ? 0 : score; $colorbar = addColorBarStyle($colorbar, perc); if (options.showPercent) { $percentage.html(perc + '%'); } if (options.showText) { var text = scoreText(score); if (!$object.val().length && score <= 0) { text = options.enterPass; } if ($text.html() !== $('<div>').html(text).html()) { $text.html(text); $object.trigger('password.text', [text, score]); } } }); if (options.animate) { $object.focus(function() { if (!shown) { $insert.slideDown(options.animateSpeed, function () { shown = true; $object.closest(options.closestSelector).addClass('pass-strength-visible'); }); } }); $object.blur(function() { if (!$object.val().length && shown) { $insert.slideUp(options.animateSpeed, function () { shown = false; $object.closest(options.closestSelector).removeClass('pass-strength-visible') }); } }); } return this; } return init.call(this); }; // Bind to jquery $.fn.password = function(options) { return this.each(function() { new Password($(this), options); }); }; })(jQuery);