1/*! 2* jQuery Password Strength plugin for Twitter Bootstrap 3* Version: 3.0.1 4* 5* Copyright (c) 2008-2013 Tane Piper 6* Copyright (c) 2013 Alejandro Blanco 7* Dual licensed under the MIT and GPL licenses. 8*/ 9 10(function (jQuery) { 11// Source: src/i18n.js 12 13 14 15 16var i18n = {}; 17 18(function (i18n, i18next) { 19 'use strict'; 20 21 i18n.fallback = { 22 "wordMinLength": "Your password is too short", 23 "wordMaxLength": "Your password is too long", 24 "wordInvalidChar": "Your password contains an invalid character", 25 "wordNotEmail": "Do not use your email as your password", 26 "wordSimilarToUsername": "Your password cannot contain your username", 27 "wordTwoCharacterClasses": "Use different character classes", 28 "wordRepetitions": "Too many repetitions", 29 "wordSequences": "Your password contains sequences", 30 "errorList": "Errors:", 31 "veryWeak": "Very Weak", 32 "weak": "Weak", 33 "normal": "Normal", 34 "medium": "Medium", 35 "strong": "Strong", 36 "veryStrong": "Very Strong" 37 }; 38 39 i18n.t = function (key) { 40 var result = ''; 41 42 // Try to use i18next.com 43 if (i18next) { 44 result = i18next.t(key); 45 } else { 46 // Fallback to english 47 result = i18n.fallback[key]; 48 } 49 50 return result === key ? '' : result; 51 }; 52}(i18n, window.i18next)); 53 54// Source: src/rules.js 55 56 57 58 59var rulesEngine = {}; 60 61try { 62 if (!jQuery && module && module.exports) { 63 var jQuery = require("jquery"), 64 jsdom = require("jsdom").jsdom; 65 jQuery = jQuery(jsdom().defaultView); 66 } 67} catch (ignore) {} 68 69(function ($, rulesEngine) { 70 "use strict"; 71 var validation = {}; 72 73 rulesEngine.forbiddenSequences = [ 74 "0123456789", "abcdefghijklmnopqrstuvwxyz", "qwertyuiop", "asdfghjkl", 75 "zxcvbnm", "!@#$%^&*()_+" 76 ]; 77 78 validation.wordNotEmail = function (options, word, score) { 79 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)) { 80 return score; 81 } 82 return 0; 83 }; 84 85 validation.wordMinLength = function (options, word, score) { 86 var wordlen = word.length, 87 lenScore = Math.pow(wordlen, options.rules.raisePower); 88 if (wordlen < options.common.minChar) { 89 lenScore = (lenScore + score); 90 } 91 return lenScore; 92 }; 93 94 validation.wordMaxLength = function (options, word, score) { 95 var wordlen = word.length, 96 lenScore = Math.pow(wordlen, options.rules.raisePower); 97 if (wordlen > options.common.maxChar) { 98 return score; 99 } 100 return lenScore; 101 }; 102 103 validation.wordInvalidChar = function (options, word, score) { 104 if (options.common.invalidCharsRegExp.test(word)) { 105 return score; 106 } 107 return 0; 108 }; 109 110 validation.wordMinLengthStaticScore = function (options, word, score) { 111 return word.length < options.common.minChar ? 0 : score; 112 }; 113 114 validation.wordMaxLengthStaticScore = function (options, word, score) { 115 return word.length > options.common.maxChar ? 0 : score; 116 }; 117 118 119 validation.wordSimilarToUsername = function (options, word, score) { 120 var username = $(options.common.usernameField).val(); 121 if (username && word.toLowerCase().match(username.replace(/[\-\[\]\/\{\}\(\)\*\+\=\?\:\.\\\^\$\|\!\,]/g, "\\$&").toLowerCase())) { 122 return score; 123 } 124 return 0; 125 }; 126 127 validation.wordTwoCharacterClasses = function (options, word, score) { 128 if (word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) || 129 (word.match(/([a-zA-Z])/) && word.match(/([0-9])/)) || 130 (word.match(/(.[!,@,#,$,%,\^,&,*,?,_,~])/) && word.match(/[a-zA-Z0-9_]/))) { 131 return score; 132 } 133 return 0; 134 }; 135 136 validation.wordRepetitions = function (options, word, score) { 137 if (word.match(/(.)\1\1/)) { return score; } 138 return 0; 139 }; 140 141 validation.wordSequences = function (options, word, score) { 142 var found = false, 143 j; 144 if (word.length > 2) { 145 $.each(rulesEngine.forbiddenSequences, function (idx, seq) { 146 if (found) { return; } 147 var sequences = [seq, seq.split('').reverse().join('')]; 148 $.each(sequences, function (idx, sequence) { 149 for (j = 0; j < (word.length - 2); j += 1) { // iterate the word trough a sliding window of size 3: 150 if (sequence.indexOf(word.toLowerCase().substring(j, j + 3)) > -1) { 151 found = true; 152 } 153 } 154 }); 155 }); 156 if (found) { return score; } 157 } 158 return 0; 159 }; 160 161 validation.wordLowercase = function (options, word, score) { 162 return word.match(/[a-z]/) && score; 163 }; 164 165 validation.wordUppercase = function (options, word, score) { 166 return word.match(/[A-Z]/) && score; 167 }; 168 169 validation.wordOneNumber = function (options, word, score) { 170 return word.match(/\d+/) && score; 171 }; 172 173 validation.wordThreeNumbers = function (options, word, score) { 174 return word.match(/(.*[0-9].*[0-9].*[0-9])/) && score; 175 }; 176 177 validation.wordOneSpecialChar = function (options, word, score) { 178 return word.match(/[!,@,#,$,%,\^,&,*,?,_,~]/) && score; 179 }; 180 181 validation.wordTwoSpecialChar = function (options, word, score) { 182 return word.match(/(.*[!,@,#,$,%,\^,&,*,?,_,~].*[!,@,#,$,%,\^,&,*,?,_,~])/) && score; 183 }; 184 185 validation.wordUpperLowerCombo = function (options, word, score) { 186 return word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && score; 187 }; 188 189 validation.wordLetterNumberCombo = function (options, word, score) { 190 return word.match(/([a-zA-Z])/) && word.match(/([0-9])/) && score; 191 }; 192 193 validation.wordLetterNumberCharCombo = function (options, word, score) { 194 return word.match(/([a-zA-Z0-9].*[!,@,#,$,%,\^,&,*,?,_,~])|([!,@,#,$,%,\^,&,*,?,_,~].*[a-zA-Z0-9])/) && score; 195 }; 196 197 validation.wordIsACommonPassword = function (options, word, score) { 198 if ($.inArray(word, options.rules.commonPasswords) >= 0) { 199 return score; 200 } 201 return 0; 202 }; 203 204 rulesEngine.validation = validation; 205 206 rulesEngine.executeRules = function (options, word) { 207 var totalScore = 0; 208 209 $.each(options.rules.activated, function (rule, active) { 210 if (active) { 211 var score = options.rules.scores[rule], 212 funct = rulesEngine.validation[rule], 213 result, 214 errorMessage; 215 216 if (!$.isFunction(funct)) { 217 funct = options.rules.extra[rule]; 218 } 219 220 if ($.isFunction(funct)) { 221 result = funct(options, word, score); 222 if (result) {
223 totalScore += result; 224 } 225 if (result < 0 || (!$.isNumeric(result) && !result)) { 226 errorMessage = options.ui.spanError(options, rule); 227 if (errorMessage.length > 0) { 228 options.instances.errors.push(errorMessage); 229 } 230 } 231 } 232 } 233 }); 234 235 return totalScore; 236 }; 237}(jQuery, rulesEngine)); 238 239try { 240 if (module && module.exports) { 241 module.exports = rulesEngine; 242 } 243} catch (ignore) {} 244 245// Source: src/options.js 246 247 248 249 250var defaultOptions = {}; 251 252defaultOptions.common = {}; 253defaultOptions.common.minChar = 6; 254defaultOptions.common.maxChar = 20; 255defaultOptions.common.usernameField = "#username"; 256defaultOptions.common.invalidCharsRegExp = new RegExp(/[\s,'"]/); 257defaultOptions.common.userInputs = [ 258 // Selectors for input fields with user input 259]; 260defaultOptions.common.onLoad = undefined; 261defaultOptions.common.onKeyUp = undefined; 262defaultOptions.common.onScore = undefined; 263defaultOptions.common.zxcvbn = false; 264defaultOptions.common.zxcvbnTerms = [ 265 // List of disrecommended words 266]; 267defaultOptions.common.events = ["keyup", "change", "paste"]; 268defaultOptions.common.debug = false; 269 270defaultOptions.rules = {}; 271defaultOptions.rules.extra = {}; 272defaultOptions.rules.scores = { 273 wordNotEmail: -100, 274 wordMinLength: -50, 275 wordMaxLength: -50, 276 wordInvalidChar: -100, 277 wordSimilarToUsername: -100, 278 wordSequences: -20, 279 wordTwoCharacterClasses: 2, 280 wordRepetitions: -25, 281 wordLowercase: 1, 282 wordUppercase: 3, 283 wordOneNumber: 3, 284 wordThreeNumbers: 5, 285 wordOneSpecialChar: 3, 286 wordTwoSpecialChar: 5, 287 wordUpperLowerCombo: 2, 288 wordLetterNumberCombo: 2, 289 wordLetterNumberCharCombo: 2, 290 wordIsACommonPassword: -100 291}; 292defaultOptions.rules.activated = { 293 wordNotEmail: true, 294 wordMinLength: true, 295 wordMaxLength: false, 296 wordInvalidChar: false, 297 wordSimilarToUsername: true, 298 wordSequences: true, 299 wordTwoCharacterClasses: true, 300 wordRepetitions: true, 301 wordLowercase: true, 302 wordUppercase: true, 303 wordOneNumber: true, 304 wordThreeNumbers: true, 305 wordOneSpecialChar: true, 306 wordTwoSpecialChar: true, 307 wordUpperLowerCombo: true, 308 wordLetterNumberCombo: true, 309 wordLetterNumberCharCombo: true, 310 wordIsACommonPassword: true 311}; 312defaultOptions.rules.raisePower = 1.4; 313// List taken from https://github.com/danielmiessler/SecLists (MIT License) 314defaultOptions.rules.commonPasswords = [ 315 '123456', 316 'password', 317 '12345678', 318 'qwerty', 319 '123456789', 320 '12345', 321 '1234', 322 '111111', 323 '1234567', 324 'dragon', 325 '123123', 326 'baseball', 327 'abc123', 328 'football', 329 'monkey', 330 'letmein', 331 '696969', 332 'shadow', 333 'master', 334 '666666', 335 'qwertyuiop', 336 '123321', 337 'mustang', 338 '1234567890', 339 'michael', 340 '654321', 341 'pussy', 342 'superman', 343 '1qaz2wsx', 344 '7777777', 345 'fuckyou', 346 '121212', 347 '000000', 348 'qazwsx', 349 '123qwe', 350 'killer', 351 'trustno1', 352 'jordan', 353 'jennifer', 354 'zxcvbnm', 355 'asdfgh', 356 'hunter', 357 'buster', 358 'soccer', 359 'harley', 360 'batman', 361 'andrew', 362 'tigger', 363 'sunshine', 364 'iloveyou', 365 'fuckme', 366 '2000', 367 'charlie', 368 'robert', 369 'thomas', 370 'hockey', 371 'ranger', 372 'daniel', 373 'starwars', 374 'klaster', 375 '112233', 376 'george', 377 'asshole', 378 'computer', 379 'michelle', 380 'jessica', 381 'pepper', 382 '1111', 383 'zxcvbn', 384 '555555', 385 '11111111', 386 '131313', 387 'freedom', 388 '777777', 389 'pass', 390 'fuck', 391 'maggie', 392 '159753', 393 'aaaaaa', 394 'ginger', 395 'princess', 396 'joshua', 397 'cheese', 398 'amanda', 399 'summer', 400 'love', 401 'ashley', 402 '6969', 403 'nicole', 404 'chelsea', 405 'biteme',
406 'matthew', 407 'access', 408 'yankees', 409 '987654321', 410 'dallas', 411 'austin', 412 'thunder', 413 'taylor', 414 'matrix' 415]; 416 417defaultOptions.ui = {}; 418defaultOptions.ui.bootstrap2 = false; 419defaultOptions.ui.bootstrap3 = false; 420defaultOptions.ui.colorClasses = [ 421 "danger", "danger", "warning", "warning", "success", "success" 422]; 423defaultOptions.ui.showProgressBar = true; 424defaultOptions.ui.progressBarEmptyPercentage = 1; 425defaultOptions.ui.progressBarMinPercentage = 1; 426defaultOptions.ui.progressExtraCssClasses = ''; 427defaultOptions.ui.progressBarExtraCssClasses = ''; 428defaultOptions.ui.showPopover = false; 429defaultOptions.ui.popoverPlacement = "bottom"; 430defaultOptions.ui.showStatus = false; 431defaultOptions.ui.spanError = function (options, key) { 432 "use strict"; 433 var text = options.i18n.t(key); 434 if (!text) { return ''; } 435 return '<span style="color: #d52929">' + text + '</span>'; 436}; 437defaultOptions.ui.popoverError = function (options) { 438 "use strict"; 439 var errors = options.instances.errors, 440 errorsTitle = options.i18n.t("errorList"), 441 message = "<div>" + errorsTitle + "<ul class='error-list' style='margin-bottom: 0;'>"; 442 443 jQuery.each(errors, function (idx, err) { 444 message += "<li>" + err + "</li>"; 445 }); 446 message += "</ul></div>"; 447 return message; 448}; 449defaultOptions.ui.showVerdicts = true; 450defaultOptions.ui.showVerdictsInsideProgressBar = false; 451defaultOptions.ui.useVerdictCssClass = false; 452defaultOptions.ui.showErrors = false; 453defaultOptions.ui.showScore = false; 454defaultOptions.ui.container = undefined; 455defaultOptions.ui.viewports = { 456 progress: undefined, 457 verdict: undefined, 458 errors: undefined, 459 score: undefined 460}; 461defaultOptions.ui.scores = [0, 14, 26, 38, 50]; 462 463defaultOptions.i18n = {}; 464defaultOptions.i18n.t = i18n.t; 465 466// Source: src/ui.js 467 468 469 470 471var ui = {}; 472 473(function ($, ui) { 474 "use strict"; 475 476 var statusClasses = ["error", "warning", "success"], 477 verdictKeys = [ 478 "veryWeak", "weak", "normal", "medium", "strong", "veryStrong" 479 ]; 480 481 ui.getContainer = function (options, $el) { 482 var $container; 483 484 $container = $(options.ui.container); 485 if (!($container && $container.length === 1)) { 486 $container = $el.parent(); 487 } 488 return $container; 489 }; 490 491 ui.findElement = function ($container, viewport, cssSelector) { 492 if (viewport) { 493 return $container.find(viewport).find(cssSelector); 494 } 495 return $container.find(cssSelector); 496 }; 497 498 ui.getUIElements = function (options, $el) { 499 var $container, result; 500 501 if (options.instances.viewports) { 502 return options.instances.viewports; 503 } 504 505 $container = ui.getContainer(options, $el); 506 507 result = {}; 508 result.$progressbar = ui.findElement($container, options.ui.viewports.progress, "div.progress"); 509 if (options.ui.showVerdictsInsideProgressBar) { 510 result.$verdict = result.$progressbar.find("span.password-verdict"); 511 } 512 513 if (!options.ui.showPopover) { 514 if (!options.ui.showVerdictsInsideProgressBar) { 515 result.$verdict = ui.findElement($container, options.ui.viewports.verdict, "span.password-verdict"); 516 } 517 result.$errors = ui.findElement($container, options.ui.viewports.errors, "ul.error-list"); 518 } 519 result.$score = ui.findElement($container, options.ui.viewports.score, 520 "span.password-score"); 521 522 options.instances.viewports = result; 523 return result; 524 }; 525 526 ui.initProgressBar = function (options, $el) { 527 var $container = ui.getContainer(options, $el), 528 progressbar = "<div class='progress "; 529 530 if (options.ui.bootstrap2) { 531 // Boostrap 2 532 progressbar += options.ui.progressBarExtraCssClasses + 533 "'><div class='"; 534 } else { 535 // Bootstrap 3 & 4
536 progressbar += options.ui.progressExtraCssClasses + "'><div class='" + 537 options.ui.progressBarExtraCssClasses + " progress-"; 538 } 539 progressbar += "bar'>"; 540 541 if (options.ui.showVerdictsInsideProgressBar) { 542 progressbar += "<span class='password-verdict'></span>"; 543 } 544 545 progressbar += "</div></div>"; 546 547 if (options.ui.viewports.progress) { 548 $container.find(options.ui.viewports.progress).append(progressbar); 549 } else { 550 $(progressbar).insertAfter($el); 551 } 552 }; 553 554 ui.initHelper = function (options, $el, html, viewport) { 555 var $container = ui.getContainer(options, $el); 556 if (viewport) { 557 $container.find(viewport).append(html); 558 } else { 559 $(html).insertAfter($el); 560 } 561 }; 562 563 ui.initVerdict = function (options, $el) { 564 ui.initHelper(options, $el, "<span class='password-verdict'></span>", 565 options.ui.viewports.verdict); 566 }; 567 568 ui.initErrorList = function (options, $el) { 569 ui.initHelper(options, $el, "<ul class='error-list'></ul>", 570 options.ui.viewports.errors); 571 }; 572 573 ui.initScore = function (options, $el) { 574 ui.initHelper(options, $el, "<span class='password-score'></span>", 575 options.ui.viewports.score); 576 }; 577 578 ui.initPopover = function (options, $el) { 579 $el.popover("destroy"); 580 $el.popover({ 581 html: true, 582 placement: options.ui.popoverPlacement, 583 trigger: "manual", 584 content: " " 585 }); 586 }; 587 588 ui.initUI = function (options, $el) { 589 if (options.ui.showPopover) { 590 ui.initPopover(options, $el); 591 } else { 592 if (options.ui.showErrors) { ui.initErrorList(options, $el); } 593 if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) { 594 ui.initVerdict(options, $el); 595 } 596 } 597 if (options.ui.showProgressBar) { 598 ui.initProgressBar(options, $el); 599 } 600 if (options.ui.showScore) { 601 ui.initScore(options, $el); 602 } 603 }; 604 605 ui.updateProgressBar = function (options, $el, cssClass, percentage) { 606 var $progressbar = ui.getUIElements(options, $el).$progressbar, 607 $bar = $progressbar.find(".progress-bar"), 608 cssPrefix = "progress-"; 609 610 if (options.ui.bootstrap2) { 611 $bar = $progressbar.find(".bar"); 612 cssPrefix = ""; 613 } 614 615 $.each(options.ui.colorClasses, function (idx, value) { 616 //if (options.ui.bootstrap2 || options.ui.bootstrap3) { 617 if (options.ui.bootstrap2) { 618 $bar.removeClass(cssPrefix + "bar-" + value); 619 } else { 620 $bar.removeClass("bg-" + value); 621 } 622 }); 623 //if (options.ui.bootstrap2 || options.ui.bootstrap3) { 624 if (options.ui.bootstrap2) { 625 $bar.addClass(cssPrefix + "bar-" + options.ui.colorClasses[cssClass]); 626 } else { 627 $bar.addClass("bg-" + options.ui.colorClasses[cssClass]); 628 } 629 $bar.css("width", percentage + '%'); 630 }; 631 632 ui.updateVerdict = function (options, $el, cssClass, text) { 633 var $verdict = ui.getUIElements(options, $el).$verdict; 634 $verdict.removeClass(options.ui.colorClasses.join(' ')); 635 if (cssClass > -1) { 636 $verdict.addClass(options.ui.colorClasses[cssClass]); 637 } 638 if (options.ui.showVerdictsInsideProgressBar) { 639 $verdict.css('white-space', 'nowrap'); 640 } 641 $verdict.html(text); 642 }; 643 644 ui.updateErrors = function (options, $el, remove) { 645 var $errors = ui.getUIElements(options, $el).$errors, 646 html = ""; 647 648 if (!remove) { 649 $.each(options.instances.errors, function (idx, err) { 650 html += "<li>" + err + "</li>"; 651 }); 652 } 653 $errors.html(html); 654 }; 655 656 ui.updateScore = function (options, $el, score, remove) { 657 var $score = ui.getUIElements(options, $el).$score, 658 html = ""; 659 660 if (!remove) { html = score.toFixed(2); } 661 $score.html(html); 662 }; 663 664 ui.updatePopover = function (options, $el, verdictText, remove) { 665 var popover = $el.data("bs.popover"), 666 html = "", 667 hide = true; 668 669 if (options.ui.showVerdicts && 670 !options.ui.showVerdictsInsideProgressBar && 671 verdictText.length > 0) { 672 html = "<h5><span class='password-verdict'>" + verdictText + 673 "</span></h5>"; 674 hide = false; 675 } 676 if (options.ui.showErrors) { 677 if (options.instances.errors.length > 0) { 678 hide = false; 679 } 680 html += options.ui.popoverError(options); 681 } 682 683 if (hide || remove) { 684 $el.popover("hide"); 685 return; 686 } 687 688 if (options.ui.bootstrap2) { popover = $el.data("popover"); } 689 690 if (popover.$arrow && popover.$arrow.parents("body").length > 0) { 691 $el.find("+ .popover .popover-content").html(html); 692 } else { 693 // It's hidden 694 if (options.ui.bootstrap2 || options.ui.bootstrap3) { 695 popover.options.content = html; 696 } else { 697 popover.config.content = html; 698 } 699 $el.popover("show"); 700 } 701 }; 702 703 ui.updateFieldStatus = function (options, $el, cssClass, remove) { 704 var $target = $el; 705 706 if (options.ui.bootstrap2) { 707 $target = $el.parents(".control-group").first(); 708 } else if (options.ui.bootstrap3) { 709 $target = $el.parents(".form-group").first(); 710 } 711 712 $.each(statusClasses, function (idx, css) { 713 if (options.ui.bootstrap3) { 714 css = "has-" + css; 715 } else if (!options.ui.bootstrap2) { // BS4 716 if (css === "error") { css = "danger"; } 717 css = "border-" + css; 718 } 719 $target.removeClass(css); 720 }); 721 722 if (remove) { return; } 723 724 cssClass = statusClasses[Math.floor(cssClass / 2)]; 725 if (options.ui.bootstrap3) { 726 cssClass = "has-" + cssClass; 727 } else if (!options.ui.bootstrap2) { // BS4 728 if (cssClass === "error") { cssClass = "danger"; } 729 cssClass = "border-" + cssClass; 730 } 731 $target.addClass(cssClass); 732 }; 733 734 ui.percentage = function (options, score, maximun) { 735 var result = Math.floor(100 * score / maximun), 736 min = options.ui.progressBarMinPercentage; 737 738 result = result <= min ? min : result; 739 result = result > 100 ? 100 : result; 740 return result; 741 }; 742 743 ui.getVerdictAndCssClass = function (options, score) { 744 var level, verdict; 745 746 if (score === undefined) { return ['', 0]; } 747 748 if (score <= options.ui.scores[0]) { 749 level = 0; 750 } else if (score < options.ui.scores[1]) { 751 level = 1; 752 } else if (score < options.ui.scores[2]) { 753 level = 2; 754 } else if (score < options.ui.scores[3]) { 755 level = 3; 756 } else if (score < options.ui.scores[4]) { 757 level = 4; 758 } else { 759 level = 5; 760 } 761 762 verdict = verdictKeys[level]; 763 764 return [options.i18n.t(verdict), level]; 765 }; 766 767 ui.updateUI = function (options, $el, score) { 768 var cssClass, barPercentage, verdictText, verdictCssClass; 769 770 cssClass = ui.getVerdictAndCssClass(options, score); 771 verdictText = score === 0 ? '' : cssClass[0]; 772 cssClass = cssClass[1]; 773 verdictCssClass = options.ui.useVerdictCssClass ? cssClass : -1; 774 775 if (options.ui.showProgressBar) { 776 if (score === undefined) { 777 barPercentage = options.ui.progressBarEmptyPercentage; 778 } else { 779 barPercentage = ui.percentage(options, score, options.ui.scores[4]); 780 } 781 ui.updateProgressBar(options, $el, cssClass, barPercentage); 782 if (options.ui.showVerdictsInsideProgressBar) { 783 ui.updateVerdict(options, $el, verdictCssClass, verdictText); 784 } 785 } 786 787 if (options.ui.showStatus) { 788 ui.updateFieldStatus(options, $el, cssClass, score === undefined); 789 } 790 791 if (options.ui.showPopover) { 792 ui.updatePopover(options, $el, verdictText, score === undefined); 793 } else { 794 if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) { 795 ui.updateVerdict(options, $el, verdictCssClass, verdictText); 796 } 797 if (options.ui.showErrors) { 798 ui.updateErrors(options, $el, score === undefined); 799 } 800 } 801 802 if (options.ui.showScore) { 803 ui.updateScore(options, $el, score, score === undefined); 804 } 805 }; 806}(jQuery, ui)); 807 808// Source: src/methods.js 809 810 811 812 813var methods = {}; 814 815(function ($, methods) { 816 "use strict"; 817 var onKeyUp, onPaste, applyToAll; 818 819 onKeyUp = function (event) { 820 var $el = $(event.target), 821 options = $el.data("pwstrength-bootstrap"), 822 word = $el.val(), 823 userInputs, 824 verdictText, 825 verdictLevel, 826 score; 827 828 if (options === undefined) { return; } 829 830 options.instances.errors = []; 831 if (word.length === 0) { 832 score = undefined; 833 } else { 834 if (options.common.zxcvbn) { 835 userInputs = []; 836 $.each(options.common.userInputs.concat([options.common.usernameField]), function (idx, selector) { 837 var value = $(selector).val(); 838 if (value) { userInputs.push(value); } 839 }); 840 userInputs = userInputs.concat(options.common.zxcvbnTerms); 841 score = zxcvbn(word, userInputs).guesses; 842 score = Math.log(score) * Math.LOG2E; 843 } else { 844 score = rulesEngine.executeRules(options, word); 845 } 846 if ($.isFunction(options.common.onScore)) { 847 score = options.common.onScore(options, word, score); 848 } 849 } 850 ui.updateUI(options, $el, score); 851 verdictText = ui.getVerdictAndCssClass(options, score); 852 verdictLevel = verdictText[1]; 853 verdictText = verdictText[0]; 854 855 if (options.common.debug) { 856 console.log(score + ' - ' + verdictText); 857 } 858 859 if ($.isFunction(options.common.onKeyUp)) { 860 options.common.onKeyUp(event, { 861 score: score, 862 verdictText: verdictText, 863 verdictLevel: verdictLevel 864 }); 865 } 866 }; 867 868 onPaste = function (event) { 869 // This handler is necessary because the paste event fires before the 870 // content is actually in the input, so we cannot read its value right 871 // away. Therefore, the timeouts. 872 var $el = $(event.target), 873 word = $el.val(), 874 tries = 0, 875 callback; 876 877 callback = function () { 878 var newWord = $el.val(); 879 880 if (newWord !== word) { 881 onKeyUp(event); 882 } else if (tries < 3) { 883 tries += 1; 884 setTimeout(callback, 100); 885 } 886 }; 887 888 setTimeout(callback, 100); 889 }; 890 891 methods.init = function (settings) { 892 this.each(function (idx, el) { 893 // Make it deep extend (first param) so it extends also the 894 // rules and other inside objects 895 var clonedDefaults = $.extend(true, {}, defaultOptions), 896 localOptions = $.extend(true, clonedDefaults, settings), 897 $el = $(el); 898 899 localOptions.instances = {}; 900 $el.data("pwstrength-bootstrap", localOptions); 901 902 $.each(localOptions.common.events, function (idx, eventName) { 903 var handler = eventName === "paste" ? onPaste : onKeyUp; 904 $el.on(eventName, handler); 905 }); 906 907 ui.initUI(localOptions, $el); 908 $el.trigger("keyup"); 909 910 if ($.isFunction(localOptions.common.onLoad)) { 911 localOptions.common.onLoad(); 912 } 913 }); 914 915 return this; 916 }; 917 918 methods.destroy = function () { 919 this.each(function (idx, el) { 920 var $el = $(el), 921 options = $el.data("pwstrength-bootstrap"), 922 elements = ui.getUIElements(options, $el); 923 elements.$progressbar.remove(); 924 elements.$verdict.remove(); 925 elements.$errors.remove(); 926 $el.removeData("pwstrength-bootstrap"); 927 }); 928 }; 929 930 methods.forceUpdate = function () { 931 this.each(function (idx, el) { 932 var event = { target: el }; 933 onKeyUp(event); 934 }); 935 }; 936 937 methods.addRule = function (name, method, score, active) { 938 this.each(function (idx, el) { 939 var options = $(el).data("pwstrength-bootstrap"); 940 941 options.rules.activated[name] = active; 942 options.rules.scores[name] = score; 943 options.rules.extra[name] = method; 944 }); 945 }; 946 947 applyToAll = function (rule, prop, value) { 948 this.each(function (idx, el) { 949 $(el).data("pwstrength-bootstrap").rules[prop][rule] = value; 950 }); 951 }; 952 953 methods.changeScore = function (rule, score) { 954 applyToAll.call(this, rule, "scores", score); 955 }; 956 957 methods.ruleActive = function (rule, active) { 958 applyToAll.call(this, rule, "activated", active); 959 }; 960 961 methods.ruleIsMet = function (rule) { 962 if ($.isFunction(rulesEngine.validation[rule])) { 963 if (rule === "wordMinLength") { 964 rule = "wordMinLengthStaticScore"; 965 } else if (rule === "wordMaxLength") { 966 rule = "wordMaxLengthStaticScore"; 967 } 968 969 var rulesMetCnt = 0; 970 971 this.each(function (idx, el) { 972 var options = $(el).data("pwstrength-bootstrap"); 973 974 rulesMetCnt += rulesEngine.validation[rule](options, $(el).val(), 1); 975 }); 976 977 return (rulesMetCnt === this.length); 978 } 979 980 $.error("Rule " + rule + " does not exist on jQuery.pwstrength-bootstrap.validation"); 981 }; 982 983 $.fn.pwstrength = function (method) { 984 var result; 985 986 if (methods[method]) { 987 result = methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 988 } else if (typeof method === "object" || !method) { 989 result = methods.init.apply(this, arguments); 990 } else { 991 $.error("Method " + method + " does not exist on jQuery.pwstrength-bootstrap"); 992 } 993 994 return result; 995 }; 996}(jQuery, methods)); 997}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.