diff --git a/resources/bootstrap/js/bootstrap-pwstrength.js b/resources/bootstrap/js/bootstrap-pwstrength.js new file mode 100644 index 0000000000..592b701c25 --- /dev/null +++ b/resources/bootstrap/js/bootstrap-pwstrength.js @@ -0,0 +1,812 @@ +/*! +* jQuery Password Strength plugin for Twitter Bootstrap +* Version: 2.0.0 +* +* Copyright (c) 2008-2013 Tane Piper +* Copyright (c) 2013 Alejandro Blanco +* Dual licensed under the MIT and GPL licenses. +* https://github.com/ablanco/jquery.pwstrength.bootstrap +*/ + +(function (jQuery) { +// Source: src/i18n.js + + + + +var i18n = {}; + +(function (i18n, i18next) { + 'use strict'; + + i18n.fallback = { + "wordLength": "Your password is too short", + "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; + }; +}(i18n, window.i18next)); + +// Source: src/rules.js + + + + +var rulesEngine = {}; + +try { + if (!jQuery && module && module.exports) { + var jQuery = require("jquery"), + jsdom = require("jsdom").jsdom; + jQuery = jQuery(jsdom().parentWindow); + } +} catch (ignore) {} + +(function ($, rulesEngine) { + "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.wordLength = 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.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) { + if (word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) || + (word.match(/([a-zA-Z])/) && word.match(/([0-9])/)) || + (word.match(/(.[!,@,#,$,%,\^,&,*,?,_,~])/) && word.match(/[a-zA-Z0-9_]/))) { + return score; + } + return 0; + }; + + 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) { + if (found) { return; } + var sequences = [seq, seq.split('').reverse().join('')]; + $.each(sequences, function (idx, 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(/[a-z]/) && score; + }; + + validation.wordUppercase = function (options, word, score) { + return word.match(/[A-Z]/) && 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) { + return word.match(/[!,@,#,$,%,\^,&,*,?,_,~]/) && score; + }; + + validation.wordTwoSpecialChar = function (options, word, score) { + return word.match(/(.*[!,@,#,$,%,\^,&,*,?,_,~].*[!,@,#,$,%,\^,&,*,?,_,~])/) && score; + }; + + validation.wordUpperLowerCombo = function (options, word, score) { + return word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && score; + }; + + validation.wordLetterNumberCombo = function (options, word, score) { + return word.match(/([a-zA-Z])/) && word.match(/([0-9])/) && score; + }; + + validation.wordLetterNumberCharCombo = function (options, word, score) { + return word.match(/([a-zA-Z0-9].*[!,@,#,$,%,\^,&,*,?,_,~])|([!,@,#,$,%,\^,&,*,?,_,~].*[a-zA-Z0-9])/) && score; + }; + + rulesEngine.validation = validation; + + rulesEngine.executeRules = function (options, word) { + var totalScore = 0; + + $.each(options.rules.activated, function (rule, active) { + if (active) { + var score = options.rules.scores[rule], + funct = rulesEngine.validation[rule], + result, + errorMessage; + + if (!$.isFunction(funct)) { + funct = options.rules.extra[rule]; + } + + if ($.isFunction(funct)) { + 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, rulesEngine)); + +try { + if (module && module.exports) { + module.exports = rulesEngine; + } +} catch (ignore) {} + +// Source: src/options.js + + + + +var defaultOptions = {}; + +defaultOptions.common = {}; +defaultOptions.common.minChar = 6; +defaultOptions.common.usernameField = "#username"; +defaultOptions.common.userInputs = [ + // Selectors for input fields with user input +]; +defaultOptions.common.onLoad = undefined; +defaultOptions.common.onKeyUp = undefined; +defaultOptions.common.zxcvbn = false; +defaultOptions.common.zxcvbnTerms = [ + // List of disrecommended words +]; +defaultOptions.common.debug = false; + +defaultOptions.rules = {}; +defaultOptions.rules.extra = {}; +defaultOptions.rules.scores = { + wordNotEmail: -100, + wordLength: -50, + wordSimilarToUsername: -100, + wordSequences: -20, + wordTwoCharacterClasses: 2, + wordRepetitions: -25, + wordLowercase: 1, + wordUppercase: 3, + wordOneNumber: 3, + wordThreeNumbers: 5, + wordOneSpecialChar: 3, + wordTwoSpecialChar: 5, + wordUpperLowerCombo: 2, + wordLetterNumberCombo: 2, + wordLetterNumberCharCombo: 2 +}; +defaultOptions.rules.activated = { + wordNotEmail: true, + wordLength: true, + wordSimilarToUsername: true, + wordSequences: true, + wordTwoCharacterClasses: false, + wordRepetitions: false, + wordLowercase: true, + wordUppercase: true, + wordOneNumber: true, + wordThreeNumbers: true, + wordOneSpecialChar: true, + wordTwoSpecialChar: true, + wordUpperLowerCombo: true, + wordLetterNumberCombo: true, + wordLetterNumberCharCombo: true +}; +defaultOptions.rules.raisePower = 1.4; + +defaultOptions.ui = {}; +defaultOptions.ui.bootstrap2 = false; +defaultOptions.ui.bootstrap4 = false; +defaultOptions.ui.colorClasses = [ + "danger", "danger", "danger", "warning", "warning", "success" +]; +defaultOptions.ui.showProgressBar = true; +defaultOptions.ui.progressBarEmptyPercentage = 1; +defaultOptions.ui.progressBarMinPercentage = 1; +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 = "