diff --git a/resources/static/dialog/controllers/actions.js b/resources/static/dialog/controllers/actions.js
index 884f452a53cae5d4e2743ecbaa7bcd4e8df456b5..eb5aca059fa22df7fb90a9e53a3a16cbab4ca112 100644
--- a/resources/static/dialog/controllers/actions.js
+++ b/resources/static/dialog/controllers/actions.js
@@ -100,6 +100,10 @@ BrowserID.Modules.Actions = (function() {
       startService("forgot_password", info);
     },
 
+    doResetPassword: function(info) {
+      this.doConfirmUser(info.email);
+    },
+
     doConfirmEmail: function(email) {
       startRegCheckService.call(this, email, "waitForEmailValidation", "email_confirmed");
     },
diff --git a/resources/static/dialog/resources/state_machine.js b/resources/static/dialog/resources/state_machine.js
index 5388731eddcc7ad77dbaa57d08b3dbd793cf92e5..4ab1318a43f2c7262c0d7492c5bd6987782947b2 100644
--- a/resources/static/dialog/resources/state_machine.js
+++ b/resources/static/dialog/resources/state_machine.js
@@ -62,8 +62,8 @@
   function popState(info) {
     // Skip the first state, it is where the user is at now.
     stateStack.pop();
-
     var state = stateStack[stateStack.length - 1];
+
     if (state) {
       state.args[0] = state.args[0] || {};
       _.extend(state.args[0], info);
@@ -89,7 +89,6 @@
       }
     }
 
-
     subscribe("offline", function(msg, info) {
       startState("doOffline");
     });
@@ -152,14 +151,17 @@
     subscribe("primary_user", function(msg, info) {
       addPrimaryUser = !!info.add;
       email = info.email;
-      // We don't want to put the provisioning step on the stack, instead when
-      // a user cancels this step, they should go back to the step before the
-      // provisioning.
+
+      updateCurrentStateInfo(info);
+
       var idInfo = storage.getEmail(email);
       if(idInfo && idInfo.cert) {
         mediator.publish("primary_user_ready", info);
       }
       else {
+        // We don't want to put the provisioning step on the stack, instead when
+        // a user cancels this step, they should go back to the step before the
+        // provisioning.
         startState(false, "doProvisionPrimaryUser", info);
       }
     });
@@ -253,12 +255,15 @@
     });
 
     subscribe("forgot_password", function(msg, info) {
+      // forgot password initiates the forgotten password flow.
       updateCurrentStateInfo(info);
       startState("doForgotPassword", info);
     });
 
     subscribe("reset_password", function(msg, info) {
-      startState("doConfirmUser", info.email);
+      // reset password says the password has been reset, now waiting for
+      // confirmation.
+      startState(false, "doResetPassword", info);
     });
 
     subscribe("assertion_generated", function(msg, info) {
diff --git a/resources/static/test/cases/resources/state_machine.js b/resources/static/test/cases/resources/state_machine.js
index 1fbb1e8f7394339ef53ed3f60c4b49a7896113c9..42c7dec921626738c7e1db0c0a3e8c27b7407e6a 100644
--- a/resources/static/test/cases/resources/state_machine.js
+++ b/resources/static/test/cases/resources/state_machine.js
@@ -139,12 +139,24 @@
     equal(actions.info.doForgotPassword.requiredEmail, true, "correct requiredEmail passed");
   });
 
-  test("reset_password", function() {
+  test("reset_password - call doResetPassword", function() {
     // XXX how is this different from forgot_password?
     mediator.publish("reset_password", {
       email: "testuser@testuser.com"
     });
-    equal(actions.info.doConfirmUser, "testuser@testuser.com", "reset password with the correct email");
+    equal(actions.info.doResetPassword.email, "testuser@testuser.com", "reset password with the correct email");
+  });
+
+  test("cancel reset_password flow - go two steps back", function() {
+    // we want to skip the "verify" screen of reset password and instead go two
+    // screens back.  Do do this, we are simulating the steps necessary to get
+    // to the reset_password flow.
+    mediator.publish("authenticate");
+    mediator.publish("forgot_password", { email: "testuser@testuser.com" });
+    mediator.publish("reset_password");
+    actions.info.doAuthenticate = {};
+    mediator.publish("cancel_state");
+    equal(actions.info.doAuthenticate.email, "testuser@testuser.com", "authenticate called with the correct email");
   });
 
   test("assertion_generated with null assertion", function() {
diff --git a/resources/static/test/testHelpers/helpers.js b/resources/static/test/testHelpers/helpers.js
index a4c916c160d27f09fdd275cc4d24be6bfaaf5b4a..507c885c6341c2534a1429bbe7808a00b3a21ec6 100644
--- a/resources/static/test/testHelpers/helpers.js
+++ b/resources/static/test/testHelpers/helpers.js
@@ -65,6 +65,9 @@ BrowserID.TestHelpers = (function() {
       network.init();
       storage.clear();
 
+      $("body").stop().show();
+      $("body")[0].className = "";
+
       var el = $("#controller_head");
       el.find("#formWrap .contents").html("");
       el.find("#wait .contents").html("");
@@ -81,6 +84,7 @@ BrowserID.TestHelpers = (function() {
         provisioning: provisioning
       });
       user.setOrigin(testOrigin);
+
     },
 
     teardown: function() {