diff --git a/lib/static_resources.js b/lib/static_resources.js index 8f88114a98a55ebb9388d63900121d624762dca8..26e7b85da8382394fb43fc3e25908537300ec86d 100644 --- a/lib/static_resources.js +++ b/lib/static_resources.js @@ -99,6 +99,7 @@ var dialog_js = und.flatten([ '/dialog/controllers/primary_user_provisioned.js', '/dialog/controllers/generate_assertion.js', '/dialog/controllers/is_this_your_computer.js', + '/dialog/controllers/set_password.js', '/dialog/start.js' ]]); diff --git a/resources/static/dialog/controllers/actions.js b/resources/static/dialog/controllers/actions.js index 08239b6befc50e5b56547823020dd07a5b7ef5a1..c674f1dc972f1d3f11ded20320ce5de36f91afe6 100644 --- a/resources/static/dialog/controllers/actions.js +++ b/resources/static/dialog/controllers/actions.js @@ -73,6 +73,15 @@ BrowserID.Modules.Actions = (function() { if(onsuccess) onsuccess(null); }, + doSetPassword: function(info) { + startService("set_password", info); + }, + + doStageUser: function(info) { + var email = info.email; + bid.Helpers.Dialog.createUser.call(this, email); + }, + doConfirmUser: function(info) { startRegCheckService.call(this, info, "waitForUserValidation", "user_confirmed"); }, diff --git a/resources/static/dialog/controllers/authenticate.js b/resources/static/dialog/controllers/authenticate.js index a842fecc0bc196695f8f690c90bc65903c387676..16dc1063451b9c77c2a19a95eab87b39abf7edc1 100644 --- a/resources/static/dialog/controllers/authenticate.js +++ b/resources/static/dialog/controllers/authenticate.js @@ -61,7 +61,8 @@ BrowserID.Modules.Authenticate = (function() { else if(info.known) { enterPasswordState.call(self); } else { - createSecondaryUserState.call(self); + self.close("new_user", { email: email }); + //createSecondaryUserState.call(self); } } } @@ -71,9 +72,10 @@ BrowserID.Modules.Authenticate = (function() { email = getEmail(); if (email) { - dialogHelpers.createUser.call(self, email, callback); + self.close("new_user", { email: email }); + //dialogHelpers.createUser.call(self, email, callback); } else { - callback && callback(); + complete(callback); } } diff --git a/resources/static/dialog/controllers/set_password.js b/resources/static/dialog/controllers/set_password.js new file mode 100644 index 0000000000000000000000000000000000000000..334aab99ba76118eb8bae558503b1f5ec5c7f9c0 --- /dev/null +++ b/resources/static/dialog/controllers/set_password.js @@ -0,0 +1,47 @@ +/*jshint browser:true, jQuery: true, forin: true, laxbreak:true */ +/*global _: true, BrowserID: true, PageController: true */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ +BrowserID.Modules.SetPassword = (function() { + "use strict"; + var bid = BrowserID, + dom = bid.DOM, + complete = bid.Helpers.complete, + sc; + + function submit(callback) { + var pass = dom.getInner("#password"), + vpass = dom.getInner("#vpassword"); + + var valid = bid.Validation.passwordAndValidationPassword(pass, vpass); + if(valid) { + this.close("password_set", { password: pass }); + } + + complete(callback, valid); + } + + function cancel() { + this.close("cancel_state"); + } + + var Module = bid.Modules.PageModule.extend({ + start: function(options) { + var self=this; + + self.renderDialog("set_password"); + + self.click("#cancel", cancel); + + sc.start.call(self, options); + }, + + submit: submit, + cancel: cancel + }); + + sc = Module.sc; + + return Module; +}()); diff --git a/resources/static/dialog/resources/state.js b/resources/static/dialog/resources/state.js index a96d5b8881da56ca8efda4538b355de817b3cf7b..2103ffd00b9f38227dbd053641a399b0895d7657 100644 --- a/resources/static/dialog/resources/state.js +++ b/resources/static/dialog/resources/state.js @@ -93,6 +93,18 @@ BrowserID.State = (function() { startAction("doAuthenticate", info); }); + handleState("new_user", function(msg, info) { + self.newUserEmail = info.email; + startAction("doSetPassword", info); + }); + + handleState("password_set", function(msg, info) { + info = info || {}; + info.email = self.newUserEmail; + + startAction("doStageUser", info); + }); + handleState("user_staged", function(msg, info) { self.stagedEmail = info.email; info.required = !!requiredEmail; diff --git a/resources/static/dialog/start.js b/resources/static/dialog/start.js index 45e04d4fb15c4d2f7c590eed8a4a213e9b78bfbe..14cfe1cf38a156420204ee39bf06caced07ed822 100644 --- a/resources/static/dialog/start.js +++ b/resources/static/dialog/start.js @@ -33,6 +33,7 @@ moduleManager.register("generate_assertion", modules.GenerateAssertion); moduleManager.register("xhr_delay", modules.XHRDelay); moduleManager.register("xhr_disable_form", modules.XHRDisableForm); + moduleManager.register("set_password", modules.SetPassword); moduleManager.start("xhr_delay"); moduleManager.start("xhr_disable_form"); diff --git a/resources/static/dialog/views/set_password.ejs b/resources/static/dialog/views/set_password.ejs new file mode 100644 index 0000000000000000000000000000000000000000..dff785aea66004ac9f2ceb3d8b0b30740d512599 --- /dev/null +++ b/resources/static/dialog/views/set_password.ejs @@ -0,0 +1,45 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - 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/. --> + + <strong><%= gettext('Welcome to BrowserID!') %></strong> + + <div class="form_section" id="set_password"> + <ul class="inputs"> + <li> + <%= gettext('This email looks new, so let's get you set up.') %> + </li> + + <li> + <label for="password" class="serif"><%= gettext('Password') %></label> + <input id="password" class="sans" type="password" maxlength="80" /> + + <div class="tooltip" id="password_required" for="password"> + <%= gettext('Password is required.') %> + </div> + + <div class="tooltip" id="password_length" for="password"> + <%= gettext('Password must be between 8 and 80 characters long.') %> + </div> + </li> + + <li> + <label class="serif" for="vpassword"><%= gettext('Verify Password') %></label> + <input class="sans" id="vpassword" placeholder="<%= gettext('Repeat Password') %>" type="password" maxlength=80 /> + + <div class="tooltip" id="vpassword_required" 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"> + <button><%= gettext('verify email') %></button> + <a id="cancel" href="#"><%= gettext('cancel') %></a> + </div> + </div> diff --git a/resources/static/shared/modules/page_module.js b/resources/static/shared/modules/page_module.js index b47ecf8ac7a2a496634f1b6c4ed87e437fb3e3d0..97936af09a65b43e68b8bd327edaf53491641973 100644 --- a/resources/static/shared/modules/page_module.js +++ b/resources/static/shared/modules/page_module.js @@ -52,6 +52,7 @@ BrowserID.Modules.PageModule = (function() { start: function(options) { var self=this; self.bind("form", "submit", cancelEvent(onSubmit)); + // TODO - why is this here and not in pick_email? self.click("#thisIsNotMe", self.close.bind(self, "notme")); }, diff --git a/resources/static/test/cases/controllers/authenticate.js b/resources/static/test/cases/controllers/authenticate.js index dedd5352ca678c405250f5e39f0be16168d3648b..e758e5a065d7f44edf661b74b44c3cf47baa5865 100644 --- a/resources/static/test/cases/controllers/authenticate.js +++ b/resources/static/test/cases/controllers/authenticate.js @@ -80,7 +80,7 @@ }); function testUserUnregistered() { - register("create_user", function() { + register("new_user", function() { ok(true, "email was valid, user not registered"); start(); }); @@ -88,14 +88,14 @@ controller.checkEmail(); } - asyncTest("checkEmail with unknown secondary email, expect 'create_user' message", function() { + asyncTest("checkEmail with unknown secondary email, expect 'new_user' message", function() { $("#email").val("unregistered@testuser.com"); xhr.useResult("unknown_secondary"); testUserUnregistered(); }); - asyncTest("checkEmail with email with leading/trailing whitespace, user not registered, expect 'create_user' message", function() { + asyncTest("checkEmail with email with leading/trailing whitespace, user not registered, expect 'new_user' message", function() { $("#email").val(" unregistered@testuser.com "); xhr.useResult("unknown_secondary"); @@ -165,8 +165,8 @@ $("#email").val("unregistered@testuser.com"); xhr.useResult("unknown_secondary"); - register("user_staged", function(msg, info) { - equal(info.email, "unregistered@testuser.com", "user_staged with correct email triggered"); + register("new_user", function(msg, info) { + equal(info.email, "unregistered@testuser.com", "new_user with correct email triggered"); start(); }); @@ -177,27 +177,28 @@ $("#email").val("unregistered"); var handlerCalled = false; - register("user_staged", function(msg, info) { + register("new_user", function(msg, info) { handlerCalled = true; }); controller.createUser(function() { - equal(handlerCalled, false, "bad jiji, user_staged should not have been called with invalid email"); + equal(handlerCalled, false, "bad jiji, new_user should not have been called with invalid email"); start(); }); }); + /* asyncTest("createUser with valid email but throttling", function() { $("#email").val("unregistered@testuser.com"); var handlerCalled = false; - register("user_staged", function(msg, info) { + register("new_user", function(msg, info) { handlerCalled = true; }); xhr.useResult("throttle"); controller.createUser(function() { - equal(handlerCalled, false, "bad jiji, user_staged should not have been called with throttling"); + equal(handlerCalled, false, "bad jiji, new_user should not have been called with throttling"); equal(bid.Tooltip.shown, true, "tooltip is shown"); start(); }); @@ -207,16 +208,16 @@ $("#email").val("unregistered@testuser.com"); var handlerCalled = false; - register("user_staged", function(msg, info) { + register("new_user", function(msg, info) { handlerCalled = true; }); xhr.useResult("ajaxError"); controller.createUser(function() { - equal(handlerCalled, false, "bad jiji, user_staged should not have been called with XHR error"); + equal(handlerCalled, false, "bad jiji, new_user should not have been called with XHR error"); start(); }); }); - +*/ }()); diff --git a/resources/static/test/cases/controllers/set_password.js b/resources/static/test/cases/controllers/set_password.js new file mode 100644 index 0000000000000000000000000000000000000000..2398f3221e5d237c8c60fe8a76e7ef76da4ff395 --- /dev/null +++ b/resources/static/test/cases/controllers/set_password.js @@ -0,0 +1,61 @@ +/*jshint browsers:true, forin: true, laxbreak: true */ +/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserID:true */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ +(function() { + "use strict"; + + var controller, + el = $("body"), + bid = BrowserID, + testHelpers = bid.TestHelpers, + register = testHelpers.register, + controller; + + function createController(options) { + controller = bid.Modules.SetPassword.create(); + controller.start(options); + } + + module("controllers/set_password", { + setup: function() { + testHelpers.setup(); + createController(); + }, + + teardown: function() { + controller.destroy(); + testHelpers.teardown(); + } + }); + + + test("create - show correct template", function() { + ok($("#set_password").length, "set_password template added"); + }); + + asyncTest("submit with good password/vpassword - password_set message raised", function() { + $("#password").val("password"); + $("#vpassword").val("password"); + + var password; + register("password_set", function(msg, info) { + password = info.password; + }); + + controller.submit(function() { + ok(password, "password", "password_set message raised with correct password"); + start(); + }); + }); + + asyncTest("cancel - cancel_state message raised", function() { + register("cancel_state", function(msg, info) { + ok(true, "state cancelled"); + start(); + }); + + $("#cancel").click(); + }); +}()); diff --git a/resources/static/test/cases/resources/state.js b/resources/static/test/cases/resources/state.js index 83e6c7cf6164e71f77b0befcd479e5a3754928ef..4ce48b1ba92e1058251a34adf57a579a97569a75 100644 --- a/resources/static/test/cases/resources/state.js +++ b/resources/static/test/cases/resources/state.js @@ -78,10 +78,21 @@ equal(error, "start: controller must be specified", "creating a state machine without a controller fails"); }); + test("new_user - call doSetPassword with correct email", function() { + mediator.publish("new_user", { email: TEST_EMAIL }); + + equal(actions.info.doSetPassword.email, TEST_EMAIL, "correct email sent to doSetPassword"); + }); + + test("password_set - call doStageUser with correct email", function() { + mediator.publish("new_user", { email: TEST_EMAIL }); + mediator.publish("password_set"); + + equal(actions.info.doStageUser.email, TEST_EMAIL, "correct email sent to doStageUser"); + }); + test("user_staged - call doConfirmUser", function() { - mediator.publish("user_staged", { - email: TEST_EMAIL - }); + mediator.publish("user_staged", { email: TEST_EMAIL }); equal(actions.info.doConfirmUser.email, TEST_EMAIL, "waiting for email confirmation for testuser@testuser.com"); }); diff --git a/resources/views/test.ejs b/resources/views/test.ejs index a1fb2cd58698ae93864018bbfaeee0935584d76c..a6cf9e9130619aa6d1c9cc89e90acc61cfbd2019 100644 --- a/resources/views/test.ejs +++ b/resources/views/test.ejs @@ -126,6 +126,7 @@ <script src="/dialog/controllers/provision_primary_user.js"></script> <script src="/dialog/controllers/primary_user_provisioned.js"></script> <script src="/dialog/controllers/is_this_your_computer.js"></script> + <script src="/dialog/controllers/set_password.js"></script> <script src="/pages/page_helpers.js"></script> <script src="/pages/add_email_address.js"></script> @@ -185,6 +186,7 @@ <script src="cases/controllers/provision_primary_user.js"></script> <script src="cases/controllers/primary_user_provisioned.js"></script> <script src="cases/controllers/is_this_your_computer.js"></script> + <script src="cases/controllers/set_password.js"></script> <!-- must go last or all other tests will fail. --> <script src="cases/controllers/dialog.js"></script>