diff --git a/lib/browserid/prove_template.ejs b/lib/browserid/prove_template.ejs index d9bd314860831e56c4bb86b28586153cb20320d8..d20e219da9555171ef51302105a93acec5549179 100644 --- a/lib/browserid/prove_template.ejs +++ b/lib/browserid/prove_template.ejs @@ -6,5 +6,5 @@ <%= gettext('If you are NOT trying to sign into this site, just ignore this email.') %> <%= gettext('Thanks,') %> -<%= gettext('BrowserID') %> +<%= gettext('Persona') %> <%= gettext('(A better way to sign in)') %> diff --git a/package.json b/package.json index fac169eda190ea9b0407b0c6cf92218152a219d4..7801ed885964e53f924355ddae3bb3d909007649 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "devDependencies": { "vows": "0.5.13", - "awsbox": "0.2.11", + "awsbox": "0.2.12", "irc": "0.3.3" }, "scripts": { diff --git a/resources/static/communication_iframe/start.js b/resources/static/communication_iframe/start.js index 57ce36dcaca52ba1d78fc3db41208e89371444ec..fa26648aef2caed72eeb18c9a81b2259cee266c5 100644 --- a/resources/static/communication_iframe/start.js +++ b/resources/static/communication_iframe/start.js @@ -9,6 +9,11 @@ user = bid.User, storage = bid.Storage; + // Initialize all localstorage values to default values. Neccesary for + // proper sync of IE8 localStorage across multiple simultaneous + // browser sessions. + storage.setDefaultValues(); + network.init(); var chan = Channel.build({ diff --git a/resources/static/css/style.css b/resources/static/css/style.css index 35bfa524ab66efd353488ddd596061022bb3fc77..94aac066d5eea89dbaef6c4d9df944a96b34ffaa 100644 --- a/resources/static/css/style.css +++ b/resources/static/css/style.css @@ -515,30 +515,10 @@ button.delete:active { padding: 0; } -#signUpForm .red { - color: red; -} - #signUpForm .submit { height: 28px; } -#signUpForm .error { - margin-top: 20px; - color: red; - background-color: rgba(255,0,0,0.25); - -ms-filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3fff0000,endColorstr=#3fff0000); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3fff0000,endColorstr=#3fff0000); - zoom: 1; - padding: 5px; - line-height: 16px; - - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; -} - #signUpForm > .siteinfo { margin-bottom: 10px; } diff --git a/resources/static/dialog/controllers/dialog.js b/resources/static/dialog/controllers/dialog.js index 34f9f2f135c30e7d76370e85e555b072274ba230..7e40c8c531c50ae78e90a79a06045908ef0a2b49 100644 --- a/resources/static/dialog/controllers/dialog.js +++ b/resources/static/dialog/controllers/dialog.js @@ -174,6 +174,11 @@ BrowserID.Modules.Dialog = (function() { // that come from other domains, only allow absolute paths from the // origin. params.siteLogo = fixupAbsolutePath(origin_url, paramsFromRP.siteLogo); + // To avoid mixed content errors, only allow siteLogos to be served + // from https RPs + if (URLParse(origin_url).scheme !== "https") { + throw "only https sites can specify a siteLogo"; + } } if (paramsFromRP.siteName) { diff --git a/resources/static/dialog/views/error.ejs b/resources/static/dialog/views/error.ejs index 0b35cd680dc17fcb47e25adc6284ae7cce111b46..2a0ee0066700746b6c73e31818f4353ee1156976 100644 --- a/resources/static/dialog/views/error.ejs +++ b/resources/static/dialog/views/error.ejs @@ -14,6 +14,10 @@ <%= gettext("Persona requires cookies") %> </h2> <%= format(gettext("Please close this window, <a %s>enable cookies</a> and try again"), [" target='_blank' href='http://support.mozilla.org/en-US/kb/Websites%20say%20cookies%20are%20blocked'"]) %> + <% } else if(typeof title === "string") { %> + <h2> + <span class="emphasis"><%= title %></span> + </h2> <% } else { %> <h2 id="defaultError"> <%= gettext("We are very sorry.") %><span class="emphasis"> <%= gettext("There has been an error!") %></span> diff --git a/resources/static/i/badge.png b/resources/static/i/badge.png index 1af14efe525f3e2291cd88d37d195b147801d504..2b082db5dd486134b6c1fa86f5e609dff6c0f8c0 100644 Binary files a/resources/static/i/badge.png and b/resources/static/i/badge.png differ diff --git a/resources/static/i/button-arrow.png b/resources/static/i/button-arrow.png index 2ec7e2609a4bf633b1fdfc1fb0d5bc65c2db56cb..b5d7a1d87635c7e9719b52970604ad060a599fbb 100644 Binary files a/resources/static/i/button-arrow.png and b/resources/static/i/button-arrow.png differ diff --git a/resources/static/i/count.png b/resources/static/i/count.png index 2f031bd84fd4528f74782eb417fef154e3c7f811..b6bccc3dc40388432b3ede95ce1204d50a5f78a1 100644 Binary files a/resources/static/i/count.png and b/resources/static/i/count.png differ diff --git a/resources/static/i/firefox_logo.png b/resources/static/i/firefox_logo.png index c55a338081cc1e0f1d2e78fc50226695c0b37488..c4dad373e1f95655102af8fa3a617324539e8402 100644 Binary files a/resources/static/i/firefox_logo.png and b/resources/static/i/firefox_logo.png differ diff --git a/resources/static/i/grain.png b/resources/static/i/grain.png index 2980ee90e52f15cd22eabebf59344fca831e7410..796f5fbeb24967faaf3046b51de12b0f9048e32b 100644 Binary files a/resources/static/i/grain.png and b/resources/static/i/grain.png differ diff --git a/resources/static/i/marketplace-header.png b/resources/static/i/marketplace-header.png index 03286253845256e4166036d2d933cdd2fcc1b3b1..5dbb70f6c1a8700932eda4f58899cf3cbfd5aea8 100644 Binary files a/resources/static/i/marketplace-header.png and b/resources/static/i/marketplace-header.png differ diff --git a/resources/static/i/persona-logo-transparent.png b/resources/static/i/persona-logo-transparent.png index 5484f73c13f1f0a8295a6bacf0792c57e2b4f567..c249e97fa2daf6de091f0d78a702872c0a7bafd5 100644 Binary files a/resources/static/i/persona-logo-transparent.png and b/resources/static/i/persona-logo-transparent.png differ diff --git a/resources/static/i/persona-logo-wordmark.png b/resources/static/i/persona-logo-wordmark.png index f64670ec0b53e2f8ed6f136eb0b288e955b9054a..38e0804a30ada75db73f7832b266914f4aa3bb45 100644 Binary files a/resources/static/i/persona-logo-wordmark.png and b/resources/static/i/persona-logo-wordmark.png differ diff --git a/resources/static/i/tutorial_1.png b/resources/static/i/tutorial_1.png index a19fac78c3d591d55d96c08ed2df2a477e650483..eebf4b458198996f902493f577d120e03be877fe 100644 Binary files a/resources/static/i/tutorial_1.png and b/resources/static/i/tutorial_1.png differ diff --git a/resources/static/i/tutorial_2.png b/resources/static/i/tutorial_2.png index 27b66d43a19114e1085cff3e8a71b2d2aa5199f9..11a7bf247fd96bb90e157bd2184a1e7e7174131d 100644 Binary files a/resources/static/i/tutorial_2.png and b/resources/static/i/tutorial_2.png differ diff --git a/resources/static/i/tutorial_3.png b/resources/static/i/tutorial_3.png index f3d0f6d19cdedfc10f2836bfaed47e3a33d5b500..3c6c11efd3f56aeed6bc74b303d9ab4715ea6971 100644 Binary files a/resources/static/i/tutorial_3.png and b/resources/static/i/tutorial_3.png differ diff --git a/resources/static/pages/verify_secondary_address.js b/resources/static/pages/verify_secondary_address.js index df4561ec37b6707e3401afafd4f7c07225ba283a..5b2f7f20051e8bd9c3ce71c181ac75c2cc6c4c69 100644 --- a/resources/static/pages/verify_secondary_address.js +++ b/resources/static/pages/verify_secondary_address.js @@ -19,7 +19,6 @@ BrowserID.verifySecondaryAddress = (function() { tooltip = bid.Tooltip, token, sc, - needsPassword, mustAuth, verifyFunction, doc = document, @@ -29,11 +28,6 @@ BrowserID.verifySecondaryAddress = (function() { redirectTo, redirectTimeout; // set in config if available, use REDIRECT_SECONDS otw. - function showError(el, oncomplete) { - dom.hide(".hint,#signUpForm"); - $(el).fadeIn(ANIMATION_TIME, oncomplete); - } - function showRegistrationInfo(info) { dom.setInner("#email", info.email); @@ -55,38 +49,37 @@ BrowserID.verifySecondaryAddress = (function() { function submit(oncomplete) { var pass = dom.getInner("#password") || undefined, - vpass = dom.getInner("#vpassword") || undefined, - inputValid = (!needsPassword || - validation.passwordAndValidationPassword(pass, vpass)) - && (!mustAuth || - validation.password(pass)); + inputValid = !mustAuth || validation.password(pass); if (inputValid) { user[verifyFunction](token, pass, function(info) { dom.addClass("body", "complete"); - var verified = info.valid, - selector = verified ? "#congrats" : "#cannotcomplete"; - - pageHelpers.replaceFormWithNotice(selector, function() { - if (redirectTo && verified) { - - // set the loggedIn status for the site. This allows us to get - // a silent assertion without relying on the dialog to set the - // loggedIn status for the domain. This is useful when the user - // closes the dialog OR if redirection happens before the dialog - // has had a chance to finish its business. - storage.setLoggedIn(URLParse(redirectTo).originOnly(), email); - - setTimeout(function() { - doc.location.href = redirectTo; + var verified = info.valid; + + if (verified) { + pageHelpers.replaceFormWithNotice("#congrats", function() { + if (redirectTo) { + // set the loggedIn status for the site. This allows us to get + // a silent assertion without relying on the dialog to set the + // loggedIn status for the domain. This is useful when the user + // closes the dialog OR if redirection happens before the dialog + // has had a chance to finish its business. + storage.setLoggedIn(URLParse(redirectTo).originOnly(), email); + + setTimeout(function() { + doc.location.href = redirectTo; + complete(oncomplete, verified); + }, redirectTimeout); + } + else { complete(oncomplete, verified); - }, redirectTimeout); - } - else { - complete(oncomplete, verified); - } - }); + } + }); + } + else { + pageHelpers.showFailure(errors.cannotComplete, info, oncomplete); + } }, function(info) { if (info.network && info.network.status === 401) { tooltip.showTooltip("#cannot_authenticate"); @@ -103,36 +96,30 @@ BrowserID.verifySecondaryAddress = (function() { } function startVerification(oncomplete) { + var self=this; user.tokenInfo(token, function(info) { if (info) { redirectTo = info.returnTo; email = info.email; showRegistrationInfo(info); - needsPassword = info.needs_password; mustAuth = info.must_auth; - - if (needsPassword) { - // This is a fix for legacy users who started the user creation - // process without setting their password in the dialog. If the user - // needs a password, they must set it now. Once all legacy users are - // verified or their links invalidated, this flow can be removed. - dom.addClass("body", "enter_password"); - dom.addClass("body", "enter_verify_password"); - complete(oncomplete, true); - } - else if (mustAuth) { - // These are users who have set their passwords inside of the dialog. + if (mustAuth) { + // These are users who are authenticating in a different browser or + // session than the initiator. dom.addClass("body", "enter_password"); complete(oncomplete, true); } else { - // These are users who do not have to set their passwords at all. + // Easy case where user is in same browser and same session, just + // verify and be done with it all! submit(oncomplete); } } else { - showError("#cannotconfirm"); + // renderError is used directly instead of pageHelpers.showFailure + // because showFailure hides the title in the extended info. + self.renderError("error", errors.cannotConfirm); complete(oncomplete, false); } }, pageHelpers.getFailure(errors.getTokenInfo, oncomplete)); @@ -140,7 +127,8 @@ BrowserID.verifySecondaryAddress = (function() { var Module = bid.Modules.PageModule.extend({ start: function(options) { - this.checkRequired(options, "token", "verifyFunction"); + var self=this; + self.checkRequired(options, "token", "verifyFunction"); token = options.token; verifyFunction = options.verifyFunction; @@ -151,9 +139,9 @@ BrowserID.verifySecondaryAddress = (function() { redirectTimeout = REDIRECT_SECONDS * 1000; } - startVerification(options.ready); + startVerification.call(self, options.ready); - sc.start.call(this, options); + sc.start.call(self, options); }, submit: submit diff --git a/resources/static/shared/error-messages.js b/resources/static/shared/error-messages.js index 2ce74cfde884cc3adb5a4103cd12e30794f5be89..5b3530452890c3d112c358fdc92164a68bda9e85 100644 --- a/resources/static/shared/error-messages.js +++ b/resources/static/shared/error-messages.js @@ -35,6 +35,14 @@ BrowserID.Errors = (function(){ title: "Cancelling User Account" }, + cannotConfirm: { + title: gettext("There was a problem with your signup link. Has this address already been registered?") + }, + + cannotComplete: { + title: gettext("Error encountered trying to complete registration.") + }, + checkAuthentication: { title: "Checking Authentication" }, diff --git a/resources/static/shared/storage.js b/resources/static/shared/storage.js index 7b4e768ac2d2ab3d37e36365fed4b919fd3c039b..4163e0e6bf73f420ca776d9ea5c8f6cb3b180479 100644 --- a/resources/static/shared/storage.js +++ b/resources/static/shared/storage.js @@ -49,11 +49,34 @@ BrowserID.Storage = (function() { function clear() { storage.removeItem("emails"); - storage.removeItem("tempKeypair"); storage.removeItem("siteInfo"); storage.removeItem("managePage"); } + // initialize all localStorage values to default if they are unset. + // this function is only neccesary on IE8 where there are localStorage + // synchronization issues between different browsing contexts, however + // it's intended to avoid IE8 specific bugs from being introduced. + // see issue #1637 + function setDefaultValues() { + _.each({ + emailToUserID: {}, + emails: {}, + interaction_data: {}, + loggedIn: {}, + main_site: {}, + managePage: {}, + returnTo: null, + siteInfo: {}, + stagedOnBehalfOf: null, + usersComputer: {} + }, function(defaultVal, key) { + if (!storage[key]) { + storage[key] = JSON.stringify(defaultVal); + } + }); + } + function getEmails() { try { var emails = JSON.parse(storage.emails || "{}"); @@ -124,28 +147,6 @@ BrowserID.Storage = (function() { } } - function storeTemporaryKeypair(keypair) { - storage.tempKeypair = JSON.stringify({ - publicKey: keypair.publicKey.toSimpleObject(), - secretKey: keypair.secretKey.toSimpleObject() - }); - } - - function retrieveTemporaryKeypair() { - var raw_kp = JSON.parse(storage.tempKeypair || ""); - storage.tempKeypair = null; - if (raw_kp) { - prepareDeps(); - - var kp = {}; - kp.publicKey = jwcrypto.loadPublicKeyFromObject(raw_kp.publicKey); - kp.secretKey = jwcrypto.loadSecretKeyFromObject(raw_kp.secretKey); - return kp; - } else { - return null; - } - } - function setReturnTo(returnToURL) { storage.returnTo = JSON.stringify({ at: new Date().toString(), @@ -588,9 +589,14 @@ BrowserID.Storage = (function() { * @method clear */ clear: clear, - storeTemporaryKeypair: storeTemporaryKeypair, - retrieveTemporaryKeypair: retrieveTemporaryKeypair, setReturnTo: setReturnTo, - getReturnTo: getReturnTo + getReturnTo: getReturnTo, + /** + * Set all used storage values to default if they are unset. This function + * is required for proper localStorage sync between different browsing contexts, + * see issue #1637 for full details. + * @method setDefaultValues + */ + setDefaultValues: setDefaultValues }; }()); diff --git a/resources/static/test/cases/controllers/dialog.js b/resources/static/test/cases/controllers/dialog.js index 3ab6c7d8707b073ac5fda5ef98c48707461e44bc..e7a75af818d6174a4737a623b8c99df74ca15066 100644 --- a/resources/static/test/cases/controllers/dialog.js +++ b/resources/static/test/cases/controllers/dialog.js @@ -560,7 +560,26 @@ }); }); - asyncTest("get with absolute path - allowed URL but it must be properly escaped", function() { + asyncTest("get with absolute path and http RP - not allowed", function() { + createController({ + ready: function() { + mediator.subscribe("start", function(msg, info) { + ok(false, "start should not have been called"); + }); + + var siteLogo = '/i/card.png'; + var retval = controller.get(HTTP_TEST_DOMAIN, { + siteLogo: siteLogo + }); + + equal(retval, "only https sites can specify a siteLogo", "expected error"); + testErrorVisible(); + start(); + } + }); + }); + + asyncTest("get with absolute path and https RP - allowed URL but is properly escaped", function() { createController({ ready: function() { var startInfo; @@ -569,12 +588,12 @@ }); var siteLogo = '/i/card.png" onerror="alert(\'xss\')" <script>alert(\'more xss\')</script>'; - var retval = controller.get(HTTP_TEST_DOMAIN, { + var retval = controller.get(HTTPS_TEST_DOMAIN, { siteLogo: siteLogo }); testHelpers.testObjectValuesEqual(startInfo, { - siteLogo: encodeURI(HTTP_TEST_DOMAIN + siteLogo) + siteLogo: encodeURI(HTTPS_TEST_DOMAIN + siteLogo) }); equal(typeof retval, "undefined", "no error expected"); testErrorNotVisible(); diff --git a/resources/static/test/cases/pages/verify_secondary_address.js b/resources/static/test/cases/pages/verify_secondary_address.js index 0d74afe90af7dc39c853bc3f8860a11adfbac517..ac4ddaa8b832c09fe5a03cd19c8a49a29fdcd37e 100644 --- a/resources/static/test/cases/pages/verify_secondary_address.js +++ b/resources/static/test/cases/pages/verify_secondary_address.js @@ -13,6 +13,7 @@ dom = bid.DOM, testHelpers = bid.TestHelpers, testHasClass = testHelpers.testHasClass, + testVisible = testHelpers.testVisible, validToken = true, controller, config = { @@ -56,7 +57,7 @@ } function testCannotConfirm() { - ok($("#cannotconfirm").is(":visible"), "cannot confirm box is visible"); + testHelpers.testErrorVisible(); } test("start with missing token", function() { @@ -70,22 +71,21 @@ equal(error, "missing config option: token", "correct error thrown"); }); - asyncTest("no password: start with good token and site", function() { + asyncTest("valid token, no password necessary - verify user and show site info", function() { var returnTo = "https://test.domain/path"; storage.setReturnTo(returnTo); createController(config, function() { - testEmail(); - ok($(".siteinfo").is(":visible"), "siteinfo is visible when we say what it is"); - equal($(".website:nth(0)").text(), returnTo, "website is updated"); + testVisible("#congrats"); testHasClass("body", "complete"); + equal($(".website").text(), returnTo, "website is updated"); equal(doc.location.href, returnTo, "redirection occurred to correct URL"); equal(storage.getLoggedIn("https://test.domain"), "testuser@testuser.com", "logged in status set"); start(); }); }); - asyncTest("no password: start with good token and nosite", function() { + asyncTest("valid token, no password necessary, no saved site info - verify user but do not show site info", function() { createController(config, function() { testEmail(); equal($(".siteinfo").is(":visible"), false, "siteinfo is not visible without having it"); @@ -94,7 +94,7 @@ }); }); - asyncTest("no password: start with bad token", function() { + asyncTest("invalid token - show cannot confirm error", function() { xhr.useResult("invalid"); createController(config, function() { @@ -103,7 +103,7 @@ }); }); - asyncTest("no password: start with emailForVerficationToken XHR failure", function() { + asyncTest("valid token with xhr error - show error screen", function() { xhr.useResult("ajaxError"); createController(config, function() { testHelpers.testErrorVisible(); @@ -156,88 +156,4 @@ }); }); - asyncTest("must set password, successful login", function() { - xhr.useResult("needsPassword"); - createController(config, function() { - xhr.useResult("valid"); - - $("#password").val("password"); - $("#vpassword").val("password"); - - testHasClass("body", "enter_password"); - testHasClass("body", "enter_verify_password"); - - controller.submit(function(status) { - equal(status, true, "correct status"); - testHasClass("body", "complete"); - start(); - }); - }); - }); - - asyncTest("must set password, too short a password", function() { - xhr.useResult("needsPassword"); - createController(config, function() { - xhr.useResult("valid"); - - $("#password").val("pass"); - $("#vpassword").val("pass"); - - controller.submit(function(status) { - equal(status, false, "correct status"); - testHelpers.testTooltipVisible(); - start(); - }); - }); - }); - - asyncTest("must set password, too long a password", function() { - xhr.useResult("needsPassword"); - createController(config, function() { - xhr.useResult("valid"); - - var pass = testHelpers.generateString(81); - $("#password").val(pass); - $("#vpassword").val(pass); - - controller.submit(function(status) { - equal(status, false, "correct status"); - testHelpers.testTooltipVisible(); - start(); - }); - }); - }); - - asyncTest("must set password, missing verification password", function() { - xhr.useResult("needsPassword"); - createController(config, function() { - xhr.useResult("valid"); - - $("#password").val("password"); - $("#vpassword").val(""); - - controller.submit(function(status) { - equal(status, false, "correct status"); - testHelpers.testTooltipVisible(); - start(); - }); - }); - }); - - asyncTest("must set password, mismatched passwords", function() { - xhr.useResult("needsPassword"); - createController(config, function() { - xhr.useResult("valid"); - - $("#password").val("password"); - $("#vpassword").val("password1"); - - controller.submit(function(status) { - equal(status, false, "correct status"); - testHelpers.testTooltipVisible(); - start(); - }); - }); - }); - }()); diff --git a/resources/static/test/cases/shared/storage.js b/resources/static/test/cases/shared/storage.js index 5a7048c00799dfa54ebd351407cf45199264aec9..f7238bdedf1f9379b0a2f100e2e6b665b7ea69fb 100644 --- a/resources/static/test/cases/shared/storage.js +++ b/resources/static/test/cases/shared/storage.js @@ -155,15 +155,6 @@ storage.clear(); equal(typeof storage.manage_page.get("user_has_visited"), "undefined", "after reset, user_has_visited reset correctly"); }); - - test("storeTemporaryKeypair", function() { - // XXX needs a test - }); - - test("retrieveTemporaryKeypair", function() { - // XXX needs a test - }); - test("setReturnTo", function() { storage.setReturnTo("http://some.domain/path"); equal(storage.getReturnTo(), "http://some.domain/path", "setReturnTo/getReturnTo working as expected"); diff --git a/resources/static/test/testHelpers/helpers.js b/resources/static/test/testHelpers/helpers.js index 25badaf79e045099ab636f585102088970a65a00..882d0049e0470879e1f031c1add47717f60d80cf 100644 --- a/resources/static/test/testHelpers/helpers.js +++ b/resources/static/test/testHelpers/helpers.js @@ -228,6 +228,10 @@ BrowserID.TestHelpers = (function() { notEqual(typeof toTest, "undefined", msg || "object is defined"); }, + testVisible: function(selector, msg) { + ok($(selector).is(":visible"), msg || selector + " should be visible"); + }, + testHasClass: function(selector, className, msg) { ok($(selector).hasClass(className), msg || (selector + " has className " + className)); @@ -238,14 +242,14 @@ BrowserID.TestHelpers = (function() { msg || (selector + " does not have className " + className)); }, - testElementDoesNotExist: function(selector, msg) { - equal($(selector).length, 0, msg || ("element '" + selector + "' does not exist")); - }, - testElementExists: function(selector, msg) { ok($(selector).length, msg || ("element '" + selector + "' exists")); }, + testElementDoesNotExist: function(selector, msg) { + equal($(selector).length, 0, msg || ("element '" + selector + "' does not exist")); + }, + testRPTosPPShown: function(msg) { TestHelpers.testHasClass("body", "rptospp", msg || "RP TOS/PP shown"); }, diff --git a/resources/views/add_email_address.ejs b/resources/views/add_email_address.ejs index 9a4128aeee67fac5702ae45de569cd952d41fe4a..f56a6caf70bff61116465caf50941f13d20b2bec 100644 --- a/resources/views/add_email_address.ejs +++ b/resources/views/add_email_address.ejs @@ -2,15 +2,12 @@ - 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/. --> -<div id="hAlign" class="display_always"> +<div id="hAlign"> <div id="vAlign"> - <ul class="notifications"> - <li class="notification error" id="cannotconfirm"><%= gettext('Error encountered while attempting to confirm your address. Have you previously verified this address?') %></li> - <li class="notification error" id="cannotcomplete"><%= gettext('Error encountered trying to complete registration.') %></li> - </ul> - - <form id="signUpForm" class="cf"> - <p class="hint siteinfo"><%= gettext('Finish signing into:') %> <strong><span class="website"></span></strong></p> + <form id="signUpForm" class="cf password_entry"> + <p class="hint siteinfo"> + <%= gettext('Finish signing into:') %> <strong class="website"></strong> + </p> <h1><%= gettext('Email Verification') %></h1> @@ -19,7 +16,8 @@ <label for="email"><%= gettext('Email Address') %></label> <input class="youraddress" id="email" placeholder="<%= gettext('Your Email') %>" type="email" value="" disabled="disabled" maxlength="254" /> </li> - <li class="password_entry"> + + <li> <label for="password"><%= gettext('Password') %></label> <input id="password" placeholder="<%= gettext('Your Password') %>" type="password" autofocus maxlength=80 /> @@ -27,35 +25,16 @@ <%= gettext('Password is required.') %> </div> - <div class="tooltip" id="password_length" for="password"> - <%= gettext('Password must be between 8 and 80 characters long.') %> - </div> - <div id="cannot_authenticate" class="tooltip" for="password"> <%= gettext('The account cannot be verified with this username and password.') %> </div> </li> - - <li class="password_entry" id="verify_password"> - <label for="vpassword"><%= gettext('Verify Password') %></label> - <input id="vpassword" placeholder="<%= gettext('Repeat Password') %>" type="password" maxlength="80"> - - <div id="vpassword_required" class="tooltip" for="vpassword"> - <%= gettext('Verification password is required.') %> - </div> - - <div class="tooltip" id="passwords_no_match" for="vpassword"> - <%= gettext ('Passwords do not match.') %> - </div> - - </li> </ul> <div class="submit cf password_entry"> <button><%= gettext('finish') %></button> </div> - </form> <div id="congrats"> diff --git a/resources/views/verify_email_address.ejs b/resources/views/verify_email_address.ejs index d033b9417e2b39158d875138bb6ec24aca1a0286..118c70df793807bfb6586e04eb955624061bbe5a 100644 --- a/resources/views/verify_email_address.ejs +++ b/resources/views/verify_email_address.ejs @@ -2,15 +2,13 @@ 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/. */ %> -<div id="hAlign" class="display_always"> +<div id="hAlign"> <div id="vAlign"> - <ul class="notifications"> - <li class="notification error" id="cannotconfirm"><%= gettext('There was a problem with your signup link. Has this address already been registered?') %></li> - <li class="notification error" id="cannotcomplete"><%= gettext('Error encountered trying to complete registration.') %></li> - </ul> + <form id="signUpForm" class="cf password_entry"> + <p class="hint siteinfo"> + <%= gettext('Finish signing into:') %> <strong class="website"></strong> + </p> - <form id="signUpForm" class="cf"> - <p class="hint siteinfo"><%= gettext('Finish signing into:') %> <strong><span class="website"></span></strong></p> <h1><%= gettext('Last step!') %></h1> <ul class="inputs"> @@ -19,7 +17,7 @@ <input class="youraddress" id="email" placeholder="<%= gettext('Your Email') %>" type="email" value="" disabled="disabled" maxlength="254" /> </li> - <li class="password_entry"> + <li> <label for="password"><%= gettext('Password') %></label> <input id="password" placeholder="<%= gettext('Your Password') %>" type="password" autofocus maxlength=80 /> @@ -27,28 +25,10 @@ <%= gettext('Password is required.') %> </div> - <div class="tooltip" id="password_length" for="password"> - <%= gettext('Password must be between 8 and 80 characters long.') %> - </div> - <div id="cannot_authenticate" class="tooltip" for="password"> <%= gettext('The account cannot be verified with this username and password.') %> </div> </li> - - <li class="password_entry" id="verify_password"> - <label for="vpassword"><%= gettext('Verify Password') %></label> - <input id="vpassword" placeholder="<%= gettext('Repeat Password') %>" type="password" maxlength="80"> - - <div id="vpassword_required" class="tooltip" for="vpassword"> - <%= gettext('Verification password is required.') %> - </div> - - <div class="tooltip" id="passwords_no_match" for="vpassword"> - <%= gettext ('Passwords do not match.') %> - </div> - - </li> </ul> <div class="submit cf password_entry">