From de00a20ba40d966f33e55238082057e20248d72f Mon Sep 17 00:00:00 2001 From: Shane Tomlinson <stomlinson@mozilla.com> Date: Mon, 14 May 2012 19:27:14 +0100 Subject: [PATCH] Make users who have not yet set their password by time they reach the landing page set their password. issue #1592 --- resources/static/css/style.css | 4 +- .../static/pages/verify_secondary_address.js | 21 ++++- .../cases/pages/verify_secondary_address.js | 85 +++++++++++++++++++ resources/static/test/mocks/xhr.js | 1 + resources/views/add_email_address.ejs | 14 +++ resources/views/verify_email_address.ejs | 15 ++++ 6 files changed, 136 insertions(+), 4 deletions(-) diff --git a/resources/static/css/style.css b/resources/static/css/style.css index 86b0b219f..802295dac 100644 --- a/resources/static/css/style.css +++ b/resources/static/css/style.css @@ -669,7 +669,7 @@ h1 { margin-bottom: 10px; } -.siteinfo, #congrats, .password_entry, .enter_password .hint, #unknown_secondary, #primary_verify, .verify_primary .submit { +.siteinfo, #congrats, .password_entry, #verify_password, .enter_password .hint, #unknown_secondary, #primary_verify, .verify_primary .submit { display: none; } @@ -677,7 +677,7 @@ h1 { float: left; } -.enter_password .password_entry, .known_secondary .password_entry, +.enter_password .password_entry, .enter_verify_password #verify_password, .known_secondary .password_entry, .unknown_secondary #unknown_secondary, .verify_primary #verify_primary { display: block; } diff --git a/resources/static/pages/verify_secondary_address.js b/resources/static/pages/verify_secondary_address.js index 2ccfb0c80..607a5621c 100644 --- a/resources/static/pages/verify_secondary_address.js +++ b/resources/static/pages/verify_secondary_address.js @@ -17,6 +17,7 @@ BrowserID.verifySecondaryAddress = (function() { validation = bid.Validation, token, sc, + needsPassword, mustAuth, verifyFunction; @@ -36,7 +37,11 @@ BrowserID.verifySecondaryAddress = (function() { function submit(oncomplete) { var pass = dom.getInner("#password") || undefined, - valid = !mustAuth || validation.password(pass); + vpass = dom.getInner("#vpassword") || undefined, + valid = (!needsPassword || + validation.passwordAndValidationPassword(pass, vpass)) + && (!mustAuth || + validation.password(pass)); if (valid) { user[verifyFunction](token, pass, function(info) { @@ -56,13 +61,25 @@ BrowserID.verifySecondaryAddress = (function() { if(info) { showRegistrationInfo(info); + needsPassword = info.needs_password; mustAuth = info.must_auth; - if (mustAuth) { + if (needsPassword) { + // This is a fix for legacy users who started the user creation + // process without setting their password in the dialog. If the user + // needs a password, they must set it now. Once all legacy users are + // verified or their links invalidated, this flow can be removed. + dom.addClass("body", "enter_password"); + dom.addClass("body", "enter_verify_password"); + complete(oncomplete, true); + } + else if (mustAuth) { + // These are users who have set their passwords inside of the dialog. dom.addClass("body", "enter_password"); complete(oncomplete, true); } else { + // These are users who do not have to set their passwords at all. submit(oncomplete); } } diff --git a/resources/static/test/cases/pages/verify_secondary_address.js b/resources/static/test/cases/pages/verify_secondary_address.js index a770237db..d7eacaa57 100644 --- a/resources/static/test/cases/pages/verify_secondary_address.js +++ b/resources/static/test/cases/pages/verify_secondary_address.js @@ -116,6 +116,7 @@ xhr.useResult("mustAuth"); createController(config, function() { xhr.useResult("valid"); + testHasClass("body", "enter_password"); controller.submit(function(status) { equal(status, true, "correct status"); testHasClass("body", "complete"); @@ -134,4 +135,88 @@ }); }); + asyncTest("must set password, successful login", function() { + xhr.useResult("needsPassword"); + createController(config, function() { + xhr.useResult("valid"); + + $("#password").val("password"); + $("#vpassword").val("password"); + + testHasClass("body", "enter_password"); + testHasClass("body", "enter_verify_password"); + + controller.submit(function(status) { + equal(status, true, "correct status"); + testHasClass("body", "complete"); + start(); + }); + }); + }); + + asyncTest("must set password, too short a password", function() { + xhr.useResult("needsPassword"); + createController(config, function() { + xhr.useResult("valid"); + + $("#password").val("pass"); + $("#vpassword").val("pass"); + + controller.submit(function(status) { + equal(status, false, "correct status"); + testHelpers.testTooltipVisible(); + start(); + }); + }); + }); + + asyncTest("must set password, too long a password", function() { + xhr.useResult("needsPassword"); + createController(config, function() { + xhr.useResult("valid"); + + var pass = testHelpers.generateString(81); + $("#password").val(pass); + $("#vpassword").val(pass); + + controller.submit(function(status) { + equal(status, false, "correct status"); + testHelpers.testTooltipVisible(); + start(); + }); + }); + }); + + asyncTest("must set password, missing verification password", function() { + xhr.useResult("needsPassword"); + createController(config, function() { + xhr.useResult("valid"); + + $("#password").val("password"); + $("#vpassword").val(""); + + controller.submit(function(status) { + equal(status, false, "correct status"); + testHelpers.testTooltipVisible(); + start(); + }); + }); + }); + + asyncTest("must set password, mismatched passwords", function() { + xhr.useResult("needsPassword"); + createController(config, function() { + xhr.useResult("valid"); + + $("#password").val("password"); + $("#vpassword").val("password1"); + + controller.submit(function(status) { + equal(status, false, "correct status"); + testHelpers.testTooltipVisible(); + start(); + }); + }); + }); + }()); diff --git a/resources/static/test/mocks/xhr.js b/resources/static/test/mocks/xhr.js index 8b505f997..12c612251 100644 --- a/resources/static/test/mocks/xhr.js +++ b/resources/static/test/mocks/xhr.js @@ -34,6 +34,7 @@ BrowserID.Mocks.xhr = (function() { "get /wsapi/session_context contextAjaxError": undefined, "get /wsapi/email_for_token?token=token valid": { email: "testuser@testuser.com" }, "get /wsapi/email_for_token?token=token mustAuth": { email: "testuser@testuser.com", must_auth: true }, + "get /wsapi/email_for_token?token=token needsPassword": { email: "testuser@testuser.com", needs_password: true }, "get /wsapi/email_for_token?token=token invalid": { success: false }, "post /wsapi/authenticate_user valid": { success: true, userid: 1 }, "post /wsapi/authenticate_user invalid": { success: false }, diff --git a/resources/views/add_email_address.ejs b/resources/views/add_email_address.ejs index fa6fbd891..45b711cec 100644 --- a/resources/views/add_email_address.ejs +++ b/resources/views/add_email_address.ejs @@ -31,6 +31,20 @@ <%= gettext('Password must be between 8 and 80 characters long.') %> </div> </li> + + <li class="password_entry" id="verify_password"> + <label class="serif" for="vpassword"><%= gettext('Verify Password') %></label> + <input class="sans" id="vpassword" placeholder="<%= gettext('Repeat Password') %>" type="password" maxlength="80"> + + <div id="vpassword_required" class="tooltip" for="vpassword"> + <%= gettext('Verification password is required.') %> + </div> + + <div class="tooltip" id="passwords_no_match" for="vpassword"> + <%= gettext ('Passwords do not match.') %> + </div> + + </li> </ul> <div class="submit cf password_entry"> diff --git a/resources/views/verify_email_address.ejs b/resources/views/verify_email_address.ejs index a73c80ead..1f275d3fe 100644 --- a/resources/views/verify_email_address.ejs +++ b/resources/views/verify_email_address.ejs @@ -18,6 +18,7 @@ <label class="serif" for="email"><%= gettext('Email Address') %></label> <input class="youraddress sans" id="email" placeholder="<%= gettext('Your Email') %>" type="email" value="" disabled="disabled" maxlength="254" /> </li> + <li class="password_entry"> <label class="serif" for="password"><%= gettext('Password') %></label> <input class="sans" id="password" placeholder="<%= gettext('Your Password') %>" type="password" autofocus maxlength=80 /> @@ -30,6 +31,20 @@ <%= gettext('Password must be between 8 and 80 characters long.') %> </div> </li> + + <li class="password_entry" id="verify_password"> + <label class="serif" for="vpassword"><%= gettext('Verify Password') %></label> + <input class="sans" id="vpassword" placeholder="<%= gettext('Repeat Password') %>" type="password" maxlength="80"> + + <div id="vpassword_required" class="tooltip" for="vpassword"> + <%= gettext('Verification password is required.') %> + </div> + + <div class="tooltip" id="passwords_no_match" for="vpassword"> + <%= gettext ('Passwords do not match.') %> + </div> + + </li> </ul> <div class="submit cf password_entry"> -- GitLab