diff --git a/browserid/static/css/style.css b/browserid/static/css/style.css
index 7114748d0e4083e36fd1853a151ce6efa082dca2..20c2e610d2f6ed9a9971c51a1d6bd409893d5059 100644
--- a/browserid/static/css/style.css
+++ b/browserid/static/css/style.css
@@ -724,7 +724,7 @@ h1 {
 }
 
 
-#signUpForm #siteinfo, #congrats {
+#congrats #siteinfo, #congrats {
   display: none;
 }
 
diff --git a/browserid/static/dialog/controllers/dialog_controller.js b/browserid/static/dialog/controllers/dialog_controller.js
index f25b2612410bb50b136106b6be49d5a6e5f52796..771c3177067bcf5432d58d20bb40fc4eba72a81a 100644
--- a/browserid/static/dialog/controllers/dialog_controller.js
+++ b/browserid/static/dialog/controllers/dialog_controller.js
@@ -78,6 +78,7 @@
         self.doCheckAuth();
 
         $(window).bind("unload", function() {
+          bid.Storage.setStagedOnBehalfOf("");
           self.doCancel();
         });
       },
diff --git a/browserid/static/dialog/resources/user.js b/browserid/static/dialog/resources/user.js
index 1e9ce9a46df46bb3b867684ebb3eae9396b68821..3fde2a9a9eb795b03e40e2685abd70266e544417 100644
--- a/browserid/static/dialog/resources/user.js
+++ b/browserid/static/dialog/resources/user.js
@@ -108,6 +108,10 @@ BrowserID.User = (function() {
         //   'mustAuth' - user must authenticate
         //   'noRegistration' - no registration is in progress
         if (status === "complete" || status === "mustAuth") {
+          // As soon as the registration comes back as complete, we should 
+          // ensure that the stagedOnBehalfOf is cleared so there is no stale 
+          // data.
+          storage.setStagedOnBehalfOf("");
           if (onSuccess) {
             onSuccess(status);
           }
@@ -250,6 +254,35 @@ BrowserID.User = (function() {
       registrationPoll(network.checkUserRegistration, email, onSuccess, onFailure);
     },
 
+    /**
+     * Verify a user
+     * @method verifyUser
+     * @param {string} token - token to verify.
+     * @param {string} password - password to set for account.
+     * @param {function} [onSuccess] - Called to give status updates.
+     * @param {function} [onFailure] - Called on error.
+     */
+    verifyUser: function(token, password, onSuccess, onFailure) {
+      network.emailForVerificationToken(token, function (email) {
+        var invalidInfo = { valid: false };
+        if (email) {
+          network.completeUserRegistration(token, password, function (valid) {
+            var info = valid ? {
+              valid: valid,
+              email: email,
+              origin: storage.getStagedOnBehalfOf()
+            } : invalidInfo;
+
+            storage.setStagedOnBehalfOf("");
+
+            if (onSuccess) onSuccess(info);
+          }, onFailure);
+        } else if(onSuccess) {
+          onSuccess(invalidInfo);
+        }
+      }, onFailure);
+    },
+
     /**
      * Set the password of the current user.
      * @method setPassword
diff --git a/browserid/static/dialog/test/qunit/resources/user_unit_test.js b/browserid/static/dialog/test/qunit/resources/user_unit_test.js
index c03c3610bb1d6fd60571c04de664999005801071..48e7a4b705930a18aa72f16d7206ddec37c739c0 100644
--- a/browserid/static/dialog/test/qunit/resources/user_unit_test.js
+++ b/browserid/static/dialog/test/qunit/resources/user_unit_test.js
@@ -76,6 +76,10 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
       xhrFailure ? onFailure() : onSuccess(status);
     },
 
+    completeUserRegistration: function(token, password, onSuccess, onFailure) {
+      xhrFailure ? onFailure() : onSuccess(validToken);
+    },
+
     authenticate: function(email, password, onSuccess, onFailure) {
       xhrFailure ? onFailure() : onSuccess(credentialsValid);
     },
@@ -304,8 +308,12 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
    * stored in `registrationResponse`.
    */
   test("waitForUserValidation with `complete` response", function() {
+    storage.setStagedOnBehalfOf(testOrigin);
+
     lib.waitForUserValidation("testuser@testuser.com", function(status) {
       equal(status, "complete", "complete response expected");
+
+      ok(!storage.getStagedOnBehalfOf(), "staged on behalf of is cleared when validation completes");
       start();
     }, failure("waitForUserValidation failure"));
 
@@ -315,8 +323,12 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
   test("waitForUserValidation with `mustAuth` response", function() {
     registrationResponse = "mustAuth";
 
+    storage.setStagedOnBehalfOf(testOrigin);
+
     lib.waitForUserValidation("testuser@testuser.com", function(status) {
       equal(status, "mustAuth", "mustAuth response expected");
+
+      ok(!storage.getStagedOnBehalfOf(), "staged on behalf of is cleared when validation completes");
       start();
     }, failure("waitForUserValidation failure"));
 
@@ -326,10 +338,13 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
   test("waitForUserValidation with `noRegistration` response", function() {
     registrationResponse = "noRegistration";
 
+    storage.setStagedOnBehalfOf(testOrigin);
     lib.waitForUserValidation("baduser@testuser.com", function(status) {
       ok(false, "not expecting success")
+
       start();
     }, function(status) {
+      ok(storage.getStagedOnBehalfOf(), "staged on behalf of is cleared when validation completes");
       ok(status, "noRegistration", "noRegistration response causes failure");
       start();
     });
@@ -340,10 +355,12 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
   test("waitForUserValidation with XHR failure", function() {
     xhrFailure = true;
 
+    storage.setStagedOnBehalfOf(testOrigin);
     lib.waitForUserValidation("baduser@testuser.com", function(status) {
       ok(false, "xhr failure should never succeed");
       start();
     }, function() {
+      ok(storage.getStagedOnBehalfOf(), "staged on behalf of is not cleared on XHR failure");
       ok(true, "xhr failure should always be a failure"); 
       start();
     });
@@ -351,6 +368,48 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
     stop();
   });
 
+  test("verifyUser with a good token", function() {
+    storage.setStagedOnBehalfOf(testOrigin);
+    lib.verifyUser("token", "password", function onSuccess(info) {
+      
+      ok(info.valid, "token was valid");
+      equal(info.email, "testuser@testuser.com", "email part of info");
+      equal(info.origin, testOrigin, "origin in info");
+      equal(storage.getStagedOnBehalfOf(), "", "initiating origin was removed");
+
+      start();
+    }, failure("verifyUser failure"));
+
+    stop();
+  });
+
+  test("verifyUser with a bad token", function() {
+    validToken = false;
+
+    lib.verifyUser("token", "password", function onSuccess(info) {
+      
+      equal(info.valid, false, "bad token calls onSuccess with a false validity");
+
+      start();
+    }, failure("verifyUser failure"));
+
+    stop();
+
+  });
+
+  test("verifyUser with an XHR failure", function() {
+    xhrFailure = true;
+
+    lib.verifyUser("token", "password", function onSuccess(info) {
+      ok(false, "xhr failure should never succeed");
+      start();
+    }, function() {
+      ok(true, "xhr failure should always be a failure"); 
+      start();
+    });
+      
+    stop();
+  });
 
   test("setPassword", function() {
     lib.setPassword("password", function() {
@@ -572,7 +631,10 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
    * stored in `registrationResponse`.
    */
  test("waitForEmailValidation `complete` response", function() {
+    storage.setStagedOnBehalfOf(testOrigin);
+
     lib.waitForEmailValidation("testemail@testemail.com", function(status) {
+      ok(!storage.getStagedOnBehalfOf(), "staged on behalf of is cleared when validation completes");
       equal(status, "complete", "complete response expected");
       start();
     }, failure("waitForEmailValidation failure"));
@@ -581,9 +643,11 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
   });
 
   test("waitForEmailValidation `mustAuth` response", function() {
+    storage.setStagedOnBehalfOf(testOrigin);
     registrationResponse = "mustAuth";
 
     lib.waitForEmailValidation("testemail@testemail.com", function(status) {
+      ok(!storage.getStagedOnBehalfOf(), "staged on behalf of is cleared when validation completes");
       equal(status, "mustAuth", "mustAuth response expected");
       start();
     }, failure("waitForEmailValidation failure"));
@@ -592,12 +656,14 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
   });
 
   test("waitForEmailValidation with `noRegistration` response", function() {
+    storage.setStagedOnBehalfOf(testOrigin);
     registrationResponse = "noRegistration";
 
     lib.waitForEmailValidation("baduser@testuser.com", function(status) {
       ok(false, "not expecting success")
       start();
     }, function(status) {
+      ok(storage.getStagedOnBehalfOf(), "staged on behalf of is cleared when validation completes");
       ok(status, "noRegistration", "noRegistration response causes failure");
       start();
     });
@@ -607,11 +673,14 @@ steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/user", functio
 
 
  test("waitForEmailValidation XHR failure", function() {
+    storage.setStagedOnBehalfOf(testOrigin);
     xhrFailure = true;
+
     lib.waitForEmailValidation("testemail@testemail.com", function(status) {
       ok(false, "xhr failure should never succeed");
       start();
     }, function() {
+      ok(storage.getStagedOnBehalfOf(), "staged on behalf of is cleared when validation completes");
       ok(true, "xhr failure should always be a failure"); 
       start();
     });