diff --git a/browserid/static/dialog/qunit.html b/browserid/static/dialog/qunit.html index edbdabfc8df168368d3057f16a8fbe0f4800ba05..a22393863716be5e9f6b976a45a791fbd411f96e 100644 --- a/browserid/static/dialog/qunit.html +++ b/browserid/static/dialog/qunit.html @@ -1,6 +1,6 @@ <html> <head> - <link rel="stylesheet" type="text/css" href="../../../../../../../funcunit/qunit/qunit.css" /> + <link rel="stylesheet" type="text/css" href="/funcunit/qunit/qunit.css" /> <title>dialog QUnit Test</title> <script type='text/javascript'> steal = {ignoreControllers: true} diff --git a/browserid/static/dialog/resources/browserid-identities.js b/browserid/static/dialog/resources/browserid-identities.js index a2c0c82e9b4ff10175b8fcbbf73a1c8adaab0ea3..09eab53895fe61455e1526866b8716faf0665b73 100644 --- a/browserid/static/dialog/resources/browserid-identities.js +++ b/browserid/static/dialog/resources/browserid-identities.js @@ -35,43 +35,107 @@ * * ***** END LICENSE BLOCK ***** */ "use strict"; -var BrowserIDIdentities = { - - syncIdentities: function(onSuccess, onFailure, onKeySyncFailure) { - // send up all email/pubkey pairs to the server, it will response with a - // list of emails that need new keys. This may include emails in the - // sent list, and also may include identities registered on other devices. - // we'll go through the list and generate new keypairs - - // identities that don't have an issuer are primary authentications, - // and we don't need to worry about rekeying them. - var emails = getEmails(); - var issued_identities = {}; - _(emails).each(function(email_obj, email_address) { +var BrowserIDIdentities = (function() { + function getIssuedIdentities() { + var emails = getEmails(); + var issued_identities = {}; + _(emails).each(function(email_obj, email_address) { issued_identities[email_address] = email_obj.pub; }); - - var self = this; - BrowserIDNetwork.syncEmails(issued_identities, - function onKeySyncSuccess(email, keypair) { - self.persistAddressAndKeyPair(email, keypair, "browserid.org:443"); - }, - onKeySyncFailure, onSuccess, onFailure); - }, - - persistAddressAndKeyPair: function(email, keypair, issuer) { - var new_email_obj= { - created: new Date(), - pub: keypair.pub, - priv: keypair.priv - }; - - if (issuer) { - new_email_obj.issuer = issuer; + + return issued_identities; + } + + function removeUnknownIdentities(unknown_emails) { + // first remove idenitites that the server doesn't know about + if (unknown_emails) { + _(unknown_emails).each(function(email_address) { + removeEmail(email_address); + }); + } + } + + var Identities = { + syncIdentities: function(onSuccess, onFailure, onKeySyncFailure) { + var issued_identities = getIssuedIdentities(); + + // send up all email/pubkey pairs to the server, it will response with a + // list of emails that need new keys. This may include emails in the + // sent list, and also may include identities registered on other devices. + // we'll go through the list and generate new keypairs + + // identities that don't have an issuer are primary authentications, + // and we don't need to worry about rekeying them. + + var self = this; + BrowserIDNetwork.syncEmails(issued_identities, function(resp) { + removeUnknownIdentities(resp.unknown_emails); + + // now let's begin iteratively re-keying the emails mentioned in the server provided list + var emailsToAdd = resp.key_refresh; + + function addNextEmail() { + if (!emailsToAdd || !emailsToAdd.length) { + onSuccess(); + return; + } + + // pop the first email from the list + var email = emailsToAdd.shift(); + var keypair = CryptoStubs.genKeyPair(); + + BrowserIDNetwork.setKey(email, keypair, function() { + // update emails list and commit to local storage, then go do the next email + self.addIdentity(email, keypair, "browserid.org:443"); + addNextEmail(); + }, onKeySyncFailure); + } + + addNextEmail(); + }, onFailure); + }, + + /** + * Persist an address and key pair. + * @method addIdentity + * @param {string} email - Email address. + * @param {object} keypair - Keypair for email address + * @param {string} [issuer] - Issuer of keypair + */ + addIdentity: function(email, keypair, issuer) { + var new_email_obj= { + created: new Date(), + pub: keypair.pub, + priv: keypair.priv + }; + + if (issuer) { + new_email_obj.issuer = issuer; + } + + addEmail(email, new_email_obj); + }, + + /** + * Remove an email address. + * @method removeIdentity + * @param {string} email - Email address to remove. + */ + removeIdentity: function(email) { + removeEmail(email); + }, + + /** + * Get the current list of stored identities. + * @method getIdentities + * @return {object} identities. + */ + getIdentities: function() { + return getEmails(); } - - addEmail(email, new_email_obj); - }, -}; + }; + + return Identities; +}()); diff --git a/browserid/static/dialog/resources/browserid-network.js b/browserid/static/dialog/resources/browserid-network.js index 2c022898746566f86d81ce24c0a039b499e0aa6c..07d79c1e13f3b1be46e1dc89224369fe08c33a40 100644 --- a/browserid/static/dialog/resources/browserid-network.js +++ b/browserid/static/dialog/resources/browserid-network.js @@ -120,7 +120,14 @@ var BrowserIDNetwork = (function() { withCSRF(function() { $.post("/wsapi/logout", { csrf: csrf_token - }, onSuccess ); + }, function() { + csrf_token = undefined; + withCSRF(function() { + if(onSuccess) { + onSuccess(); + } + }); + } ); }); }, @@ -282,8 +289,11 @@ var BrowserIDNetwork = (function() { /** * Sync emails * @method syncEmails + * @param {object} issued_identities - Identities to check against. + * @param {function} [onSuccess] - Called with response when complete. + * @param {function} [onFailure] - Called on XHR failure. */ - syncEmails: function(issued_identities, onKeySyncSuccess, onKeySyncFailure, onSuccess, onFailure) { + syncEmails: function(issued_identities, onSuccess, onFailure) { withCSRF(function() { $.ajax({ type: "POST", @@ -292,36 +302,7 @@ var BrowserIDNetwork = (function() { emails: issued_identities, csrf: csrf_token }, - success: function(resp, textStatus, jqXHR) { - // first remove idenitites that the server doesn't know about - if (resp.unknown_emails) { - _(resp.unknown_emails).each(function(email_address) { - removeEmail(email_address); - }); - } - - // now let's begin iteratively re-keying the emails mentioned in the server provided list - var emailsToAdd = resp.key_refresh; - - function addNextEmail() { - if (!emailsToAdd || !emailsToAdd.length) { - onSuccess(); - return; - } - - // pop the first email from the list - var email = emailsToAdd.shift(); - var keypair = CryptoStubs.genKeyPair(); - - BrowserIDNetwork.setKey(email, keypair, function() { - // update emails list and commit to local storage, then go do the next email - onKeySyncSuccess(email, keypair); - addNextEmail(); - }, onKeySyncFailure); - } - - addNextEmail(); - }, + success: onSuccess, error: onFailure }); }); diff --git a/browserid/static/dialog/test/qunit/browserid-identities_test.js b/browserid/static/dialog/test/qunit/browserid-identities_test.js new file mode 100644 index 0000000000000000000000000000000000000000..69084f00aa9bc0304c8ca23e5bcb5518f080ea2f --- /dev/null +++ b/browserid/static/dialog/test/qunit/browserid-identities_test.js @@ -0,0 +1,113 @@ +/*jshint browsers:true, forin: true, laxbreak: true */ +/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserIDNetwork: true */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla BrowserID. + * + * The Initial Developer of the Original Code is Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +/** + * This test assumes for authentication that there is a user named + * "testuser@testuser.com" with the password "testuser" + */ +steal.plugins("jquery", "funcunit/qunit").then("/dialog/resources/browserid-identities", function() { + module("browserid-identities"); + + test("getIdentities", function() { + var identities = BrowserIDIdentities.getIdentities(); + equal("object", typeof identities, "we have some identities"); + }); + + test("addIdentity", function() { + BrowserIDIdentities.addIdentity("testemail@testemail.com", { + pub: "pub", + priv: "priv" + }, "issuer"); + + var identities = BrowserIDIdentities.getIdentities(); + ok("testemail@testemail.com" in identities, "Our new email is added"); + }); + + test("removeIdentity", function() { + BrowserIDIdentities.addIdentity("testemail@testemail.com", { + pub: "pub", + priv: "priv" + }, "issuer"); + + BrowserIDIdentities.removeIdentity("testemail@testemail.com"); + + var identities = BrowserIDIdentities.getIdentities(); + equal(false, "testemail@testemail.com" in identities, "Our new email is removed"); + }); + + test("syncIdentities with no identities", function() { + clearEmails(); + BrowserIDNetwork.authenticate("testuser@testuser.com", "testuser", function() { + BrowserIDIdentities.syncIdentities(function onSuccess() { + ok(true, "we have synced identities"); + start(); + }, function onFailure() { + ok(false, "identity sync failure"); + start(); + }, function onKeySyncFailure() { + ok(false, "identity key sync failure"); + start(); + }); + + }, function() { + ok(false, "Authentication failure"); + start(); + }); + stop(); + }); + + test("syncIdentities with identities preloaded", function() { + BrowserIDNetwork.authenticate("testuser@testuser.com", "testuser", function() { + BrowserIDIdentities.syncIdentities(function onSuccess() { + ok(true, "we have synced identities"); + start(); + }, function onFailure() { + ok(false, "identity sync failure"); + start(); + }, function onKeySyncFailure() { + ok(false, "identity key sync failure"); + start(); + }); + + }, function() { + ok(false, "Authentication failure"); + start(); + }); + stop(); + }); + + +}); diff --git a/browserid/static/dialog/test/qunit/browserid-network_test.js b/browserid/static/dialog/test/qunit/browserid-network_test.js index c14b14f84ddc7c173f3a0c33f94aeb2dd505990e..2ce1d4e659b68a13fb9e909f06b7c5ed7e3a53f8 100644 --- a/browserid/static/dialog/test/qunit/browserid-network_test.js +++ b/browserid/static/dialog/test/qunit/browserid-network_test.js @@ -1,3 +1,39 @@ +/*jshint browsers:true, forin: true, laxbreak: true */ +/*global test: true, start: true, stop: true, module: true, ok: true, equal: true, BrowserIDNetwork: true */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla BrowserID. + * + * The Initial Developer of the Original Code is Mozilla. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ /** * This test assumes for authentication that there is a user named * "testuser@testuser.com" with the password "testuser" diff --git a/browserid/static/dialog/test/qunit/qunit.js b/browserid/static/dialog/test/qunit/qunit.js index 304452245c6cfa98a4c836d82dff4021b7b1a44d..05837c783c2853bdbfd3b1cdea71f4232ea0b9b8 100644 --- a/browserid/static/dialog/test/qunit/qunit.js +++ b/browserid/static/dialog/test/qunit/qunit.js @@ -1,3 +1,7 @@ -steal +steal("/dialog/resources/storage.js", + "/dialog/resources/underscore-min.js", + "/dialog/resources/crypto-api.js", + "/dialog/resources/crypto.js") .plugins("funcunit/qunit") - .then("browserid-network_test"); + .then("browserid-network_test") + .then("browserid-identities_test");