/*! * jQuery Password Strength plugin for Twitter Bootstrap * Version: 3.1.1 * * Copyright (c) 2008-2013 Tane Piper * Copyright (c) 2013 Alejandro Blanco * Dual licensed under the MIT and GPL licenses. */ (function (jQuery) { // Source: src/i18n.js // eslint-disable-next-line no-implicit-globals var i18n = {}; (function(i18next) { 'use strict'; i18n.fallback = { wordMinLength: 'Your password is too short', wordMaxLength: 'Your password is too long', wordInvalidChar: 'Your password contains an invalid character', wordNotEmail: 'Do not use your email as your password', wordSimilarToUsername: 'Your password cannot contain your username', wordTwoCharacterClasses: 'Use different character classes', wordRepetitions: 'Too many repetitions', wordSequences: 'Your password contains sequences', errorList: 'Errors:', veryWeak: 'Very Weak', weak: 'Weak', normal: 'Normal', medium: 'Medium', strong: 'Strong', veryStrong: 'Very Strong' }; i18n.t = function(key) { var result = ''; // Try to use i18next.com if (i18next) { result = i18next.t(key); } else { // Fallback to english result = i18n.fallback[key]; } return result === key ? '' : result; }; })(window.i18next); // Source: src/rules.js // eslint-disable-next-line no-implicit-globals var rulesEngine = {}; try { if (!jQuery && module && module.exports) { var jQuery = require('jquery'), jsdom = require('jsdom').jsdom; jQuery = jQuery(jsdom().defaultView); } } catch (ignore) { // Nothing to do } (function($) { 'use strict'; var validation = {}; rulesEngine.forbiddenSequences = [ '0123456789', 'abcdefghijklmnopqrstuvwxyz', 'qwertyuiop', 'asdfghjkl', 'zxcvbnm', '!@#$%^&*()_+' ]; validation.wordNotEmail = function(options, word, score) { if ( word.match( /^([\w!#$%&'*+\-/=?^`{|}~]+\.)*[\w!#$%&'*+\-/=?^`{|}~]+@((((([a-z0-9]{1}[a-z0-9-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(:\d{1,5})?)$/i ) ) { return score; } return 0; }; validation.wordMinLength = function(options, word, score) { var wordlen = word.length, lenScore = Math.pow(wordlen, options.rules.raisePower); if (wordlen < options.common.minChar) { lenScore = lenScore + score; } return lenScore; }; validation.wordMaxLength = function(options, word, score) { var wordlen = word.length, lenScore = Math.pow(wordlen, options.rules.raisePower); if (wordlen > options.common.maxChar) { return score; } return lenScore; }; validation.wordInvalidChar = function(options, word, score) { if (options.common.invalidCharsRegExp.test(word)) { return score; } return 0; }; validation.wordMinLengthStaticScore = function(options, word, score) { return word.length < options.common.minChar ? 0 : score; }; validation.wordMaxLengthStaticScore = function(options, word, score) { return word.length > options.common.maxChar ? 0 : score; }; validation.wordSimilarToUsername = function(options, word, score) { var username = $(options.common.usernameField).val(); if ( username && word .toLowerCase() .match( username .replace(/[-[\]/{}()*+=?:.\\^$|!,]/g, '\\$&') .toLowerCase() ) ) { return score; } return 0; }; validation.wordTwoCharacterClasses = function(options, word, score) { var specialCharRE = new RegExp( '(.' + options.rules.specialCharClass + ')', 'u' ); if ( word.match(/(\p{Ll}.*\p{Lu})|(\p{Lu}.*\p{Ll})/u) || (word.match(/(\p{Letter})/u) && word.match(/([0-9])/)) || (word.match(specialCharRE) && word.match(/[\p{Letter}0-9_]/u)) ) { return score; } return; }; validation.wordRepetitions = function(options, word, score) { if (word.match(/(.)\1\1/)) { return score; } return 0; }; validation.wordSequences = function(options, word, score) { var found = false, j; if (word.length > 2) { $.each(rulesEngine.forbiddenSequences, function(idx, seq) { var sequences; if (found) { return; } sequences = [ seq, seq .split('') .reverse() .join('') ]; $.each(sequences, function(ignore, sequence) { for (j = 0; j < word.length - 2; j += 1) { // iterate the word trough a sliding window of size 3: if ( sequence.indexOf( word.toLowerCase().substring(j, j + 3) ) > -1 ) { found = true; } } }); }); if (found) { return score; } } return 0; }; validation.wordLowercase = function(options, word, score) { return word.match(/\p{Ll}/u) && score; }; validation.wordUppercase = function(options, word, score) { return word.match(/\p{Lu}/u) && score; }; validation.word = function(options, word, score) { return word.match(/\p{Letter}/u) && score; }; validation.wordOneNumber = function(options, word, score) { return word.match(/\d+/) && score; }; validation.wordThreeNumbers = function(options, word, score) { return word.match(/(.*[0-9].*[0-9].*[0-9])/) && score; }; validation.wordOneSpecialChar = function(options, word, score) { var specialCharRE = new RegExp(options.rules.specialCharClass, 'u'); return word.match(specialCharRE) && score; }; validation.wordTwoSpecialChar = function(options, word, score) { var twoSpecialCharRE = new RegExp( '(.*' + options.rules.specialCharClass + '.*' + options.rules.specialCharClass + ')', 'u' ); return word.match(twoSpecialCharRE) && score; }; validation.wordUpperLowerCombo = function(options, word, score) { return word.match(/(\p{Ll}.*\p{Lu})|(\p{Lu}.*\p{Ll})/u) && score; }; validation.wordLetterNumberCombo = function(options, word, score) { return word.match(/([\p{Letter}])/u) && word.match(/([0-9])/) && score; }; validation.wordLetterNumberCharCombo = function(options, word, score) { var letterNumberCharComboRE = new RegExp( '([\p{Letter}0-9].*' + options.rules.specialCharClass + ')|(' + options.rules.specialCharClass + '.*[\p{Letter}0-9])', 'u' ); return word.match(letterNumberCharComboRE) && score; }; validation.wordIsACommonPassword = function(options, word, score) { if ($.inArray(word, options.rules.commonPasswords) >= 0) { return score; } return 0; }; rulesEngine.validation = validation; rulesEngine.executeRules = function(options, word) { var totalScore = 0; $.each(options.rules.activated, function(rule, active) { var score, funct, result, errorMessage; if (active) { score = options.rules.scores[rule]; funct = rulesEngine.validation[rule]; if (typeof funct !== 'function') { funct = options.rules.extra[rule]; } if (typeof funct === 'function') { result = funct(options, word, score); if (result) { totalScore += result; } if (result < 0 || (!$.isNumeric(result) && !result)) { errorMessage = options.ui.spanError(options, rule); if (errorMessage.length > 0) { options.instances.errors.push(errorMessage); } } } } }); return totalScore; }; })(jQuery); try { if (module && module.exports) { module.exports = rulesEngine; } } catch (ignore) { // Nothing to do } // Source: src/options.js // eslint-disable-next-line no-implicit-globals var defaultOptions = {}; defaultOptions.common = {}; defaultOptions.common.minChar = 6; defaultOptions.common.maxChar = 20; defaultOptions.common.usernameField = '#username'; defaultOptions.common.invalidCharsRegExp = new RegExp(/[\s,'"]/); defaultOptions.common.userInputs = [ // Selectors for input fields with user input ]; defaultOptions.common.onLoad = undefined; defaultOptions.common.onKeyUp = undefined; defaultOptions.common.onScore = undefined; defaultOptions.common.zxcvbn = false; defaultOptions.common.zxcvbnTerms = [ // List of disrecommended words ]; defaultOptions.common.events = ['keyup', 'change', 'paste']; defaultOptions.common.debug = false; defaultOptions.rules = {}; defaultOptions.rules.extra = {}; defaultOptions.rules.scores = { wordNotEmail: -100, wordMinLength: -50, wordMaxLength: -50, wordInvalidChar: -100, wordSimilarToUsername: -100, wordSequences: -20, wordTwoCharacterClasses: 2, wordRepetitions: -25, wordLowercase: 1, word: 1, wordUppercase: 3, wordOneNumber: 3, wordThreeNumbers: 5, wordOneSpecialChar: 3, wordTwoSpecialChar: 5, wordUpperLowerCombo: 2, wordLetterNumberCombo: 2, wordLetterNumberCharCombo: 2, wordIsACommonPassword: -100 }; defaultOptions.rules.activated = { wordNotEmail: true, wordMinLength: true, wordMaxLength: false, wordInvalidChar: false, wordSimilarToUsername: true, wordSequences: true, wordTwoCharacterClasses: true, wordRepetitions: true, wordLowercase: true, word: true, wordUppercase: true, wordOneNumber: true, wordThreeNumbers: true, wordOneSpecialChar: true, wordTwoSpecialChar: true, wordUpperLowerCombo: true, wordLetterNumberCombo: true, wordLetterNumberCharCombo: true, wordIsACommonPassword: true }; defaultOptions.rules.raisePower = 1.4; defaultOptions.rules.specialCharClass = "(?=.*?[^\\p{Letter}\\s0-9])"; //'[!,@,#,$,%,^,&,*,?,_,~]'; // List taken from https://github.com/danielmiessler/SecLists (MIT License) defaultOptions.rules.commonPasswords = [ '123456', 'password', '12345678', 'qwerty', '123456789', '12345', '1234', '111111', '1234567', 'dragon', '123123', 'baseball', 'abc123', 'football', 'monkey', 'letmein', '696969', 'shadow', 'master', '666666', 'qwertyuiop', '123321', 'mustang', '1234567890', 'michael', '654321', 'pussy', 'superman', '1qaz2wsx', '7777777', 'fuckyou', '121212', '000000', 'qazwsx', '123qwe', 'killer', 'trustno1', 'jordan', 'jennifer', 'zxcvbnm', 'asdfgh', 'hunter', 'buster', 'soccer', 'harley', 'batman', 'andrew', 'tigger', 'sunshine', 'iloveyou', 'fuckme', '2000', 'charlie', 'robert', 'thomas', 'hockey', 'ranger', 'daniel', 'starwars', 'klaster', '112233', 'george', 'asshole', 'computer', 'michelle', 'jessica', 'pepper', '1111', 'zxcvbn', '555555', '11111111', '131313', 'freedom', '777777', 'pass', 'fuck', 'maggie', '159753', 'aaaaaa', 'ginger', 'princess', 'joshua', 'cheese', 'amanda', 'summer', 'love', 'ashley', '6969', 'nicole', 'chelsea', 'biteme', 'matthew', 'access', 'yankees', '987654321', 'dallas', 'austin', 'thunder', 'taylor', 'matrix' ]; defaultOptions.ui = {}; defaultOptions.ui.bootstrap2 = false; defaultOptions.ui.bootstrap3 = false; defaultOptions.ui.colorClasses = [ 'danger', 'danger', 'danger', 'warning', 'warning', 'success' ]; defaultOptions.ui.showProgressBar = true; defaultOptions.ui.progressBarEmptyPercentage = 1; defaultOptions.ui.progressBarMinWidth = 1; defaultOptions.ui.progressBarMinPercentage = 1; defaultOptions.ui.progressExtraCssClasses = ''; defaultOptions.ui.progressBarExtraCssClasses = ''; defaultOptions.ui.showPopover = false; defaultOptions.ui.popoverPlacement = 'bottom'; defaultOptions.ui.showStatus = false; defaultOptions.ui.spanError = function(options, key) { 'use strict'; var text = options.i18n.t(key); if (!text) { return ''; } return '' + text + ''; }; defaultOptions.ui.popoverError = function(options) { 'use strict'; var errors = options.instances.errors, errorsTitle = options.i18n.t('errorList'), message = '