diff --git a/resources/static/shared/network.js b/resources/static/shared/network.js index ed2cc792620a933b3ecee39784c11dd95e4a0eae..752ce427df57ff8903fea6a742ccd7b795b97703 100644 --- a/resources/static/shared/network.js +++ b/resources/static/shared/network.js @@ -94,6 +94,10 @@ BrowserID.Network = (function() { // Any time the context info changes, we want to know about it. mediator.subscribe('context_info', onContextChange); + // BEGIN TEST API + this.cookiesEnabledOverride = config && config.cookiesEnabledOverride; + // END TEST API + clearContext(); }, @@ -677,6 +681,12 @@ BrowserID.Network = (function() { enabled = false; } + // BEGIN TESTING API + if (typeof Network.cookiesEnabledOverride === "boolean") { + enabled = Network.cookiesEnabledOverride; + } + // END TESTING API + complete(onComplete, enabled); }, onFailure); }, diff --git a/resources/static/shared/user.js b/resources/static/shared/user.js index 2c3752a41f3374944a7e57c5a310a68338219c51..0695c836c9d1b045c3b35415067205c4415eb69b 100644 --- a/resources/static/shared/user.js +++ b/resources/static/shared/user.js @@ -679,6 +679,7 @@ BrowserID.User = (function() { if(cookiesEnabled) { network.checkAuth(function(authenticated) { setAuthenticationStatus(authenticated); + if (!authenticated) authenticated = false; complete(onComplete, authenticated); }, onFailure); } @@ -692,7 +693,9 @@ BrowserID.User = (function() { * Check whether the current user is authenticated. If authenticated, sync * identities. * @method checkAuthenticationAndSync - * @param {function} [onComplete] - Called on sync completion. + * @param {function} [onComplete] - Called on sync completion with one + * boolean parameter, authenticated. authenticated will be true if user + * is authenticated, false otw. * @param {function} [onFailure] - Called on error. */ checkAuthenticationAndSync: function(onComplete, onFailure) { @@ -1052,7 +1055,7 @@ BrowserID.User = (function() { * Get an assertion for the current domain if the user is signed into it * @method getPersistentSigninAssertion * @param {function} onComplete - called on completion. Called with an - * assertion if successful, null otw. + * an email and assertion if successful, null otw. * @param {function} onFailure - called on XHR failure. */ getSilentAssertion: function(siteSpecifiedEmail, onComplete, onFailure) { diff --git a/resources/static/test/cases/shared/network.js b/resources/static/test/cases/shared/network.js index ef310d932c20905bea77f4aca7dbe8e263c7ca85..4ce7680923dd3d0f03d8c57f771d69d461ae7e53 100644 --- a/resources/static/test/cases/shared/network.js +++ b/resources/static/test/cases/shared/network.js @@ -20,7 +20,6 @@ module("shared/network", { setup: function() { testHelpers.setup(); - network.init(); }, teardown: function() { testHelpers.teardown(); @@ -593,12 +592,28 @@ }); asyncTest("cookiesEnabled with cookies enabled - return true status", function() { + network.init({ cookiesEnabledOverride: true }); network.cookiesEnabled(function(status) { equal(status, true, "cookies are enabled, correct status"); start(); }, testHelpers.unexpectedXHRFailure); }); + asyncTest("cookiesEnabled with cookies disabled - return true status", function() { + network.init({ cookiesEnabledOverride: false }); + network.cookiesEnabled(function(status) { + equal(status, false, "cookies are disabled, correct status"); + start(); + }, testHelpers.unexpectedXHRFailure); + }); + + asyncTest("cookiesEnabled with browser defined cookie status - wait and see", function() { + network.cookiesEnabled(function(status) { + equal(status, true, "hopefully cookies are enabled, correct status"); + start(); + }, testHelpers.unexpectedXHRFailure); + }); + asyncTest("cookiesEnabled with onComplete exception thrown - should not call onComplete a second time", function() { // Since we are manually throwing an exception, it must be caught // below. diff --git a/resources/static/test/cases/shared/user.js b/resources/static/test/cases/shared/user.js index c44fe0cd719b806924b091a621d1f2a0e0af5cfa..a07a5febb04c5527c7a5ff9980d62b994828bf96 100644 --- a/resources/static/test/cases/shared/user.js +++ b/resources/static/test/cases/shared/user.js @@ -14,6 +14,8 @@ var jwcrypto = require("./lib/jwcrypto"); testHelpers = bid.TestHelpers, testOrigin = testHelpers.testOrigin, failureCheck = testHelpers.failureCheck, + testUndefined = testHelpers.testUndefined, + testNotUndefined = testHelpers.testNotUndefined, provisioning = bid.Mocks.Provisioning, TEST_EMAIL = "testuser@testuser.com"; @@ -512,24 +514,40 @@ var jwcrypto = require("./lib/jwcrypto"); asyncTest("checkAuthentication with valid authentication", function() { + storage.addSecondaryEmail(TEST_EMAIL); xhr.setContextInfo("auth_level", "primary"); + lib.checkAuthentication(function(authenticated) { equal(authenticated, "primary", "We are authenticated!"); + testNotUndefined(storage.getEmail(TEST_EMAIL), "localStorage is not cleared"); start(); }); }); - asyncTest("checkAuthentication with invalid authentication", function() { + asyncTest("checkAuthentication with invalid authentication - localStorage cleared", function() { + storage.addSecondaryEmail(TEST_EMAIL); xhr.setContextInfo("auth_level", undefined); + lib.checkAuthentication(function(authenticated) { - equal(authenticated, undefined, "We are not authenticated!"); + equal(authenticated, false, "We are not authenticated!"); + testUndefined(storage.getEmail(TEST_EMAIL), "localStorage was cleared"); start(); }); }); + asyncTest("checkAuthentication with cookies disabled - localStorage is not cleared, user can enable their cookies and try again", function() { + storage.addSecondaryEmail(TEST_EMAIL); + network.init({ cookiesEnabledOverride: false }); + + lib.checkAuthentication(function(authenticated) { + equal(authenticated, false, "We are not authenticated!"); + testNotUndefined(storage.getEmail(TEST_EMAIL), "localStorage is not cleared"); + start(); + }); + }); asyncTest("checkAuthentication with XHR failure", function() { xhr.useResult("contextAjaxError"); @@ -548,12 +566,24 @@ var jwcrypto = require("./lib/jwcrypto"); }); - - asyncTest("checkAuthenticationAndSync with invalid authentication", function() { + asyncTest("checkAuthenticationAndSync with invalid authentication - localStorage cleared", function() { + storage.addSecondaryEmail(TEST_EMAIL); xhr.setContextInfo("auth_level", undefined); lib.checkAuthenticationAndSync(function onComplete(authenticated) { - equal(authenticated, undefined, "We are not authenticated!"); + equal(authenticated, false, "We are not authenticated!"); + testUndefined(storage.getEmail(TEST_EMAIL), "localStorage was cleared"); + start(); + }, testHelpers.unexpectedXHRFailure); + }); + + asyncTest("checkAuthenticationAndSync with cookies disabled - localStorage not cleared, user can enable their cookies and try again", function() { + storage.addSecondaryEmail(TEST_EMAIL); + network.init({ cookiesEnabledOverride: false }); + + lib.checkAuthenticationAndSync(function onComplete(authenticated) { + equal(authenticated, false, "We are not authenticated!"); + testNotUndefined(storage.getEmail(TEST_EMAIL), "localStorage is not cleared"); start(); }, testHelpers.unexpectedXHRFailure); }); @@ -942,6 +972,34 @@ var jwcrypto = require("./lib/jwcrypto"); }); + asyncTest("getSilentAssertion with logged in user, emails match - user already logged in, call callback with email and null assertion", function() { + var LOGGED_IN_EMAIL = TEST_EMAIL; + xhr.setContextInfo("auth_level", "password"); + + lib.syncEmailKeypair(LOGGED_IN_EMAIL, function() { + storage.setLoggedIn(lib.getOrigin(), LOGGED_IN_EMAIL); + lib.getSilentAssertion(LOGGED_IN_EMAIL, function(email, assertion) { + equal(email, LOGGED_IN_EMAIL, "correct email"); + strictEqual(assertion, null, "correct assertion"); + start(); + }, testHelpers.unexpectedXHRFailure); + }, testHelpers.unexpectedXHRFailure); + }); + + asyncTest("getSilentAssertion with logged in user, request email different from logged in email, valid cert for logged in email - logged in user needs assertion - call callback with email and assertion.", function() { + xhr.setContextInfo("auth_level", "password"); + var LOGGED_IN_EMAIL = TEST_EMAIL; + var REQUESTED_EMAIL = "requested@testuser.com"; + + lib.syncEmailKeypair(LOGGED_IN_EMAIL, function() { + storage.setLoggedIn(lib.getOrigin(), LOGGED_IN_EMAIL); + lib.getSilentAssertion(REQUESTED_EMAIL, function(email, assertion) { + equal(email, LOGGED_IN_EMAIL, "correct email"); + testAssertion(assertion, start); + }, testHelpers.unexpectedXHRFailure); + }, testHelpers.unexpectedXHRFailure); + }); + asyncTest("logoutUser", function(onSuccess) { lib.authenticate(TEST_EMAIL, "testuser", function(authenticated) { lib.syncEmails(function() { diff --git a/resources/static/test/testHelpers/helpers.js b/resources/static/test/testHelpers/helpers.js index 2c77f42019d666b16005680e32cd1afc4aab1bc6..c309deeb16f250d20aa848d01b1d5d5b0f0e3b90 100644 --- a/resources/static/test/testHelpers/helpers.js +++ b/resources/static/test/testHelpers/helpers.js @@ -68,7 +68,7 @@ BrowserID.TestHelpers = (function() { transport.setContextInfo("cookies_enabled", true); transport.useResult("valid"); - network.init(); + network.init({ forceCookieStatus: undefined }); clearStorage(); $("body").stop().show(); @@ -223,6 +223,14 @@ BrowserID.TestHelpers = (function() { testHasClass: function(selector, className, msg) { ok($(selector).hasClass(className), selector + " has className " + className + " - " + msg); + }, + + testUndefined: function(toTest, msg) { + equal(typeof toTest, "undefined", msg || "object is undefined"); + }, + + testNotUndefined: function(toTest, msg) { + notEqual(typeof toTest, "undefined", msg || "object is defined"); } };