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),