From 3238e2d9fcd532807847556514c0519fa0869b14 Mon Sep 17 00:00:00 2001 From: Dylan Hardison Date: Wed, 4 Nov 2015 17:51:25 -0500 Subject: Bug 1177911 - Determine and implement better password requirements for BMO --- js/account.js | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) (limited to 'js') diff --git a/js/account.js b/js/account.js index 31c1a50e6..c268bb8e5 100644 --- a/js/account.js +++ b/js/account.js @@ -7,6 +7,146 @@ $(function() { + function make_password_strength($password) { + return function(event) { + var password = $password.val(); + var missing_features = {"upper": true, "lower": true, "numbers": true, "symbols": true, "length12": true}; + var features = [], + charset = 0, + score = 0, + min_features = 3; + + $("#password-meter").show(); + $("#password-meter-label").show(); + + if (password.match(/[A-Z]/)) { + delete missing_features.upper; + features.push("upper"); + charset += 26; + } + if (password.match(/[a-z]/)) { + delete missing_features.lower; + features.push("lower"); + charset += 26; + } + if (password.match(/[0-9]/)) { + delete missing_features.numbers; + features.push("numbers"); + charset += 10; + } + if (password.match(/[^A-Za-z0-9]/)) { + delete missing_features.symbols; + features.push("symbols"); + charset += 30; // there are 30-32 typable characters on a keyboard. + } + if (password.length > 12) { + delete missing_features.length12; + features.push("length12"); + } + + $("#password-features li").removeClass("feature-ok"); + features.forEach(function(name) { + $("#password-feature-" + name).addClass("feature-ok"); + }); + + var entropy = Math.floor(Math.log(charset) * (password.length / Math.log(2))); + if (entropy) { + score = entropy/128; + } + + $password.get(0).setCustomValidity(""); + if (features.length < min_features) { + $("#password-msg") + .text("Password does not meet requirements") + .attr("class", "password-bad"); + $password.get(0).setCustomValidity($("#password-msg").text()); + } + else if (password.length < 8) { + $("#password-msg") + .text("Password is too short") + .attr("class", "password-bad"); + $password.get(0).setCustomValidity($("#password-msg").text()); + } + else { + $("#password-msg") + .text("Password meets requirements") + .attr("class", "password-good"); + $password.get(0).setCustomValidity(""); + } + + if (entropy < 60) { + $("#password-meter") + .removeClass("meter-good meter-ok") + .addClass("meter-bad"); + } + else if (entropy >= 120) { + $("#password-meter") + .removeClass("meter-bad meter-ok") + .addClass("meter-good"); + } + else if (entropy > 60) { + $("#password-meter") + .removeClass("meter-bad meter-good") + .addClass("meter-ok"); + } + + if (score === 0) { + score = 0.01; + $("#password-meter") + .removeClass("meter-good meter-ok") + .addClass("meter-bad"); + } + + $("#password-meter").width(Math.max(0, Math.min($password.width()+10, Math.ceil(($password.width()+10) * score)))); + }; + } + + function make_password_confirm($password1, $password2) { + return function (event) { + if ($password1.val() != $password2.val()) { + $password2.get(0).setCustomValidity("Does not match previous password"); + } + else { + $password2.get(0).setCustomValidity(""); + } + }; + } + var password1_sel, password2_sel; + var complexity = $("#password-features").data("password-complexity"); + var page = $("#password-features").data("password-page"); + var check_password_strength, check_password_confirm; + + if (page == "account") { + $("#new_password1, #new_password2, #new_login_name").change(function() { + $("#old_password").attr("required", true); + }); + } + + if (complexity == "bmo") { + if (page == "confirm") { + password1_sel = "#passwd1"; + password2_sel = "#passwd2"; + } + else { + password1_sel = "#new_password1"; + password2_sel = "#new_password2"; + } + $("#password-features").show(); + + check_password_strength = make_password_strength($(password1_sel)); + check_password_confirm = make_password_confirm($(password1_sel), $(password2_sel)); + + $(password1_sel).on("input", check_password_strength); + $(password1_sel).on("focus", check_password_strength); + + $(password1_sel).on("blur", check_password_confirm); + $(password1_sel).on("change", check_password_confirm); + $(password2_sel).on("input", check_password_confirm); + } + else { + $("#password-features").hide(); + } + // account disabling $('#account-disable-toggle') -- cgit v1.2.3-24-g4f1b