1/*! 2* jQuery Password Strength plugin for Twitter Bootstrap 3* Version: 3.0.4 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 validation.wordSimilarToUsername = function (options, word, score) { 119 var username = $(options.common.usernameField).val(); 120 if (username && word.toLowerCase().match(username.replace(/[\-\[\]\/\{\}\(\)\*\+\=\?\:\.\\\^\$\|\!\,]/g, "\\$&").toLowerCase())) { 121 return score; 122 } 123 return 0; 124 }; 125 126 validation.wordTwoCharacterClasses = function (options, word, score) { 127 if (word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) || 128 (word.match(/([a-zA-Z])/) && word.match(/([0-9])/)) || 129 (word.match(/(.[!,@,#,$,%,\^,&,*,?,_,~])/) && word.match(/[a-zA-Z0-9_]/))) { 130 return score; 131 } 132 return 0; 133 }; 134 135 validation.wordRepetitions = function (options, word, score) { 136 if (word.match(/(.)\1\1/)) { return score; } 137 return 0; 138 }; 139 140 validation.wordSequences = function (options, word, score) { 141 var found = false, 142 j; 143 if (word.length > 2) { 144 $.each(rulesEngine.forbiddenSequences, function (idx, seq) { 145 if (found) { return; } 146 var sequences = [seq, seq.split('').reverse().join('')]; 147 $.each(sequences, function (idx, sequence) { 148 for (j = 0; j < (word.length - 2); j += 1) { // iterate the word trough a sliding window of size 3: 149 if (sequence.indexOf(word.toLowerCase().substring(j, j + 3)) > -1) { 150 found = true; 151 } 152 } 153 }); 154 }); 155 if (found) { return score; } 156 } 157 return 0; 158 }; 159 160 validation.wordLowercase = function (options, word, score) { 161 return word.match(/[a-z]/) && score; 162 }; 163 164 validation.wordUppercase = function (options, word, score) { 165 return word.match(/[A-Z]/) && score; 166 }; 167 168 validation.wordOneNumber = function (options, word, score) { 169 return word.match(/\d+/) && score; 170 }; 171 172 validation.wordThreeNumbers = function (options, word, score) { 173 return word.match(/(.*[0-9].*[0-9].*[0-9])/) && score; 174 }; 175 176 validation.wordOneSpecialChar = function (options, word, score) { 177 return word.match(/[!,@,#,$,%,\^,&,*,?,_,~]/) && score; 178 }; 179 180 validation.wordTwoSpecialChar = function (options, word, score) { 181 return word.match(/(.*[!,@,#,$,%,\^,&,*,?,_,~].*[!,@,#,$,%,\^,&,*,?,_,~])/) && score; 182 }; 183 184 validation.wordUpperLowerCombo = function (options, word, score) { 185 return word.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/) && score; 186 }; 187 188 validation.wordLetterNumberCombo = function (options, word, score) { 189 return word.match(/([a-zA-Z])/) && word.match(/([0-9])/) && score; 190 }; 191 192 validation.wordLetterNumberCharCombo = function (options, word, score) { 193 return word.match(/([a-zA-Z0-9].*[!,@,#,$,%,\^,&,*,?,_,~])|([!,@,#,$,%,\^,&,*,?,_,~].*[a-zA-Z0-9])/) && score; 194 }; 195 196 validation.wordIsACommonPassword = function (options, word, score) { 197 if ($.inArray(word, options.rules.commonPasswords) >= 0) { 198 return score; 199 } 200 return 0; 201 }; 202 203 rulesEngine.validation = validation; 204 205 rulesEngine.executeRules = function (options, word) { 206 var totalScore = 0; 207 208 $.each(options.rules.activated, function (rule, active) { 209 if (active) { 210 var score = options.rules.scores[rule], 211 funct = rulesEngine.validation[rule], 212 result, 213 errorMessage; 214 215 if (!$.isFunction(funct)) { 216 funct = options.rules.extra[rule]; 217 } 218 219 if ($.isFunction(funct)) { 220 result = funct(options, word, score); 221 if (result) {
222 totalScore += result; 223 } 224 if (result < 0 || (!$.isNumeric(result) && !result)) { 225 errorMessage = options.ui.spanError(options, rule); 226 if (errorMessage.length > 0) { 227 options.instances.errors.push(errorMessage); 228 } 229 } 230 } 231 } 232 }); 233 234 return totalScore; 235 }; 236}(jQuery, rulesEngine)); 237 238try { 239 if (module && module.exports) { 240 module.exports = rulesEngine; 241 } 242} catch (ignore) {} 243 244// Source: src/options.js 245 246 247 248 249var defaultOptions = {}; 250 251defaultOptions.common = {}; 252defaultOptions.common.minChar = 6; 253defaultOptions.common.maxChar = 20; 254defaultOptions.common.usernameField = "#username"; 255defaultOptions.common.invalidCharsRegExp = new RegExp(/[\s,'"]/); 256defaultOptions.common.userInputs = [ 257 // Selectors for input fields with user input 258]; 259defaultOptions.common.onLoad = undefined; 260defaultOptions.common.onKeyUp = undefined; 261defaultOptions.common.onScore = undefined; 262defaultOptions.common.zxcvbn = false; 263defaultOptions.common.zxcvbnTerms = [ 264 // List of disrecommended words 265]; 266defaultOptions.common.events = ["keyup", "change", "paste"]; 267defaultOptions.common.debug = false; 268 269defaultOptions.rules = {}; 270defaultOptions.rules.extra = {}; 271defaultOptions.rules.scores = { 272 wordNotEmail: -100, 273 wordMinLength: -50, 274 wordMaxLength: -50, 275 wordInvalidChar: -100, 276 wordSimilarToUsername: -100, 277 wordSequences: -20, 278 wordTwoCharacterClasses: 2, 279 wordRepetitions: -25, 280 wordLowercase: 1, 281 wordUppercase: 3, 282 wordOneNumber: 3, 283 wordThreeNumbers: 5, 284 wordOneSpecialChar: 3, 285 wordTwoSpecialChar: 5, 286 wordUpperLowerCombo: 2, 287 wordLetterNumberCombo: 2, 288 wordLetterNumberCharCombo: 2, 289 wordIsACommonPassword: -100 290}; 291defaultOptions.rules.activated = { 292 wordNotEmail: true, 293 wordMinLength: true, 294 wordMaxLength: false, 295 wordInvalidChar: false, 296 wordSimilarToUsername: true, 297 wordSequences: true, 298 wordTwoCharacterClasses: true, 299 wordRepetitions: true, 300 wordLowercase: true, 301 wordUppercase: true, 302 wordOneNumber: true, 303 wordThreeNumbers: true, 304 wordOneSpecialChar: true, 305 wordTwoSpecialChar: true, 306 wordUpperLowerCombo: true, 307 wordLetterNumberCombo: true, 308 wordLetterNumberCharCombo: true, 309 wordIsACommonPassword: true 310}; 311defaultOptions.rules.raisePower = 1.4; 312// List taken from https://github.com/danielmiessler/SecLists (MIT License) 313defaultOptions.rules.commonPasswords = [ 314 '123456', 315 'password', 316 '12345678', 317 'qwerty', 318 '123456789', 319 '12345', 320 '1234', 321 '111111', 322 '1234567', 323 'dragon', 324 '123123', 325 'baseball', 326 'abc123', 327 'football', 328 'monkey', 329 'letmein', 330 '696969', 331 'shadow', 332 'master', 333 '666666', 334 'qwertyuiop', 335 '123321', 336 'mustang', 337 '1234567890', 338 'michael', 339 '654321', 340 'pussy', 341 'superman', 342 '1qaz2wsx', 343 '7777777', 344 'fuckyou', 345 '121212', 346 '000000', 347 'qazwsx', 348 '123qwe', 349 'killer', 350 'trustno1', 351 'jordan', 352 'jennifer', 353 'zxcvbnm', 354 'asdfgh', 355 'hunter', 356 'buster', 357 'soccer', 358 'harley', 359 'batman', 360 'andrew', 361 'tigger', 362 'sunshine', 363 'iloveyou', 364 'fuckme', 365 '2000', 366 'charlie', 367 'robert', 368 'thomas', 369 'hockey', 370 'ranger', 371 'daniel', 372 'starwars', 373 'klaster', 374 '112233', 375 'george', 376 'asshole', 377 'computer', 378 'michelle', 379 'jessica', 380 'pepper', 381 '1111', 382 'zxcvbn', 383 '555555', 384 '11111111', 385 '131313', 386 'freedom', 387 '777777', 388 'pass', 389 'fuck', 390 'maggie', 391 '159753', 392 'aaaaaa', 393 'ginger', 394 'princess', 395 'joshua', 396 'cheese', 397 'amanda', 398 'summer', 399 'love', 400 'ashley', 401 '6969', 402 'nicole', 403 'chelsea', 404 'biteme', 405 'matthew', 406 'access', 407 'yankees', 408 '987654321', 409 'dallas', 410 'austin', 411 'thunder', 412 'taylor', 413 'matrix' 414]; 415 416defaultOptions.ui = {}; 417defaultOptions.ui.bootstrap2 = false;
418defaultOptions.ui.bootstrap3 = false; 419defaultOptions.ui.colorClasses = [ 420 "danger", "danger", "danger", "warning", "warning", "success" 421]; 422defaultOptions.ui.showProgressBar = true; 423defaultOptions.ui.progressBarEmptyPercentage = 1; 424defaultOptions.ui.progressBarMinWidth = 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 try { 580 $el.popover("destroy"); 581 } catch (error) { 582 // Bootstrap 4.2.X onwards 583 $el.popover("dispose"); 584 } 585 $el.popover({ 586 html: true, 587 placement: options.ui.popoverPlacement, 588 trigger: "manual", 589 content: " " 590 }); 591 }; 592 593 ui.initUI = function (options, $el) { 594 if (options.ui.showPopover) { 595 ui.initPopover(options, $el); 596 } else { 597 if (options.ui.showErrors) { ui.initErrorList(options, $el); } 598 if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) { 599 ui.initVerdict(options, $el); 600 } 601 } 602 if (options.ui.showProgressBar) { 603 ui.initProgressBar(options, $el); 604 } 605 if (options.ui.showScore) { 606 ui.initScore(options, $el); 607 } 608 }; 609 610 ui.updateProgressBar = function (options, $el, cssClass, percentage) { 611 var $progressbar = ui.getUIElements(options, $el).$progressbar, 612 $bar = $progressbar.find(".progress-bar"), 613 cssPrefix = "progress-"; 614 615 if (options.ui.bootstrap2) { 616 $bar = $progressbar.find(".bar"); 617 cssPrefix = ""; 618 } 619 620 $.each(options.ui.colorClasses, function (idx, value) { 621 if (options.ui.bootstrap2 || options.ui.bootstrap3) { 622 $bar.removeClass(cssPrefix + "bar-" + value); 623 } else { 624 $bar.removeClass("bg-" + value); 625 } 626 }); 627 if (options.ui.bootstrap2 || options.ui.bootstrap3) { 628 $bar.addClass(cssPrefix + "bar-" + options.ui.colorClasses[cssClass]); 629 } else { 630 $bar.addClass("bg-" + options.ui.colorClasses[cssClass]); 631 } 632 if (percentage > 0) { 633 $bar.css("min-width", options.ui.progressBarMinWidth + 'px'); 634 } else { 635 $bar.css("min-width", ''); 636 } 637 $bar.css("width", percentage + '%'); 638 }; 639 640 ui.updateVerdict = function (options, $el, cssClass, text) { 641 var $verdict = ui.getUIElements(options, $el).$verdict; 642 $verdict.removeClass(options.ui.colorClasses.join(' ')); 643 if (cssClass > -1) { 644 $verdict.addClass(options.ui.colorClasses[cssClass]); 645 } 646 if (options.ui.showVerdictsInsideProgressBar) { 647 $verdict.css('white-space', 'nowrap'); 648 } 649 $verdict.html(text); 650 }; 651 652 ui.updateErrors = function (options, $el, remove) { 653 var $errors = ui.getUIElements(options, $el).$errors, 654 html = ""; 655 656 if (!remove) { 657 $.each(options.instances.errors, function (idx, err) { 658 html += "<li>" + err + "</li>"; 659 }); 660 } 661 $errors.html(html); 662 }; 663 664 ui.updateScore = function (options, $el, score, remove) { 665 var $score = ui.getUIElements(options, $el).$score, 666 html = ""; 667 668 if (!remove) { html = score.toFixed(2); } 669 $score.html(html); 670 }; 671 672 ui.updatePopover = function (options, $el, verdictText, remove) { 673 var popover = $el.data("bs.popover"), 674 html = "", 675 hide = true; 676 677 if (options.ui.showVerdicts && 678 !options.ui.showVerdictsInsideProgressBar && 679 verdictText.length > 0) { 680 html = "<h5><span class='password-verdict'>" + verdictText + 681 "</span></h5>"; 682 hide = false;
683 } 684 if (options.ui.showErrors) { 685 if (options.instances.errors.length > 0) { 686 hide = false; 687 } 688 html += options.ui.popoverError(options); 689 } 690 691 if (hide || remove) { 692 $el.popover("hide"); 693 return; 694 } 695 696 if (options.ui.bootstrap2) { popover = $el.data("popover"); } 697 698 if (popover.$arrow && popover.$arrow.parents("body").length > 0) { 699 $el.find("+ .popover .popover-content").html(html); 700 } else { 701 // It's hidden 702 if (options.ui.bootstrap2 || options.ui.bootstrap3) { 703 popover.options.content = html; 704 } else { 705 popover.config.content = html; 706 } 707 $el.popover("show"); 708 } 709 }; 710 711 ui.updateFieldStatus = function (options, $el, cssClass, remove) { 712 var $target = $el; 713 714 if (options.ui.bootstrap2) { 715 $target = $el.parents(".control-group").first(); 716 } else if (options.ui.bootstrap3) { 717 $target = $el.parents(".form-group").first(); 718 } 719 720 $.each(statusClasses, function (idx, css) { 721 if (options.ui.bootstrap3) { 722 css = "has-" + css; 723 } else if (!options.ui.bootstrap2) { // BS4 724 if (css === "error") { css = "danger"; } 725 css = "border-" + css; 726 } 727 $target.removeClass(css); 728 }); 729 730 if (remove) { return; } 731 732 cssClass = statusClasses[Math.floor(cssClass / 2)]; 733 if (options.ui.bootstrap3) { 734 cssClass = "has-" + cssClass; 735 } else if (!options.ui.bootstrap2) { // BS4 736 if (cssClass === "error") { cssClass = "danger"; } 737 cssClass = "border-" + cssClass; 738 } 739 $target.addClass(cssClass); 740 }; 741 742 ui.percentage = function (options, score, maximun) { 743 var result = Math.floor(100 * score / maximun), 744 min = options.ui.progressBarMinPercentage; 745 746 result = result <= min ? min : result; 747 result = result > 100 ? 100 : result; 748 return result; 749 }; 750 751 ui.getVerdictAndCssClass = function (options, score) { 752 var level, verdict; 753 754 if (score === undefined) { return ['', 0]; } 755 756 if (score <= options.ui.scores[0]) { 757 level = 0; 758 } else if (score < options.ui.scores[1]) { 759 level = 1; 760 } else if (score < options.ui.scores[2]) { 761 level = 2; 762 } else if (score < options.ui.scores[3]) { 763 level = 3; 764 } else if (score < options.ui.scores[4]) { 765 level = 4; 766 } else { 767 level = 5; 768 } 769 770 verdict = verdictKeys[level]; 771 772 return [options.i18n.t(verdict), level]; 773 }; 774 775 ui.updateUI = function (options, $el, score) { 776 var cssClass, barPercentage, verdictText, verdictCssClass; 777 778 cssClass = ui.getVerdictAndCssClass(options, score); 779 verdictText = score === 0 ? '' : cssClass[0]; 780 cssClass = cssClass[1]; 781 verdictCssClass = options.ui.useVerdictCssClass ? cssClass : -1; 782 783 if (options.ui.showProgressBar) { 784 if (score === undefined) { 785 barPercentage = options.ui.progressBarEmptyPercentage; 786 } else { 787 barPercentage = ui.percentage(options, score, options.ui.scores[4]); 788 } 789 ui.updateProgressBar(options, $el, cssClass, barPercentage); 790 if (options.ui.showVerdictsInsideProgressBar) { 791 ui.updateVerdict(options, $el, verdictCssClass, verdictText); 792 } 793 } 794 795 if (options.ui.showStatus) { 796 ui.updateFieldStatus(options, $el, cssClass, score === undefined); 797 } 798 799 if (options.ui.showPopover) { 800 ui.updatePopover(options, $el, verdictText, score === undefined); 801 } else { 802 if (options.ui.showVerdicts && !options.ui.showVerdictsInsideProgressBar) { 803 ui.updateVerdict(options, $el, verdictCssClass, verdictText); 804 } 805 if (options.ui.showErrors) { 806 ui.updateErrors(options, $el, score === undefined); 807 } 808 } 809 810 if (options.ui.showScore) { 811 ui.updateScore(options, $el, score, score === undefined); 812 } 813 }; 814}(jQuery, ui)); 815 816// Source: src/methods.js 817 818 819 820 821var methods = {}; 822 823(function ($, methods) { 824 "use strict"; 825 var onKeyUp, onPaste, applyToAll; 826 827 onKeyUp = function (event) { 828 var $el = $(event.target), 829 options = $el.data("pwstrength-bootstrap"), 830 word = $el.val(), 831 userInputs, 832 verdictText, 833 verdictLevel, 834 score; 835 836 if (options === undefined) { return; } 837 838 options.instances.errors = []; 839 if (word.length === 0) { 840 score = undefined; 841 } else { 842 if (options.common.zxcvbn) { 843 userInputs = []; 844 $.each(options.common.userInputs.concat([options.common.usernameField]), function (idx, selector) { 845 var value = $(selector).val(); 846 if (value) { userInputs.push(value); } 847 }); 848 userInputs = userInputs.concat(options.common.zxcvbnTerms); 849 score = zxcvbn(word, userInputs).guesses; 850 score = Math.log(score) * Math.LOG2E; 851 } else { 852 score = rulesEngine.executeRules(options, word); 853 } 854 if ($.isFunction(options.common.onScore)) { 855 score = options.common.onScore(options, word, score); 856 } 857 } 858 ui.updateUI(options, $el, score); 859 verdictText = ui.getVerdictAndCssClass(options, score); 860 verdictLevel = verdictText[1]; 861 verdictText = verdictText[0]; 862 863 if (options.common.debug) { 864 console.log(score + ' - ' + verdictText); 865 } 866 867 if ($.isFunction(options.common.onKeyUp)) { 868 options.common.onKeyUp(event, { 869 score: score, 870 verdictText: verdictText, 871 verdictLevel: verdictLevel 872 }); 873 } 874 }; 875 876 onPaste = function (event) { 877 // This handler is necessary because the paste event fires before the 878 // content is actually in the input, so we cannot read its value right 879 // away. Therefore, the timeouts. 880 var $el = $(event.target), 881 word = $el.val(), 882 tries = 0, 883 callback; 884 885 callback = function () { 886 var newWord = $el.val(); 887 888 if (newWord !== word) { 889 onKeyUp(event); 890 } else if (tries < 3) { 891 tries += 1; 892 setTimeout(callback, 100); 893 } 894 }; 895 896 setTimeout(callback, 100); 897 }; 898 899 methods.init = function (settings) { 900 this.each(function (idx, el) { 901 // Make it deep extend (first param) so it extends also the 902 // rules and other inside objects 903 var clonedDefaults = $.extend(true, {}, defaultOptions), 904 localOptions = $.extend(true, clonedDefaults, settings), 905 $el = $(el); 906 907 localOptions.instances = {}; 908 $el.data("pwstrength-bootstrap", localOptions); 909 910 $.each(localOptions.common.events, function (idx, eventName) { 911 var handler = eventName === "paste" ? onPaste : onKeyUp; 912 $el.on(eventName, handler); 913 }); 914 915 ui.initUI(localOptions, $el); 916 $el.trigger("keyup"); 917 918 if ($.isFunction(localOptions.common.onLoad)) { 919 localOptions.common.onLoad(); 920 } 921 }); 922 923 return this; 924 }; 925 926 methods.destroy = function () { 927 this.each(function (idx, el) { 928 var $el = $(el), 929 options = $el.data("pwstrength-bootstrap"), 930 elements = ui.getUIElements(options, $el); 931 elements.$progressbar.remove(); 932 elements.$verdict.remove(); 933 elements.$errors.remove(); 934 $el.removeData("pwstrength-bootstrap"); 935 }); 936 }; 937 938 methods.forceUpdate = function () { 939 this.each(function (idx, el) { 940 var event = { target: el }; 941 onKeyUp(event); 942 }); 943 }; 944 945 methods.addRule = function (name, method, score, active) { 946 this.each(function (idx, el) { 947 var options = $(el).data("pwstrength-bootstrap"); 948 949 options.rules.activated[name] = active; 950 options.rules.scores[name] = score; 951 options.rules.extra[name] = method; 952 }); 953 }; 954 955 applyToAll = function (rule, prop, value) { 956 this.each(function (idx, el) { 957 $(el).data("pwstrength-bootstrap").rules[prop][rule] = value; 958 }); 959 }; 960 961 methods.changeScore = function (rule, score) { 962 applyToAll.call(this, rule, "scores", score); 963 }; 964 965 methods.ruleActive = function (rule, active) { 966 applyToAll.call(this, rule, "activated", active); 967 }; 968 969 methods.ruleIsMet = function (rule) { 970 var rulesMetCnt = 0; 971 972 if (rule === "wordMinLength") { 973 rule = "wordMinLengthStaticScore"; 974 } else if (rule === "wordMaxLength") { 975 rule = "wordMaxLengthStaticScore"; 976 } 977 978 this.each(function (idx, el) { 979 var options = $(el).data("pwstrength-bootstrap"), 980 ruleFunction = rulesEngine.validation[rule], 981 result; 982 983 if (!$.isFunction(ruleFunction)) { 984 ruleFunction = options.rules.extra[rule]; 985 } 986 if ($.isFunction(ruleFunction)) { 987 result = ruleFunction(options, $(el).val(), 1); 988 if ($.isNumeric(result)) { 989 rulesMetCnt += result; 990 } 991 } 992 }); 993 994 return (rulesMetCnt === this.length); 995 }; 996 997 $.fn.pwstrength = function (method) { 998 var result; 999 1000 if (methods[method]) { 1001 result = methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 1002 } else if (typeof method === "object" || !method) { 1003 result = methods.init.apply(this, arguments); 1004 } else { 1005 $.error("Method " + method + " does not exist on jQuery.pwstrength-bootstrap"); 1006 } 1007 1008 return result; 1009 }; 1010}(jQuery, methods)); 1011}(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.