diff --git a/resources/static/dialog/controllers/actions.js b/resources/static/dialog/controllers/actions.js
index 655da3f96017e86b5ec373658df721e97cedf61e..3a2aa0eea5f2e68e6a6cc9a9e1d025cba78060cd 100644
--- a/resources/static/dialog/controllers/actions.js
+++ b/resources/static/dialog/controllers/actions.js
@@ -29,11 +29,10 @@ BrowserID.Modules.Actions = (function() {
     return module;
   }
 
-  function startRegCheckService(email, verifier, message) {
-    this.confirmEmail = email;
-
+  function startRegCheckService(options, verifier, message) {
     var controller = startService("check_registration", {
-      email: email,
+      email: options.email,
+      required: options.required,
       verifier: verifier,
       verificationMessage: message
     });
@@ -76,8 +75,8 @@ BrowserID.Modules.Actions = (function() {
       if(onsuccess) onsuccess(null);
     },
 
-    doConfirmUser: function(email) {
-      startRegCheckService.call(this, email, "waitForUserValidation", "user_confirmed");
+    doConfirmUser: function(info) {
+      startRegCheckService.call(this, info, "waitForUserValidation", "user_confirmed");
     },
 
     doPickEmail: function(info) {
@@ -104,14 +103,14 @@ BrowserID.Modules.Actions = (function() {
       this.doConfirmUser(info.email);
     },
 
-    doConfirmEmail: function(email) {
-      startRegCheckService.call(this, email, "waitForEmailValidation", "email_confirmed");
+    doConfirmEmail: function(info) {
+      startRegCheckService.call(this, info, "waitForEmailValidation", "email_confirmed");
     },
 
-    doEmailConfirmed: function() {
+    doEmailConfirmed: function(info) {
       var self=this;
       // yay!  now we need to produce an assertion.
-      user.getAssertion(self.confirmEmail, user.getOrigin(), function(assertion) {
+      user.getAssertion(info.email, user.getOrigin(), function(assertion) {
         self.publish("assertion_generated", {
           assertion: assertion
         });
diff --git a/resources/static/dialog/controllers/check_registration.js b/resources/static/dialog/controllers/check_registration.js
index 206dc041d3c245653b0fb246f9556507d550416d..04a9711b693e18364f5bef6691735ecc29b42129 100644
--- a/resources/static/dialog/controllers/check_registration.js
+++ b/resources/static/dialog/controllers/check_registration.js
@@ -14,14 +14,16 @@ BrowserID.Modules.CheckRegistration = (function() {
   var Module = bid.Modules.PageModule.extend({
     start: function(options) {
       var self=this;
-      self.renderWait("confirm_email", {
-          email: options.email
-      });
+      options = options || {};
+      options.required = !!options.required;
+
+      self.renderWait("confirm_email", options);
       self.email = options.email;
       self.verifier = options.verifier;
       self.verificationMessage = options.verificationMessage;
 
-      self.bind("#back", "click", self.cancel);
+      self.bind("#back", "click", self.back);
+      self.bind("#cancel", "click", self.cancel);
 
       Module.sc.start.call(self, options);
     },
@@ -42,12 +44,15 @@ BrowserID.Modules.CheckRegistration = (function() {
       }, self.getErrorDialog(errors.registration, oncomplete));
     },
 
-    cancel: function() {
-      var self=this;
+    back: function() {
       // XXX this should change to cancelEmailValidation for email, but this
       // will work.
       user.cancelUserValidation();
-      self.close("cancel_state");
+      this.close("cancel_state");
+    },
+
+    cancel: function() {
+      this.close("cancel");
     }
 
   });
diff --git a/resources/static/dialog/resources/state.js b/resources/static/dialog/resources/state.js
index d7fc6d59a6a47064e93073de214293830a4b643a..d29f7ffa4b5ab3d9bfb7b82a8063730e01e82158 100644
--- a/resources/static/dialog/resources/state.js
+++ b/resources/static/dialog/resources/state.js
@@ -9,8 +9,8 @@ BrowserID.State = (function() {
       mediator = bid.Mediator,
       publish = mediator.publish.bind(mediator),
       user = bid.User,
-      controller,
       moduleManager = bid.module,
+      controller,
       addPrimaryUser = false,
       email,
       requiredEmail;
@@ -82,11 +82,13 @@ BrowserID.State = (function() {
     });
 
     subscribe("user_staged", function(msg, info) {
-      startState("doConfirmUser", info.email);
+      self.stagedEmail = info.email;
+      info.required = !!requiredEmail;
+      startState("doConfirmUser", info);
     });
 
     subscribe("user_confirmed", function() {
-      startState("doEmailConfirmed");
+      startState("doEmailConfirmed", { email: self.stagedEmail} );
     });
 
     subscribe("primary_user", function(msg, info) {
@@ -221,11 +223,13 @@ BrowserID.State = (function() {
     });
 
     subscribe("email_staged", function(msg, info) {
-      startState("doConfirmEmail", info.email);
+      self.stagedEmail = info.email;
+      info.required = !!requiredEmail;
+      startState("doConfirmEmail", info);
     });
 
     subscribe("email_confirmed", function() {
-      startState("doEmailConfirmed");
+      startState("doEmailConfirmed", { email: self.stagedEmail} );
     });
 
     subscribe("cancel_state", function(msg, info) {
@@ -243,6 +247,9 @@ BrowserID.State = (function() {
         throw "start: controller must be specified";
       }
 
+      addPrimaryUser = false;
+      email = requiredEmail = null;
+
       State.sc.start.call(this, options);
       startStateMachine.call(this);
     }
diff --git a/resources/static/dialog/views/confirm_email.ejs b/resources/static/dialog/views/confirm_email.ejs
index 39e17c36f0bcd435310a0c3e8bbeb87133573a77..79e472165f954d82ef51785aa206e5ee828cfdeb 100644
--- a/resources/static/dialog/views/confirm_email.ejs
+++ b/resources/static/dialog/views/confirm_email.ejs
@@ -3,6 +3,21 @@
       file, You can obtain one at http://mozilla.org/MPL/2.0/. */ %>
 
     <h2><%= gettext('Check your email!') %></h2>
-    <p><%= format(gettext('We sent a confirmation email to <strong>%s</strong>'), [email]) %></p>
-    <p><%= gettext('To finish signing in just click the verify link we sent to your email address.') %></p><br />
-    <p><%= gettext('If this is a mistake, just ignore the sent email and <a href="#" id="back">use another email address</a>.') %></p>
+
+    <p>
+      <%= format(gettext('We sent a confirmation email to <strong>%s</strong>'), [email]) %>
+    </p>
+
+    <p>
+      <%= gettext('To finish signing in just click the verify link we sent to your email address.') %>
+    </p>
+    <br />
+
+    <p>
+      <% if(required) { %>
+        <%= gettext('If this is a mistake, just ignore the sent email and <a href="#" id="cancel">cancel</a>.') %>
+      <% } else { %>
+        <%= gettext('If this is a mistake, just ignore the sent email and <a href="#" id="back">use another email address</a>.') %>
+      <% } %>
+    </p>
+
diff --git a/resources/static/test/cases/controllers/actions.js b/resources/static/test/cases/controllers/actions.js
index 2ed23b47e783b6bdac87c8844ea2aeeca43f845c..74ef5b3a55aec42bb78eb8e76ea7b2ee4a36c910 100644
--- a/resources/static/test/cases/controllers/actions.js
+++ b/resources/static/test/cases/controllers/actions.js
@@ -7,6 +7,7 @@
   "use strict";
 
   var bid = BrowserID,
+      user = bid.User,
       controller,
       el,
       testHelpers = bid.TestHelpers;
@@ -29,7 +30,7 @@
     }
   });
 
-  asyncTest("doError with no template should display default error screen", function() {
+  asyncTest("doError with no template - display default error screen", function() {
     createController({
       ready: function() {
         equal(testHelpers.errorVisible(), false, "Error is not yet visible");
@@ -41,7 +42,7 @@
     });
   });
 
-  asyncTest("doError with with template should display error screen", function() {
+  asyncTest("doError with with template - display error screen", function() {
     createController({
       ready: function() {
         equal(testHelpers.errorVisible(), false, "Error is not yet visible");
@@ -53,7 +54,7 @@
     });
   });
 
-  asyncTest("doOffline should print offline error screen", function() {
+  asyncTest("doOffline - print offline error screen", function() {
     createController({
       ready: function() {
         controller.doOffline();
@@ -64,7 +65,7 @@
     });
   });
 
-  asyncTest("doProvisionPrimaryUser tries to start the provision_primary_user service", function() {
+  asyncTest("doProvisionPrimaryUser - start the provision_primary_user service", function() {
     createController({
       ready: function() {
         var error;
@@ -80,7 +81,7 @@
     });
   });
 
-  asyncTest("doVerifyPrimaryUser tries to start the verify_primary_user service", function() {
+  asyncTest("doVerifyPrimaryUser - start the verify_primary_user service", function() {
     createController({
       ready: function() {
         var error;
@@ -96,7 +97,7 @@
     });
   });
 
-  asyncTest("doPrimaryUserProvisioned tries to start the primary_user_verified service", function() {
+  asyncTest("doPrimaryUserProvisioned - start the primary_user_verified service", function() {
     createController({
       ready: function() {
         var error;
@@ -112,7 +113,7 @@
     });
   });
 
-  asyncTest("doEmailChosen tries to start the email_chosen service", function() {
+  asyncTest("doEmailChosen - start the email_chosen service", function() {
     createController({
       ready: function() {
         var error;
@@ -128,5 +129,52 @@
     });
   });
 
+  asyncTest("doConfirmUser - start the check_registration service", function() {
+    createController({
+      ready: function() {
+        var error;
+        try {
+          controller.doConfirmUser({email: "testuser@testuser.com"});
+        } catch(e) {
+          error = e;
+        }
+
+        equal(error, "module not registered for check_registration", "correct service started");
+        start();
+      }
+    });
+  });
+
+  asyncTest("doConfirmEmail - start the check_registration service", function() {
+    createController({
+      ready: function() {
+        var error;
+        try {
+          controller.doConfirmEmail({email: "testuser@testuser.com"});
+        } catch(e) {
+          error = e;
+        }
+
+        equal(error, "module not registered for check_registration", "correct service started");
+        start();
+      }
+    });
+
+  });
+
+  asyncTest("doEmailConfirmed - generate an assertion for the email", function() {
+    createController({
+      ready: function() {
+        testHelpers.register("assertion_generated", function(msg, info) {
+          ok(info.assertion, "assertion generated");
+          start();
+        });
+
+        user.syncEmailKeypair("testuser@testuser.com", function() {
+          controller.doEmailConfirmed({email: "testuser@testuser.com"});
+        });
+      }
+    });
+  });
 }());
 
diff --git a/resources/static/test/cases/controllers/check_registration.js b/resources/static/test/cases/controllers/check_registration.js
index d65e8b8320d941946220d468c87bd3ab76856c0f..c852f17d784b7dc3604d2944d135adaa995b0835 100644
--- a/resources/static/test/cases/controllers/check_registration.js
+++ b/resources/static/test/cases/controllers/check_registration.js
@@ -22,7 +22,7 @@
     });
   }
 
-  module("controllers/checkregistration_controller", {
+  module("controllers/check_registration", {
     setup: function() {
       testHelpers.setup();
     },
@@ -63,7 +63,7 @@
     }, 500);
   });
 
-  asyncTest("user validation with XHR error", function() {
+  asyncTest("user validation with XHR error - show error message", function() {
     xhr.useResult("ajaxError");
 
     createController("waitForUserValidation", "user_verified");
@@ -76,11 +76,22 @@
     });
   });
 
-  asyncTest("cancel raises cancel_state", function() {
+  asyncTest("back - raise cancel_state", function() {
     createController("waitForUserValidation", "user_verified");
     controller.startCheck(function() {
       register("cancel_state", function() {
-        ok(true, "on cancel, cancel_state is triggered");
+        ok(true, "cancel_state is triggered");
+        start();
+      });
+      controller.back();
+    });
+  });
+
+  asyncTest("cancel - raise cancel", function() {
+    createController("waitForUserValidation", "user_verified");
+    controller.startCheck(function() {
+      register("cancel", function() {
+        ok(true, "cancel is triggered");
         start();
       });
       controller.cancel();
diff --git a/resources/static/test/cases/resources/state.js b/resources/static/test/cases/resources/state.js
index 01cb58ad6720e5d426136ae082cbb7c82369f8a6..84f7961a57efadd5b86798f9992d884aa4270f3d 100644
--- a/resources/static/test/cases/resources/state.js
+++ b/resources/static/test/cases/resources/state.js
@@ -72,21 +72,40 @@
     equal(actions.called.doOffline, true, "controller is offline");
   });
 
-  test("user_staged", function() {
-    // XXX rename user_staged to confirm_user or something to that effect.
+  test("user_staged - call doConfirmUser", function() {
     mediator.publish("user_staged", {
       email: "testuser@testuser.com"
     });
 
-    equal(actions.info.doConfirmUser, "testuser@testuser.com", "waiting for email confirmation for testuser@testuser.com");
+    equal(actions.info.doConfirmUser.email, "testuser@testuser.com", "waiting for email confirmation for testuser@testuser.com");
   });
 
-  test("user_confirmed", function() {
+  test("user_staged with required email - call doConfirmUser with required = true", function() {
+    mediator.publish("start", { requiredEmail: "testuser@testuser.com" });
+    mediator.publish("user_staged", { email: "testuser@testuser.com" });
+
+    equal(actions.info.doConfirmUser.required, true, "doConfirmUser called with required flag");
+  });
+
+  test("user_confirmed - call doEmailConfirmed", function() {
     mediator.publish("user_confirmed");
 
     ok(actions.called.doEmailConfirmed, "user was confirmed");
   });
 
+  test("email_staged - call doConfirmEmail", function() {
+    mediator.publish("email_staged", { email: "testuser@testuser.com" });
+
+    equal(actions.info.doConfirmEmail.required, false, "doConfirmEmail called without required flag");
+  });
+
+  test("email_staged with required email - call doConfirmEmail with required = true", function() {
+    mediator.publish("start", { requiredEmail: "testuser@testuser.com" });
+    mediator.publish("email_staged", { email: "testuser@testuser.com" });
+
+    equal(actions.info.doConfirmEmail.required, true, "doConfirmEmail called with required flag");
+  });
+
   test("primary_user with already provisioned primary user calls doEmailChosen", function() {
     storage.addEmail("testuser@testuser.com", { type: "primary", cert: "cert" });
     mediator.publish("primary_user", { email: "testuser@testuser.com" });