diff --git a/lib/browserid/views.js b/lib/browserid/views.js index b26361e2c6a04ff4e381cafe12b62c80132764b1..a8fc5def028e31e5f86cb2d34439d46851b53271 100644 --- a/lib/browserid/views.js +++ b/lib/browserid/views.js @@ -176,6 +176,17 @@ exports.setup = function(app) { renderCachableView(req, res, 'add_email_address.ejs', {title: 'Verify Email Address', fullpage: false}); }); + + app.get("/reset_password", function(req,res) { + renderCachableView(req, res, 'add_email_address.ejs', {title: 'Reset Password'}); + }); + + app.get("/confirm", function(req,res) { + renderCachableView(req, res, 'add_email_address.ejs', {title: 'Confirm Email'}); + }); + + + // serve up testing templates. but NOT in staging or production. see GH-1044 if ([ 'https://login.persona.org', 'https://login.anosrep.org' ].indexOf(config.get('public_url')) === -1) { // serve test.ejs to /test or /test/ or /test/index.html diff --git a/resources/static/common/js/user.js b/resources/static/common/js/user.js index d36d94ea66236862842204edebde5b1e6eb4c490..25cef980406b2306911d32f55e8cd8bafa4b7cc1 100644 --- a/resources/static/common/js/user.js +++ b/resources/static/common/js/user.js @@ -627,7 +627,7 @@ BrowserID.User = (function() { /** * Verify the password reset for a user. - * @method verifyPasswordReset + * @method completePasswordReset * @param {string} token - token to verify. * @param {string} password * @param {function} [onComplete] - Called on completion. @@ -635,7 +635,7 @@ BrowserID.User = (function() { * with valid=false otw. * @param {function} [onFailure] - Called on error. */ - verifyPasswordReset: function(token, password, onComplete, onFailure) { + completePasswordReset: function(token, password, onComplete, onFailure) { completeAddressVerification(token, password, "completePasswordReset", onComplete, onFailure); }, @@ -663,19 +663,19 @@ BrowserID.User = (function() { */ requestEmailReverify: function(email, onComplete, onFailure) { var idInfo = storage.getEmail(email); - if (idInfo && idInfo.verified) { + if (!idInfo) { + // user does not own this address. + complete(onComplete, { success: false, reason: "invalid_email" }); + } + else if (idInfo.verified) { // this email is already verified, cannot be reverified. complete(onComplete, { success: false, reason: "verified_email" }); } - else if (idInfo && !idInfo.verified) { + else if (!idInfo.verified) { // this address is unverified, try to reverify it. network.requestEmailReverify(email, origin, stageAddressVerificationResponse.curry(onComplete), onFailure); } - else { - // user does not own this address. - complete(onComplete, { success: false, reason: "invalid_email" }); - } }, completeEmailReverify: function(token, password, onComplete, onFailure) { diff --git a/resources/static/pages/js/start.js b/resources/static/pages/js/start.js index fdcdcf2f644cdb65cf8b6e335d2192f728bbe3bb..ca4d024ac9bbe72c70fa7c084b44874530b76ed5 100644 --- a/resources/static/pages/js/start.js +++ b/resources/static/pages/js/start.js @@ -117,6 +117,14 @@ $(function() { start(true); } + function verifySecondaryAddress(verifyFunction) { + var module = bid.verifySecondaryAddress.create(); + module.start({ + token: token, + verifyFunction: verifyFunction + }); + } + function start(status) { // If cookies are disabled, do not run any of the page specific code and // instead just show the error message. @@ -138,18 +146,16 @@ $(function() { bid.forgot(); } else if (path === "/add_email_address") { - var module = bid.verifySecondaryAddress.create(); - module.start({ - token: token, - verifyFunction: "verifyEmail" - }); + verifySecondaryAddress("verifyEmail"); } else if (path === "/verify_email_address") { - var module = bid.verifySecondaryAddress.create(); - module.start({ - token: token, - verifyFunction: "verifyUser" - }); + verifySecondaryAddress("verifyUser"); + } + else if (path === "/complete_password_reset") { + verifySecondaryAddress("completePasswordReset"); + } + else if (path === "/complete_email_reverify") { + verifySecondaryAddress("completeEmailReverify"); } else if (path === "/about") { var module = bid.about.create(); diff --git a/resources/static/test/cases/common/js/user.js b/resources/static/test/cases/common/js/user.js index ce212f120bc5d56c6f0360347c295f5022ea554c..b196fe70b49624bd3e0203fc8bc9b898cc81decb 100644 --- a/resources/static/test/cases/common/js/user.js +++ b/resources/static/test/cases/common/js/user.js @@ -3,9 +3,12 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -var jwcrypto = require("./lib/jwcrypto"); (function() { + "use strict"; + + var jwcrypto = require("./lib/jwcrypto"); + var bid = BrowserID, lib = bid.User, storage = bid.Storage, @@ -45,7 +48,7 @@ var jwcrypto = require("./lib/jwcrypto"); // Check for parts of the assertion equal(components.payload.aud, testOrigin, "correct audience"); - var expires = parseInt(components.payload.exp); + var expires = parseInt(components.payload.exp, 10); ok(typeof expires === "number" && !isNaN(expires), "expiration date is valid"); // this should be based on server time, not local time. @@ -520,11 +523,11 @@ var jwcrypto = require("./lib/jwcrypto"); failureCheck(lib.requestPasswordReset, "registered@testuser.com", "password"); }); - asyncTest("verifyPasswordReset with a good token", function() { + asyncTest("completePasswordReset with a good token", function() { storage.addSecondaryEmail(TEST_EMAIL, { verified: false }); storage.setReturnTo(testOrigin); - lib.verifyPasswordReset("token", "password", function onSuccess(info) { + lib.completePasswordReset("token", "password", function onSuccess(info) { testObjectValuesEqual(info, { valid: true, email: TEST_EMAIL, @@ -538,19 +541,19 @@ var jwcrypto = require("./lib/jwcrypto"); }, testHelpers.unexpectedXHRFailure); }); - asyncTest("verifyPasswordReset with a bad token", function() { + asyncTest("completePasswordReset with a bad token", function() { xhr.useResult("invalid"); - lib.verifyPasswordReset("token", "password", function onSuccess(info) { + lib.completePasswordReset("token", "password", function onSuccess(info) { equal(info.valid, false, "bad token calls onSuccess with a false validity"); start(); }, testHelpers.unexpectedXHRFailure); }); - asyncTest("verifyPasswordReset with an XHR failure", function() { + asyncTest("completePasswordReset with an XHR failure", function() { xhr.useResult("ajaxError"); - lib.verifyPasswordReset( + lib.completePasswordReset( "token", "password", testHelpers.unexpectedSuccess, @@ -1405,7 +1408,6 @@ var jwcrypto = require("./lib/jwcrypto"); start(); }, testHelpers.expectedXHRFailure); }, testHelpers.unexpectedXHRFailure); - xhr.useResult }, testHelpers.unexpectedXHRFailure); }); diff --git a/tests/page-requests-test.js b/tests/page-requests-test.js index 57f9b081300a171366a24b1c72a4bf43405d4605..2ae2100ab194871b2b756358c7d566802f609539 100755 --- a/tests/page-requests-test.js +++ b/tests/page-requests-test.js @@ -63,6 +63,8 @@ suite.addBatch({ 'GET /privacy': respondsWith(200), 'GET /verify_email_address': respondsWith(200), 'GET /add_email_address': respondsWith(200), + 'GET /reset_password': respondsWith(200), + 'GET /confirm': respondsWith(200), 'GET /idp_auth_complete': respondsWith(200), 'GET /pk': respondsWith(200), 'GET /.well-known/browserid': respondsWith(200),