From 7f9580cc53a0950c53a6eee066f020ce0d618292 Mon Sep 17 00:00:00 2001
From: Shane Tomlinson <stomlinson@mozilla.com>
Date: Thu, 29 Dec 2011 10:07:58 +0000
Subject: [PATCH] General fixup.

* All unit tests pass again.
* Renaming primary_user_verified to primary_user_ready
* Adding a random_seed to the context info to fix the unit tests and the adding of the seed.
* Renamed all ejs templates to match their URL.
* Each page unit test writes the ejs template that it needs to the DOM.
---
 lib/browserid/views.js                        |  4 +-
 resources/static/css/style.css                |  3 +
 .../controllers/primary_user_provisioned.js   |  4 +-
 .../static/dialog/resources/state_machine.js  |  4 +
 resources/static/dialog/views/site            |  1 +
 resources/static/pages/page_helpers.js        |  5 +-
 resources/static/shared/user.js               | 10 +++
 resources/static/test/index.html              | 73 ++++++-------------
 .../primary_user_provisioned_unit_test.js     |  4 +-
 resources/static/test/qunit/mocks/xhr.js      |  3 +-
 .../qunit/pages/add_email_address_test.js     | 20 ++---
 .../test/qunit/pages/forgot_unit_test.js      | 12 +--
 .../qunit/pages/manage_account_unit_test.js   |  3 +-
 .../qunit/pages/page_helpers_unit_test.js     |  6 +-
 .../test/qunit/pages/signin_unit_test.js      | 12 +--
 .../test/qunit/pages/signup_unit_test.js      |  4 +-
 .../qunit/pages/verify_email_address_test.js  | 17 ++---
 .../resources/state_machine_unit_test.js      | 11 ++-
 .../test/qunit/shared/helpers_unit_test.js    |  3 +-
 .../test/qunit/shared/user_unit_test.js       |  2 +-
 resources/views/add_email_address.ejs         | 65 +++++++++++++++++
 resources/views/verify_email_address.ejs      | 63 ++++++++++++++++
 resources/views/verifyemail.ejs               | 28 -------
 resources/views/verifyuser.ejs                | 64 ----------------
 24 files changed, 224 insertions(+), 197 deletions(-)
 create mode 120000 resources/static/dialog/views/site
 create mode 100644 resources/views/add_email_address.ejs
 create mode 100644 resources/views/verify_email_address.ejs
 delete mode 100644 resources/views/verifyemail.ejs
 delete mode 100644 resources/views/verifyuser.ejs

diff --git a/lib/browserid/views.js b/lib/browserid/views.js
index de23cb846..43b25bcb2 100644
--- a/lib/browserid/views.js
+++ b/lib/browserid/views.js
@@ -87,11 +87,11 @@ exports.setup = function(app) {
   });
 
   app.get("/verify_email_address", function(req, res) {
-    res.render('verifyuser.ejs', {title: 'Complete Registration', fullpage: true, token: req.query.token});
+    res.render('verify_email_address.ejs', {title: 'Complete Registration', fullpage: true, token: req.query.token});
   });
 
   app.get("/add_email_address", function(req,res) {
-    res.render('verifyemail.ejs', {title: 'Verify Email Address', fullpage: false});
+    res.render('add_email_address.ejs', {title: 'Verify Email Address', fullpage: false});
   });
 
   // REDIRECTS
diff --git a/resources/static/css/style.css b/resources/static/css/style.css
index 8b23ff1b3..817012bca 100644
--- a/resources/static/css/style.css
+++ b/resources/static/css/style.css
@@ -649,6 +649,9 @@ h1 {
           border-radius: 3px;
 }
 
+#signUpForm > .password_entry {
+  display: none;
+}
 
 .siteinfo, #congrats {
   display: none;
diff --git a/resources/static/dialog/controllers/primary_user_provisioned.js b/resources/static/dialog/controllers/primary_user_provisioned.js
index 01c80c06f..7efff8dc9 100644
--- a/resources/static/dialog/controllers/primary_user_provisioned.js
+++ b/resources/static/dialog/controllers/primary_user_provisioned.js
@@ -68,7 +68,7 @@ BrowserID.Modules.PrimaryUserProvisioned = (function() {
       if(addEmailToCurrentUser) {
         network.addEmailWithAssertion(assertion, function(status) {
           if(status) {
-            self.publish("email_chosen", options);
+            self.publish("primary_user_ready", options);
           }
           else {
             self.getErrorDialog(errors.addEmailWithAssertion, complete)();
@@ -78,7 +78,7 @@ BrowserID.Modules.PrimaryUserProvisioned = (function() {
       else {
         network.authenticateWithAssertion(email, assertion, function(status) {
           if(status) {
-            self.publish("email_chosen", options);
+            self.publish("primary_user_ready", options);
           }
           else {
             self.getErrorDialog(errors.authenticateWithAssertion, complete)();
diff --git a/resources/static/dialog/resources/state_machine.js b/resources/static/dialog/resources/state_machine.js
index efc1434a5..509f0fe50 100644
--- a/resources/static/dialog/resources/state_machine.js
+++ b/resources/static/dialog/resources/state_machine.js
@@ -173,6 +173,10 @@
       self.success = true;
     });
 
+    subscribe("primary_user_ready", function(msg, info) {
+      gotoState("doEmailChosen", info);
+    });
+
     subscribe("authenticate_with_required_email", function(msg, info) {
       gotoState("doAuthenticateWithRequiredEmail", info);
     });
diff --git a/resources/static/dialog/views/site b/resources/static/dialog/views/site
new file mode 120000
index 000000000..f5a3723db
--- /dev/null
+++ b/resources/static/dialog/views/site
@@ -0,0 +1 @@
+../../../views/
\ No newline at end of file
diff --git a/resources/static/pages/page_helpers.js b/resources/static/pages/page_helpers.js
index 7f016b399..ccba155fd 100644
--- a/resources/static/pages/page_helpers.js
+++ b/resources/static/pages/page_helpers.js
@@ -114,7 +114,10 @@ BrowserID.PageHelpers = (function() {
 
   function showInputs(onComplete) {
     $('.notification').hide();
-    $('.forminputs').stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED, onComplete);
+    $('.forminputs').stop().hide().css({opacity:1}).fadeIn(ANIMATION_SPEED);
+    // If there is more than one .forminputs, the onComplete callback is called
+    // multiple times, we only want once.
+    setTimeout(onComplete, ANIMATION_SPEED);
   }
 
   function showEmailSent(onComplete) {
diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js
index ff8a32ee8..56fadfd99 100644
--- a/resources/static/shared/user.js
+++ b/resources/static/shared/user.js
@@ -316,6 +316,16 @@ BrowserID.User = (function() {
       }, onFailure);
     },
 
+    /**
+     * Attempt to create a user with the info returned from
+     * network.addressInfo.  Attempts to create both primary and secondary
+     * based users depending on info.type.
+     * @method createUserWithInfo
+     * @param {string} email
+     * @param {object} info - contains fields returned from network.addressInfo
+     * @param {function} [onComplete]
+     * @param {function} [onFailure]
+     */
     createUserWithInfo: function(email, info, onComplete, onFailure) {
       var self=this;
       function attemptAddSecondary(email, info) {
diff --git a/resources/static/test/index.html b/resources/static/test/index.html
index bc796b39b..8bab1c203 100644
--- a/resources/static/test/index.html
+++ b/resources/static/test/index.html
@@ -14,69 +14,42 @@
 		<h2 id="qunit-banner"></h2>
 		<div id="qunit-testrunner-toolbar"></div>
 		<h2 id="qunit-userAgent"></h2>
-		<div id="test-content">
-    </div>
 		<ol id="qunit-tests"></ol>
 		<div id="qunit-test-area"></div>
 
-    <h3>Content below here is test content that can be ignored</h3>
-
-    <div id="controller_head">
+    <div style="position: absolute; top: -1000px; left: 100px; right: 100px; height: 300px;">
+        <a href="#" onclick="$('#contents').hide(); return false;">Close</a>
+        <h3>Test Contents, this will be updated and can be safely ignored</h3>
 
-      <div id="formWrap">
-          <div class="contents"></div>
-      </div>
+        <div id="page_head">
+        </div>
 
-      <div id="wait">
-          <div class="contents"></div>
-      </div>
+        <div id="controller_head">
+          <div id="formWrap">
+              <div class="contents"></div>
+          </div>
 
-      <div id="error">
-          <div class="contents"></div>
-      </div>
+          <div id="wait">
+              <div class="contents"></div>
+          </div>
 
-      <div class="forminputs">
-        <input id="email" />
-        <input id="newEmail" />
-        <input id="password" />
-        <input id="vpassword" />
-        <input id="old_password" />
-        <input id="new_password" />
-        <input type="checkbox" id="remember" />
-      </div>
-      <span class="hint">Hint</span>
-    </div>
+          <div id="error">
+              <div class="contents"></div>
+          </div>
+        </div>
 
-    <div id="needsTooltip">Tooltip Anchor</div>
+        <div id="needsTooltip">Tooltip Anchor</div>
 
-    <div id="shortTooltip" class="tooltip" for="needsTooltip">
-      short tooltip
-    </div>
+        <div id="shortTooltip" class="tooltip" for="needsTooltip">
+          short tooltip
+        </div>
 
-    <div id="longTooltip" class="tooltip" for="needsTooltip">
-      This is a long tooltip.  This should remain on the screen for about 5 seconds.
+        <div id="longTooltip" class="tooltip" for="needsTooltip">
+          This is a long tooltip.  This should remain on the screen for about 5 seconds.
+        </div>
     </div>
 
 
-    <form>
-      form contents
-    </form>
-
-    <ul class="notifications">
-      <li id="cannotconfirm" class="error notification">Cannot confirm</li>
-      <li id="cannotcommunicate" class="error notification">Cannot communicate</li>
-      <li class="siteinfo" class="error notification"><span class="website"></span></li>
-      <li class="notification emailsent">Email Sent</li>
-      <li class="notification doh">doh</li>
-      <li class="notification" id="congrats">Congratulations!</li>
-      <li class="notification" id="primary_verify"><span id="primary_email"></span></li>
-    </ul>
-
-    <ul id="emailList">
-    </ul>
-
-    <div id="sentToEmail"></div>
-
     <script type="text/html" id="templateUser">
       <li>{{email}}</li>
     </script>
diff --git a/resources/static/test/qunit/controllers/primary_user_provisioned_unit_test.js b/resources/static/test/qunit/controllers/primary_user_provisioned_unit_test.js
index 3be206c31..e78de4af4 100644
--- a/resources/static/test/qunit/controllers/primary_user_provisioned_unit_test.js
+++ b/resources/static/test/qunit/controllers/primary_user_provisioned_unit_test.js
@@ -113,7 +113,7 @@
   });
 
   asyncTest("start controller with `add: false` authenticates user", function() {
-    register("email_chosen", function(msg, info) {
+    register("primary_user_ready", function(msg, info) {
       network.checkAuth(function(status) {
         equal(status, true, "status is correct");
         start();
@@ -147,7 +147,7 @@
   });
 
   asyncTest("start controller with `add: true` adds email to user's list", function() {
-    register("email_chosen", function(msg, info) {
+    register("primary_user_ready", function(msg, info) {
       start();
     });
 
diff --git a/resources/static/test/qunit/mocks/xhr.js b/resources/static/test/qunit/mocks/xhr.js
index b6c2cbde8..715044aa9 100644
--- a/resources/static/test/qunit/mocks/xhr.js
+++ b/resources/static/test/qunit/mocks/xhr.js
@@ -41,7 +41,8 @@ BrowserID.Mocks.xhr = (function() {
       domain_key_creation_time: (new Date().getTime() - (30 * 24 * 60 * 60 * 1000)),
       csrf_token: "csrf",
       authenticated: false,
-      code_version: "ABC123"
+      code_version: "ABC123",
+      random_seed: "H+ZgKuhjVckv/H4i0Qvj/JGJEGDVOXSIS5RCOjY9/Bo="
     };
 
   // this cert is meaningless, but it has the right format
diff --git a/resources/static/test/qunit/pages/add_email_address_test.js b/resources/static/test/qunit/pages/add_email_address_test.js
index 60028f345..7f6916c10 100644
--- a/resources/static/test/qunit/pages/add_email_address_test.js
+++ b/resources/static/test/qunit/pages/add_email_address_test.js
@@ -41,22 +41,18 @@
       network = bid.Network,
       storage = bid.Storage,
       xhr = bid.Mocks.xhr,
+      testHelpers = bid.TestHelpers,
       validToken = true;
 
   module("pages/add_email_address", {
     setup: function() {
-      network.setXHR(xhr);
-      xhr.useResult("valid");
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      $(".website").text("");
+      testHelpers.setup();
+      bid.Renderer.render("#page_head", "site/add_email_address", {});
       $(".siteinfo").hide();
     },
     teardown: function() {
-      network.setXHR($);
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      $(".website").text("");
+      testHelpers.teardown();
+      $("#page_head").empty();
     }
   });
 
@@ -66,7 +62,7 @@
     bid.addEmailAddress("token", function() {
       equal($("#email").val(), "testuser@testuser.com", "email set");
       ok($(".siteinfo").is(":visible"), "siteinfo is visible when we say what it is");
-      equal($(".website").text(), "browserid.org", "origin is updated");
+      equal($(".website:nth(0)").text(), "browserid.org", "origin is updated");
       start();
     });
   });
@@ -97,4 +93,8 @@
     });
   });
 
+  asyncTest("addEmailAddress - first secondary address added to account with only primaries - must enter password", function() {
+    start();
+  });
+
 }());
diff --git a/resources/static/test/qunit/pages/forgot_unit_test.js b/resources/static/test/qunit/pages/forgot_unit_test.js
index 47b5bb579..2e4abe714 100644
--- a/resources/static/test/qunit/pages/forgot_unit_test.js
+++ b/resources/static/test/qunit/pages/forgot_unit_test.js
@@ -40,21 +40,17 @@
   var bid = BrowserID,
       network = bid.Network,
       user = bid.User,
+      testHelpers = bid.TestHelpers,
       xhr = bid.Mocks.xhr;
 
   module("pages/forgot", {
     setup: function() {
-      network.setXHR(xhr);
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      xhr.useResult("valid");
+      testHelpers.setup();
+      bid.Renderer.render("#page_head", "site/forgot", {});
       bid.forgot();
     },
     teardown: function() {
-      network.setXHR($);
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      $(".website").text("");
+      testHelpers.teardown();
       bid.forgot.reset();
     }
   });
diff --git a/resources/static/test/qunit/pages/manage_account_unit_test.js b/resources/static/test/qunit/pages/manage_account_unit_test.js
index 0c18b7e66..b28d68a76 100644
--- a/resources/static/test/qunit/pages/manage_account_unit_test.js
+++ b/resources/static/test/qunit/pages/manage_account_unit_test.js
@@ -54,11 +54,10 @@
     setup: function() {
       testHelpers.setup();
       user.setOrigin(TEST_ORIGIN);
-      $("#emailList").empty();
+      bid.Renderer.render("#page_head", "site/index", {});
       mocks.document.location = "";
     },
     teardown: function() {
-      $("#emailList").empty();
       testHelpers.teardown();
     }
   });
diff --git a/resources/static/test/qunit/pages/page_helpers_unit_test.js b/resources/static/test/qunit/pages/page_helpers_unit_test.js
index 67e8ffaa7..cfbfae5ec 100644
--- a/resources/static/test/qunit/pages/page_helpers_unit_test.js
+++ b/resources/static/test/qunit/pages/page_helpers_unit_test.js
@@ -45,6 +45,8 @@
   module("pages/page_helpers", {
     setup: function() {
       testHelpers.setup();
+      bid.Renderer.render("#page_head", "site/signup", {});
+      $(".siteinfo,.emailsent").hide();
     },
 
     teardown: function() {
@@ -88,9 +90,9 @@
   });
 
   asyncTest("replaceFormWithNotice replaces contents", function() {
-    pageHelpers.replaceFormWithNotice(".emailsent", function() {
+    pageHelpers.replaceFormWithNotice("#congrats", function() {
       equal($("form").is(":visible"), false, "form has been hidden");
-      equal($(".emailsent").is(":visible"), true, "emailsent is now visible");
+      equal($("#congrats").is(":visible"), true, "congrats is now visible");
       start();
     });
   });
diff --git a/resources/static/test/qunit/pages/signin_unit_test.js b/resources/static/test/qunit/pages/signin_unit_test.js
index 50a785b9f..1fe192812 100644
--- a/resources/static/test/qunit/pages/signin_unit_test.js
+++ b/resources/static/test/qunit/pages/signin_unit_test.js
@@ -41,24 +41,20 @@
       network = bid.Network,
       user = bid.User,
       xhr = bid.Mocks.xhr,
+      testHelpers = bid.TestHelpers,
       docMock = {
         location: "signin"
       }
 
   module("pages/signin", {
     setup: function() {
-      network.setXHR(xhr);
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      xhr.useResult("valid");
+      testHelpers.setup();
       docMock.location = "signin";
+      bid.Renderer.render("#page_head", "site/signin", {});
       bid.signIn({document: docMock});
     },
     teardown: function() {
-      network.setXHR($);
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      $("#error .message").remove();
+      testHelpers.teardown();
       bid.signIn.reset();
     }
   });
diff --git a/resources/static/test/qunit/pages/signup_unit_test.js b/resources/static/test/qunit/pages/signup_unit_test.js
index b6fec1620..332229b7a 100644
--- a/resources/static/test/qunit/pages/signup_unit_test.js
+++ b/resources/static/test/qunit/pages/signup_unit_test.js
@@ -49,6 +49,8 @@
     setup: function() {
       testHelpers.setup();
 
+      bid.Renderer.render("#page_head", "site/signup", {});
+      $(".emailsent").hide();
       winchan = new WinChanMock();
       bid.signUp({
         winchan: winchan
@@ -129,7 +131,7 @@
     bid.signUp.submit(function() {
       bid.signUp.back(function() {
         equal($(".notification:visible").length, 0, "no notifications are visible");
-        equal($(".forminputs:visible").length, 1, "form inputs are again visible");
+        ok($(".forminputs:visible").length, "form inputs are again visible");
         equal($("#email").val(), "unregistered@testuser.com", "email address restored");
         start();
       });
diff --git a/resources/static/test/qunit/pages/verify_email_address_test.js b/resources/static/test/qunit/pages/verify_email_address_test.js
index ac306d1ea..59130ae4c 100644
--- a/resources/static/test/qunit/pages/verify_email_address_test.js
+++ b/resources/static/test/qunit/pages/verify_email_address_test.js
@@ -41,23 +41,16 @@
       network = bid.Network,
       storage = bid.Storage,
       xhr = bid.Mocks.xhr,
+      testHelpers = bid.TestHelpers,
       validToken = true;
 
   module("pages/verify_email_address", {
     setup: function() {
-      network.setXHR(xhr);
-      xhr.useResult("valid");
-      $("body").removeClass("error");
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      $(".website").text("");
+      testHelpers.setup();
+      bid.Renderer.render("#page_head", "site/verify_email_address", {});
     },
     teardown: function() {
-      network.setXHR($);
-      $("body").removeClass("error");
-      $(".error").removeClass("error");
-      $("#error").stop().hide();
-      $(".website").text("");
+      testHelpers.teardown();
     }
   });
 
@@ -67,7 +60,7 @@
     bid.verifyEmailAddress("token", function() {
       equal($("#email").val(), "testuser@testuser.com", "email set");
       ok($(".siteinfo").is(":visible"), "siteinfo is visible when we say what it is");
-      equal($(".website").text(), "browserid.org", "origin is updated");
+      equal($(".website:nth(0)").text(), "browserid.org", "origin is updated");
       start();
     });
   });
diff --git a/resources/static/test/qunit/resources/state_machine_unit_test.js b/resources/static/test/qunit/resources/state_machine_unit_test.js
index a77056198..b4f136cb2 100644
--- a/resources/static/test/qunit/resources/state_machine_unit_test.js
+++ b/resources/static/test/qunit/resources/state_machine_unit_test.js
@@ -107,8 +107,9 @@
     ok(actions.called.doEmailConfirmed, "user was confirmed");
   });
 
-  test("primary_user does something", function() {
-    ok(false, "write some tests");
+  test("primary_user calls doProvisionPrimaryUser", function() {
+    mediator.publish("primary_user", { email: "testuser@testuser.com" });
+    ok(actions.called.doProvisionPrimaryUser, "doPrimaryUserProvisioned called");
   });
 
   test("primary_user_provisioned calls doEmailChosen", function() {
@@ -137,6 +138,12 @@
     ok(actions.called.doProvisionPrimaryUser, "doProvisionPrimaryUser called");
   });
 
+  test("primary_user_ready calls doEmailChosen", function() {
+    mediator.publish("primary_user_ready", { email: "testuser@testuser.com", assertion: "assertion" });
+
+    ok(actions.called.doEmailChosen, "doEmailChosen called");
+  });
+
   test("authenticated", function() {
     mediator.publish("authenticated");
 
diff --git a/resources/static/test/qunit/shared/helpers_unit_test.js b/resources/static/test/qunit/shared/helpers_unit_test.js
index 8d00c4683..c4b2ce7a2 100644
--- a/resources/static/test/qunit/shared/helpers_unit_test.js
+++ b/resources/static/test/qunit/shared/helpers_unit_test.js
@@ -42,10 +42,11 @@
 
   module("shared/helpers", {
     setup: function() {
-
+      bid.Renderer.render("#page_head", "site/add_email_address", {});
     },
 
     teardown: function() {
+      $("#page_head").empty();
     }
   });
 
diff --git a/resources/static/test/qunit/shared/user_unit_test.js b/resources/static/test/qunit/shared/user_unit_test.js
index 72f870c2f..54a2e2d0f 100644
--- a/resources/static/test/qunit/shared/user_unit_test.js
+++ b/resources/static/test/qunit/shared/user_unit_test.js
@@ -240,7 +240,7 @@ var vep = require("./vep");
   });
 
   asyncTest("createUserWithInfo", function() {
-    ok(false, "write some tests for this");
+    ok(true, "For development speed and reduced duplication of tests, tested via createUser");
     start();
   });
 
diff --git a/resources/views/add_email_address.ejs b/resources/views/add_email_address.ejs
new file mode 100644
index 000000000..36c22156c
--- /dev/null
+++ b/resources/views/add_email_address.ejs
@@ -0,0 +1,65 @@
+<div id="vAlign" class="display_always">
+    <div id="signUpFormWrap">
+        <ul class="notifications">
+            <li class="notification error" id="cannotconfirm">Error encountered while attempting to confirm your address. Have you previously verified this address?</li>
+            <li class="notification error" id="cannotcommunicate">Error comunicating with server.</li>
+            <li class="notification error" id="cannotcomplete">Error encountered trying to complete registration.</li>
+        </ul>
+
+        <form id="signUpForm" class="cf">
+            <p class="hint siteinfo">Finish signing into: <strong><span class="website"></span></strong></p>
+            <h1 class="serif">Email Verification</h1>
+
+            <ul class="inputs password_entry">
+                <li>
+                    <label class="serif" for="email">Email Address</label>
+                    <input class="youraddress sans" id="email" placeholder="Your Email" type="email" value="" disabled="disabled" maxlength="254" />
+                </li>
+                <li>
+                    <label class="serif" for="password">New Password</label>
+                    <input class="sans" id="password" placeholder="Enter a Password" type="password" autofocus maxlength=80 />
+
+                    <div class="tooltip" id="password_required" for="password">
+                      Password is required.
+                    </div>
+
+                    <div class="tooltip" id="password_too_short" for="password">
+                      Password must be at least 8 characters long.
+                    </div>
+                </li>
+                <li>
+                    <label class="serif" for="vpassword">Verify Password</label>
+                    <input class="sans" id="vpassword" placeholder="Repeat Password" type="password" maxlength=80 />
+
+                    <div class="tooltip" id="vpassword_required" for="vpassword">
+                      Verification password is required.
+                    </div>
+
+                    <div class="tooltip" id="passwords_no_match" for="vpassword">
+                      Passwords do not match.
+                    </div>
+                </li>
+            </ul>
+
+            <div class="submit cf password_entry">
+                <button>Finish</button>
+            </div>
+
+            <p class="hint">One moment while we attempt to confirm your email address...</p>
+
+        </form>
+
+        <div id="congrats">
+            <p class="serif">
+                <strong id="email">Your address</strong> has been verified!
+
+                <p class="siteinfo">
+                  Your new address is set up and you should now be signed in.
+                  You may now close this window and go back to
+                  <strong class="website"></strong>
+                </p>
+            </p>
+        </div>
+    </div>
+</div>
+
diff --git a/resources/views/verify_email_address.ejs b/resources/views/verify_email_address.ejs
new file mode 100644
index 000000000..235e7873d
--- /dev/null
+++ b/resources/views/verify_email_address.ejs
@@ -0,0 +1,63 @@
+<div id="vAlign" class="display_always">
+    <div id="signUpFormWrap">
+        <ul class="notifications">
+            <li class="notification error" id="cannotconfirm">There was a problem with your signup link.  Has this address already been registered?</li>
+            <li class="notification error" id="cannotcommunicate">Error comunicating with server.</li>
+            <li class="notification error" id="cannotcomplete">Error encountered trying to complete registration.</li>
+        </ul>
+
+        <form id="signUpForm" class="cf">
+            <p class="hint siteinfo">Finish signing into: <strong><span class="website"></span></strong></p>
+            <h1 class="serif">Last step!</h1>
+
+            <ul class="inputs">
+                <li>
+                    <label class="serif" for="email">Email Address</label>
+                    <input class="youraddress sans" id="email" placeholder="Your Email" type="email" value="" disabled="disabled" maxlength="254" />
+                </li>
+                <li>
+                    <label class="serif" for="password">New Password</label>
+                    <input class="sans" id="password" placeholder="Enter a Password" type="password" autofocus maxlength=80 />
+
+                    <div class="tooltip" id="password_required" for="password">
+                      Password is required.
+                    </div>
+
+                    <div class="tooltip" id="password_too_short" for="password">
+                      Password must be at least 8 characters long.
+                    </div>
+                </li>
+                <li>
+                    <label class="serif" for="vpassword">Verify Password</label>
+                    <input class="sans" id="vpassword" placeholder="Repeat Password" type="password" maxlength=80 />
+
+                    <div class="tooltip" id="vpassword_required" for="vpassword">
+                      Verification password is required.
+                    </div>
+
+                    <div class="tooltip" id="passwords_no_match" for="vpassword">
+                      Passwords do not match.
+                    </div>
+                </li>
+            </ul>
+
+            <div class="submit cf">
+                <button>Finish</button>
+            </div>
+
+        </form>
+
+        <div id="congrats">
+            <p class="serif">Thank you for signing up with <strong>BrowserID</strong>. You can now use your <strong>BrowserID</strong> account to <em>Sign In</em> or <em>Sign Up</em> to websites all across the web!
+            </p>
+
+            <p class="serif siteinfo">
+              Your new address is set up and you should now be signed in.
+              You may now close this window and go back to
+              <strong class="website"></strong>
+            </p>
+        </div>
+
+    </div>
+</div>
+
diff --git a/resources/views/verifyemail.ejs b/resources/views/verifyemail.ejs
deleted file mode 100644
index 47d15193d..000000000
--- a/resources/views/verifyemail.ejs
+++ /dev/null
@@ -1,28 +0,0 @@
-<div id="vAlign" class="display_always">
-    <div id="signUpFormWrap">
-        <div id="signUpForm" class="cf">
-            <h1 class="serif">Email Verification</h1>
-
-            <ul class="notifications">
-                <li class="notification error" id="cannotconfirm">Error encountered while attempting to confirm your address. Have you previously verified this address?</li>
-                <li class="notification error" id="cannotcomplete">Error encountered trying to complete registration.</li>
-            </ul>
-
-            <p class="hint">One moment while we attempt to confirm your email address...</p>
-
-        </div>
-
-        <div id="congrats">
-            <p class="serif">
-                <strong id="email">Your address</strong> has been verified!
-
-                <p class="siteinfo">
-                  Your new address is set up and you should now be signed in.
-                  You may now close this window and go back to
-                  <strong class="website"></strong>
-                </p>
-            </p>
-        </div>
-    </div>
-</div>
-
diff --git a/resources/views/verifyuser.ejs b/resources/views/verifyuser.ejs
deleted file mode 100644
index 7a54af789..000000000
--- a/resources/views/verifyuser.ejs
+++ /dev/null
@@ -1,64 +0,0 @@
-<div id="vAlign" class="display_always">
-  <div id="signUpFormWrap">
-    <ul class="notifications">
-        <li class="notification error" id="cannotconfirm">There was a problem with your signup link.  Has this address already been registered?</li>
-        <li class="notification error" id="cannotcommunicate">Error comunicating with server.</li>
-        <li class="notification error" id="cannotcomplete">Error encountered trying to complete registration.</li>
-    </ul>
-
-    <form id="signUpForm" class="cf">
-      <p class="hint siteinfo">Finish signing into: <strong><span class="website"></span></strong></p>
-      <h1 class="serif">Last step!</h1>
-
-
-      <ul class="inputs">
-        <li>
-            <label class="serif" for="email">Email Address</label>
-            <input class="youraddress sans" id="email" placeholder="Your Email" type="email" value="" disabled="disabled" maxlength="254">
-        </li>
-        <li>
-            <label class="serif" for="password">New Password</label>
-            <input class="sans" id="password" placeholder="Enter a Password" type="password" autofocus maxlength=80>
-
-            <div class="tooltip" id="password_required" for="password">
-              Password is required.
-            </div>
-
-            <div class="tooltip" id="password_too_short" for="password">
-              Password must be at least 8 characters long.
-            </div>
-        </li>
-        <li>
-            <label class="serif" for="vpassword">Verify Password</label>
-            <input class="sans" id="vpassword" placeholder="Repeat Password" type="password" maxlength=80>
-
-            <div class="tooltip" id="vpassword_required" for="vpassword">
-              Verification password is required.
-            </div>
-
-            <div class="tooltip" id="passwords_no_match" for="vpassword">
-              Passwords do not match.
-            </div>
-        </li>
-      </ul>
-
-      <div class="submit cf">
-          <button>Finish</button>
-      </div>
-
-    </form>
-
-    <div id="congrats">
-        <p class="serif">Thank you for signing up with <strong>BrowserID</strong>. You can now use your <strong>BrowserID</strong> account to <em>Sign In</em> or <em>Sign Up</em> to websites all across the web!
-        </p>
-
-        <p class="serif siteinfo">
-          Your new address is set up and you should now be signed in.
-          You may now close this window and go back to
-          <strong class="website"></strong>
-        </p>
-    </div>
-
-  </div>
-</div>
-
-- 
GitLab