summaryrefslogtreecommitdiffstats
path: root/services/fxaccounts/tests/xpcshell/test_accounts.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/fxaccounts/tests/xpcshell/test_accounts.js')
-rw-r--r--services/fxaccounts/tests/xpcshell/test_accounts.js1531
1 files changed, 0 insertions, 1531 deletions
diff --git a/services/fxaccounts/tests/xpcshell/test_accounts.js b/services/fxaccounts/tests/xpcshell/test_accounts.js
deleted file mode 100644
index d6139a076..000000000
--- a/services/fxaccounts/tests/xpcshell/test_accounts.js
+++ /dev/null
@@ -1,1531 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/FxAccounts.jsm");
-Cu.import("resource://gre/modules/FxAccountsClient.jsm");
-Cu.import("resource://gre/modules/FxAccountsCommon.js");
-Cu.import("resource://gre/modules/FxAccountsOAuthGrantClient.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
-
-// We grab some additional stuff via backstage passes.
-var {AccountState} = Cu.import("resource://gre/modules/FxAccounts.jsm", {});
-
-const ONE_HOUR_MS = 1000 * 60 * 60;
-const ONE_DAY_MS = ONE_HOUR_MS * 24;
-const TWO_MINUTES_MS = 1000 * 60 * 2;
-
-initTestLogging("Trace");
-
-// XXX until bug 937114 is fixed
-Cu.importGlobalProperties(['atob']);
-
-var log = Log.repository.getLogger("Services.FxAccounts.test");
-log.level = Log.Level.Debug;
-
-// See verbose logging from FxAccounts.jsm
-Services.prefs.setCharPref("identity.fxaccounts.loglevel", "Trace");
-Log.repository.getLogger("FirefoxAccounts").level = Log.Level.Trace;
-
-// The oauth server is mocked, but set these prefs to pass param checks
-Services.prefs.setCharPref("identity.fxaccounts.remote.oauth.uri", "https://example.com/v1");
-Services.prefs.setCharPref("identity.fxaccounts.oauth.client_id", "abc123");
-
-
-const PROFILE_SERVER_URL = "http://example.com/v1";
-const CONTENT_URL = "http://accounts.example.com/";
-
-Services.prefs.setCharPref("identity.fxaccounts.remote.profile.uri", PROFILE_SERVER_URL);
-Services.prefs.setCharPref("identity.fxaccounts.settings.uri", CONTENT_URL);
-
-/*
- * The FxAccountsClient communicates with the remote Firefox
- * Accounts auth server. Mock the server calls, with a little
- * lag time to simulate some latency.
- *
- * We add the _verified attribute to mock the change in verification
- * state on the FXA server.
- */
-
-function MockStorageManager() {
-}
-
-MockStorageManager.prototype = {
- promiseInitialized: Promise.resolve(),
-
- initialize(accountData) {
- this.accountData = accountData;
- },
-
- finalize() {
- return Promise.resolve();
- },
-
- getAccountData() {
- return Promise.resolve(this.accountData);
- },
-
- updateAccountData(updatedFields) {
- for (let [name, value] of Object.entries(updatedFields)) {
- if (value == null) {
- delete this.accountData[name];
- } else {
- this.accountData[name] = value;
- }
- }
- return Promise.resolve();
- },
-
- deleteAccountData() {
- this.accountData = null;
- return Promise.resolve();
- }
-}
-
-function MockFxAccountsClient() {
- this._email = "nobody@example.com";
- this._verified = false;
- this._deletedOnServer = false; // for testing accountStatus
-
- // mock calls up to the auth server to determine whether the
- // user account has been verified
- this.recoveryEmailStatus = function (sessionToken) {
- // simulate a call to /recovery_email/status
- return Promise.resolve({
- email: this._email,
- verified: this._verified
- });
- };
-
- this.accountStatus = function(uid) {
- let deferred = Promise.defer();
- deferred.resolve(!!uid && (!this._deletedOnServer));
- return deferred.promise;
- };
-
- this.accountKeys = function (keyFetchToken) {
- let deferred = Promise.defer();
-
- do_timeout(50, () => {
- let response = {
- kA: expandBytes("11"),
- wrapKB: expandBytes("22")
- };
- deferred.resolve(response);
- });
- return deferred.promise;
- };
-
- this.resendVerificationEmail = function(sessionToken) {
- // Return the session token to show that we received it in the first place
- return Promise.resolve(sessionToken);
- };
-
- this.signCertificate = function() { throw "no" };
-
- this.signOut = () => Promise.resolve();
- this.signOutAndDestroyDevice = () => Promise.resolve({});
-
- FxAccountsClient.apply(this);
-}
-MockFxAccountsClient.prototype = {
- __proto__: FxAccountsClient.prototype
-}
-
-/*
- * We need to mock the FxAccounts module's interfaces to external
- * services, such as storage and the FxAccounts client. We also
- * mock the now() method, so that we can simulate the passing of
- * time and verify that signatures expire correctly.
- */
-function MockFxAccounts() {
- return new FxAccounts({
- VERIFICATION_POLL_TIMEOUT_INITIAL: 100, // 100ms
-
- _getCertificateSigned_calls: [],
- _d_signCertificate: Promise.defer(),
- _now_is: new Date(),
- now: function () {
- return this._now_is;
- },
- newAccountState(credentials) {
- // we use a real accountState but mocked storage.
- let storage = new MockStorageManager();
- storage.initialize(credentials);
- return new AccountState(storage);
- },
- getCertificateSigned: function (sessionToken, serializedPublicKey) {
- _("mock getCertificateSigned\n");
- this._getCertificateSigned_calls.push([sessionToken, serializedPublicKey]);
- return this._d_signCertificate.promise;
- },
- _registerOrUpdateDevice() {
- return Promise.resolve();
- },
- fxAccountsClient: new MockFxAccountsClient()
- });
-}
-
-/*
- * Some tests want a "real" fxa instance - however, we still mock the storage
- * to keep the tests fast on b2g.
- */
-function MakeFxAccounts(internal = {}) {
- if (!internal.newAccountState) {
- // we use a real accountState but mocked storage.
- internal.newAccountState = function(credentials) {
- let storage = new MockStorageManager();
- storage.initialize(credentials);
- return new AccountState(storage);
- };
- }
- if (!internal._signOutServer) {
- internal._signOutServer = () => Promise.resolve();
- }
- if (!internal._registerOrUpdateDevice) {
- internal._registerOrUpdateDevice = () => Promise.resolve();
- }
- return new FxAccounts(internal);
-}
-
-add_task(function* test_non_https_remote_server_uri_with_requireHttps_false() {
- Services.prefs.setBoolPref(
- "identity.fxaccounts.allowHttp",
- true);
- Services.prefs.setCharPref(
- "identity.fxaccounts.remote.signup.uri",
- "http://example.com/browser/browser/base/content/test/general/accounts_testRemoteCommands.html");
- do_check_eq(yield fxAccounts.promiseAccountsSignUpURI(),
- "http://example.com/browser/browser/base/content/test/general/accounts_testRemoteCommands.html");
-
- Services.prefs.clearUserPref("identity.fxaccounts.remote.signup.uri");
- Services.prefs.clearUserPref("identity.fxaccounts.allowHttp");
-});
-
-add_task(function* test_non_https_remote_server_uri() {
- Services.prefs.setCharPref(
- "identity.fxaccounts.remote.signup.uri",
- "http://example.com/browser/browser/base/content/test/general/accounts_testRemoteCommands.html");
- rejects(fxAccounts.promiseAccountsSignUpURI(), null, "Firefox Accounts server must use HTTPS");
- Services.prefs.clearUserPref("identity.fxaccounts.remote.signup.uri");
-});
-
-add_task(function* test_get_signed_in_user_initially_unset() {
- _("Check getSignedInUser initially and after signout reports no user");
- let account = MakeFxAccounts();
- let credentials = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- assertion: "foobar",
- sessionToken: "dead",
- kA: "beef",
- kB: "cafe",
- verified: true
- };
- let result = yield account.getSignedInUser();
- do_check_eq(result, null);
-
- yield account.setSignedInUser(credentials);
- let histogram = Services.telemetry.getHistogramById("FXA_CONFIGURED");
- do_check_eq(histogram.snapshot().sum, 1);
- histogram.clear();
-
- result = yield account.getSignedInUser();
- do_check_eq(result.email, credentials.email);
- do_check_eq(result.assertion, credentials.assertion);
- do_check_eq(result.kB, credentials.kB);
-
- // Delete the memory cache and force the user
- // to be read and parsed from storage (e.g. disk via JSONStorage).
- delete account.internal.signedInUser;
- result = yield account.getSignedInUser();
- do_check_eq(result.email, credentials.email);
- do_check_eq(result.assertion, credentials.assertion);
- do_check_eq(result.kB, credentials.kB);
-
- // sign out
- let localOnly = true;
- yield account.signOut(localOnly);
-
- // user should be undefined after sign out
- result = yield account.getSignedInUser();
- do_check_eq(result, null);
-});
-
-add_task(function* test_update_account_data() {
- _("Check updateUserAccountData does the right thing.");
- let account = MakeFxAccounts();
- let credentials = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- assertion: "foobar",
- sessionToken: "dead",
- kA: "beef",
- kB: "cafe",
- verified: true
- };
- yield account.setSignedInUser(credentials);
-
- let newCreds = {
- email: credentials.email,
- uid: credentials.uid,
- assertion: "new_assertion",
- }
- yield account.updateUserAccountData(newCreds);
- do_check_eq((yield account.getSignedInUser()).assertion, "new_assertion",
- "new field value was saved");
-
- // but we should fail attempting to change email or uid.
- newCreds = {
- email: "someoneelse@example.com",
- uid: credentials.uid,
- assertion: "new_assertion",
- }
- yield Assert.rejects(account.updateUserAccountData(newCreds));
- newCreds = {
- email: credentials.email,
- uid: "another_uid",
- assertion: "new_assertion",
- }
- yield Assert.rejects(account.updateUserAccountData(newCreds));
-
- // should fail without email or uid.
- newCreds = {
- assertion: "new_assertion",
- }
- yield Assert.rejects(account.updateUserAccountData(newCreds));
-
- // and should fail with a field name that's not known by storage.
- newCreds = {
- email: credentials.email,
- uid: "another_uid",
- foo: "bar",
- }
- yield Assert.rejects(account.updateUserAccountData(newCreds));
-});
-
-add_task(function* test_getCertificateOffline() {
- _("getCertificateOffline()");
- let fxa = MakeFxAccounts();
- let credentials = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- sessionToken: "dead",
- verified: true,
- };
-
- yield fxa.setSignedInUser(credentials);
-
- // Test that an expired cert throws if we're offline.
- let offline = Services.io.offline;
- Services.io.offline = true;
- yield fxa.internal.getKeypairAndCertificate(fxa.internal.currentAccountState).then(
- result => {
- Services.io.offline = offline;
- do_throw("Unexpected success");
- },
- err => {
- Services.io.offline = offline;
- // ... so we have to check the error string.
- do_check_eq(err, "Error: OFFLINE");
- }
- );
- yield fxa.signOut(/*localOnly = */true);
-});
-
-add_task(function* test_getCertificateCached() {
- _("getCertificateCached()");
- let fxa = MakeFxAccounts();
- let credentials = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- sessionToken: "dead",
- verified: true,
- // A cached keypair and cert that remain valid.
- keyPair: {
- validUntil: Date.now() + KEY_LIFETIME + 10000,
- rawKeyPair: "good-keypair",
- },
- cert: {
- validUntil: Date.now() + CERT_LIFETIME + 10000,
- rawCert: "good-cert",
- },
- };
-
- yield fxa.setSignedInUser(credentials);
- let {keyPair, certificate} = yield fxa.internal.getKeypairAndCertificate(fxa.internal.currentAccountState);
- // should have the same keypair and cert.
- do_check_eq(keyPair, credentials.keyPair.rawKeyPair);
- do_check_eq(certificate, credentials.cert.rawCert);
- yield fxa.signOut(/*localOnly = */true);
-});
-
-add_task(function* test_getCertificateExpiredCert() {
- _("getCertificateExpiredCert()");
- let fxa = MakeFxAccounts({
- getCertificateSigned() {
- return "new cert";
- }
- });
- let credentials = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- sessionToken: "dead",
- verified: true,
- // A cached keypair that remains valid.
- keyPair: {
- validUntil: Date.now() + KEY_LIFETIME + 10000,
- rawKeyPair: "good-keypair",
- },
- // A cached certificate which has expired.
- cert: {
- validUntil: Date.parse("Mon, 13 Jan 2000 21:45:06 GMT"),
- rawCert: "expired-cert",
- },
- };
- yield fxa.setSignedInUser(credentials);
- let {keyPair, certificate} = yield fxa.internal.getKeypairAndCertificate(fxa.internal.currentAccountState);
- // should have the same keypair but a new cert.
- do_check_eq(keyPair, credentials.keyPair.rawKeyPair);
- do_check_neq(certificate, credentials.cert.rawCert);
- yield fxa.signOut(/*localOnly = */true);
-});
-
-add_task(function* test_getCertificateExpiredKeypair() {
- _("getCertificateExpiredKeypair()");
- let fxa = MakeFxAccounts({
- getCertificateSigned() {
- return "new cert";
- },
- });
- let credentials = {
- email: "foo@example.com",
- uid: "1234@lcip.org",
- sessionToken: "dead",
- verified: true,
- // A cached keypair that has expired.
- keyPair: {
- validUntil: Date.now() - 1000,
- rawKeyPair: "expired-keypair",
- },
- // A cached certificate which remains valid.
- cert: {
- validUntil: Date.now() + CERT_LIFETIME + 10000,
- rawCert: "expired-cert",
- },
- };
-
- yield fxa.setSignedInUser(credentials);
- let {keyPair, certificate} = yield fxa.internal.getKeypairAndCertificate(fxa.internal.currentAccountState);
- // even though the cert was valid, the fact the keypair was not means we
- // should have fetched both.
- do_check_neq(keyPair, credentials.keyPair.rawKeyPair);
- do_check_neq(certificate, credentials.cert.rawCert);
- yield fxa.signOut(/*localOnly = */true);
-});
-
-// Sanity-check that our mocked client is working correctly
-add_test(function test_client_mock() {
- let fxa = new MockFxAccounts();
- let client = fxa.internal.fxAccountsClient;
- do_check_eq(client._verified, false);
- do_check_eq(typeof client.signIn, "function");
-
- // The recoveryEmailStatus function eventually fulfills its promise
- client.recoveryEmailStatus()
- .then(response => {
- do_check_eq(response.verified, false);
- run_next_test();
- });
-});
-
-// Sign in a user, and after a little while, verify the user's email.
-// Right after signing in the user, we should get the 'onlogin' notification.
-// Polling should detect that the email is verified, and eventually
-// 'onverified' should be observed
-add_test(function test_verification_poll() {
- let fxa = new MockFxAccounts();
- let test_user = getTestUser("francine");
- let login_notification_received = false;
-
- makeObserver(ONVERIFIED_NOTIFICATION, function() {
- log.debug("test_verification_poll observed onverified");
- // Once email verification is complete, we will observe onverified
- fxa.internal.getUserAccountData().then(user => {
- // And confirm that the user's state has changed
- do_check_eq(user.verified, true);
- do_check_eq(user.email, test_user.email);
- do_check_true(login_notification_received);
- run_next_test();
- });
- });
-
- makeObserver(ONLOGIN_NOTIFICATION, function() {
- log.debug("test_verification_poll observer onlogin");
- login_notification_received = true;
- });
-
- fxa.setSignedInUser(test_user).then(() => {
- fxa.internal.getUserAccountData().then(user => {
- // The user is signing in, but email has not been verified yet
- do_check_eq(user.verified, false);
- do_timeout(200, function() {
- log.debug("Mocking verification of francine's email");
- fxa.internal.fxAccountsClient._email = test_user.email;
- fxa.internal.fxAccountsClient._verified = true;
- });
- });
- });
-});
-
-// Sign in the user, but never verify the email. The check-email
-// poll should time out. No verifiedlogin event should be observed, and the
-// internal whenVerified promise should be rejected
-add_test(function test_polling_timeout() {
- // This test could be better - the onverified observer might fire on
- // somebody else's stack, and we're not making sure that we're not receiving
- // such a message. In other words, this tests either failure, or success, but
- // not both.
-
- let fxa = new MockFxAccounts();
- let test_user = getTestUser("carol");
-
- let removeObserver = makeObserver(ONVERIFIED_NOTIFICATION, function() {
- do_throw("We should not be getting a login event!");
- });
-
- fxa.internal.POLL_SESSION = 1;
-
- let p = fxa.internal.whenVerified({});
-
- fxa.setSignedInUser(test_user).then(() => {
- p.then(
- (success) => {
- do_throw("this should not succeed");
- },
- (fail) => {
- removeObserver();
- fxa.signOut().then(run_next_test);
- }
- );
- });
-});
-
-add_test(function test_getKeys() {
- let fxa = new MockFxAccounts();
- let user = getTestUser("eusebius");
-
- // Once email has been verified, we will be able to get keys
- user.verified = true;
-
- fxa.setSignedInUser(user).then(() => {
- fxa.getSignedInUser().then((user) => {
- // Before getKeys, we have no keys
- do_check_eq(!!user.kA, false);
- do_check_eq(!!user.kB, false);
- // And we still have a key-fetch token and unwrapBKey to use
- do_check_eq(!!user.keyFetchToken, true);
- do_check_eq(!!user.unwrapBKey, true);
-
- fxa.internal.getKeys().then(() => {
- fxa.getSignedInUser().then((user) => {
- // Now we should have keys
- do_check_eq(fxa.internal.isUserEmailVerified(user), true);
- do_check_eq(!!user.verified, true);
- do_check_eq(user.kA, expandHex("11"));
- do_check_eq(user.kB, expandHex("66"));
- do_check_eq(user.keyFetchToken, undefined);
- do_check_eq(user.unwrapBKey, undefined);
- run_next_test();
- });
- });
- });
- });
-});
-
-add_task(function* test_getKeys_nonexistent_account() {
- let fxa = new MockFxAccounts();
- let bismarck = getTestUser("bismarck");
-
- let client = fxa.internal.fxAccountsClient;
- client.accountStatus = () => Promise.resolve(false);
- client.accountKeys = () => {
- return Promise.reject({
- code: 401,
- errno: ERRNO_INVALID_AUTH_TOKEN,
- });
- };
-
- yield fxa.setSignedInUser(bismarck);
-
- let promiseLogout = new Promise(resolve => {
- makeObserver(ONLOGOUT_NOTIFICATION, function() {
- log.debug("test_getKeys_nonexistent_account observed logout");
- resolve();
- });
- });
-
- try {
- yield fxa.internal.getKeys();
- do_check_true(false);
- } catch (err) {
- do_check_eq(err.code, 401);
- do_check_eq(err.errno, ERRNO_INVALID_AUTH_TOKEN);
- }
-
- yield promiseLogout;
-
- let user = yield fxa.internal.getUserAccountData();
- do_check_eq(user, null);
-});
-
-// getKeys with invalid keyFetchToken should delete keyFetchToken from storage
-add_task(function* test_getKeys_invalid_token() {
- let fxa = new MockFxAccounts();
- let yusuf = getTestUser("yusuf");
-
- let client = fxa.internal.fxAccountsClient;
- client.accountStatus = () => Promise.resolve(true);
- client.accountKeys = () => {
- return Promise.reject({
- code: 401,
- errno: ERRNO_INVALID_AUTH_TOKEN,
- });
- };
-
- yield fxa.setSignedInUser(yusuf);
-
- try {
- yield fxa.internal.getKeys();
- do_check_true(false);
- } catch (err) {
- do_check_eq(err.code, 401);
- do_check_eq(err.errno, ERRNO_INVALID_AUTH_TOKEN);
- }
-
- let user = yield fxa.internal.getUserAccountData();
- do_check_eq(user.email, yusuf.email);
- do_check_eq(user.keyFetchToken, null);
-});
-
-// fetchAndUnwrapKeys with no keyFetchToken should trigger signOut
-add_test(function test_fetchAndUnwrapKeys_no_token() {
- let fxa = new MockFxAccounts();
- let user = getTestUser("lettuce.protheroe");
- delete user.keyFetchToken
-
- makeObserver(ONLOGOUT_NOTIFICATION, function() {
- log.debug("test_fetchAndUnwrapKeys_no_token observed logout");
- fxa.internal.getUserAccountData().then(user => {
- run_next_test();
- });
- });
-
- fxa.setSignedInUser(user).then(
- user => {
- return fxa.internal.fetchAndUnwrapKeys();
- }
- ).then(
- null,
- error => {
- log.info("setSignedInUser correctly rejected");
- }
- )
-});
-
-// Alice (User A) signs up but never verifies her email. Then Bob (User B)
-// signs in with a verified email. Ensure that no sign-in events are triggered
-// on Alice's behalf. In the end, Bob should be the signed-in user.
-add_test(function test_overlapping_signins() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- let bob = getTestUser("bob");
-
- makeObserver(ONVERIFIED_NOTIFICATION, function() {
- log.debug("test_overlapping_signins observed onverified");
- // Once email verification is complete, we will observe onverified
- fxa.internal.getUserAccountData().then(user => {
- do_check_eq(user.email, bob.email);
- do_check_eq(user.verified, true);
- run_next_test();
- });
- });
-
- // Alice is the user signing in; her email is unverified.
- fxa.setSignedInUser(alice).then(() => {
- log.debug("Alice signing in ...");
- fxa.internal.getUserAccountData().then(user => {
- do_check_eq(user.email, alice.email);
- do_check_eq(user.verified, false);
- log.debug("Alice has not verified her email ...");
-
- // Now Bob signs in instead and actually verifies his email
- log.debug("Bob signing in ...");
- fxa.setSignedInUser(bob).then(() => {
- do_timeout(200, function() {
- // Mock email verification ...
- log.debug("Bob verifying his email ...");
- fxa.internal.fxAccountsClient._verified = true;
- });
- });
- });
- });
-});
-
-add_task(function* test_getAssertion_invalid_token() {
- let fxa = new MockFxAccounts();
-
- let client = fxa.internal.fxAccountsClient;
- client.accountStatus = () => Promise.resolve(true);
-
- let creds = {
- sessionToken: "sessionToken",
- kA: expandHex("11"),
- kB: expandHex("66"),
- verified: true,
- email: "sonia@example.com",
- };
- yield fxa.setSignedInUser(creds);
-
- try {
- let promiseAssertion = fxa.getAssertion("audience.example.com");
- fxa.internal._d_signCertificate.reject({
- code: 401,
- errno: ERRNO_INVALID_AUTH_TOKEN,
- });
- yield promiseAssertion;
- do_check_true(false, "getAssertion should reject invalid session token");
- } catch (err) {
- do_check_eq(err.code, 401);
- do_check_eq(err.errno, ERRNO_INVALID_AUTH_TOKEN);
- }
-
- let user = yield fxa.internal.getUserAccountData();
- do_check_eq(user.email, creds.email);
- do_check_eq(user.sessionToken, null);
-});
-
-add_task(function* test_getAssertion() {
- let fxa = new MockFxAccounts();
-
- do_check_throws(function* () {
- yield fxa.getAssertion("nonaudience");
- });
-
- let creds = {
- sessionToken: "sessionToken",
- kA: expandHex("11"),
- kB: expandHex("66"),
- verified: true
- };
- // By putting kA/kB/verified in "creds", we skip ahead
- // to the "we're ready" stage.
- yield fxa.setSignedInUser(creds);
-
- _("== ready to go\n");
- // Start with a nice arbitrary but realistic date. Here we use a nice RFC
- // 1123 date string like we would get from an HTTP header. Over the course of
- // the test, we will update 'now', but leave 'start' where it is.
- let now = Date.parse("Mon, 13 Jan 2014 21:45:06 GMT");
- let start = now;
- fxa.internal._now_is = now;
-
- let d = fxa.getAssertion("audience.example.com");
- // At this point, a thread has been spawned to generate the keys.
- _("-- back from fxa.getAssertion\n");
- fxa.internal._d_signCertificate.resolve("cert1");
- let assertion = yield d;
- do_check_eq(fxa.internal._getCertificateSigned_calls.length, 1);
- do_check_eq(fxa.internal._getCertificateSigned_calls[0][0], "sessionToken");
- do_check_neq(assertion, null);
- _("ASSERTION: " + assertion + "\n");
- let pieces = assertion.split("~");
- do_check_eq(pieces[0], "cert1");
- let userData = yield fxa.getSignedInUser();
- let keyPair = userData.keyPair;
- let cert = userData.cert;
- do_check_neq(keyPair, undefined);
- _(keyPair.validUntil + "\n");
- let p2 = pieces[1].split(".");
- let header = JSON.parse(atob(p2[0]));
- _("HEADER: " + JSON.stringify(header) + "\n");
- do_check_eq(header.alg, "DS128");
- let payload = JSON.parse(atob(p2[1]));
- _("PAYLOAD: " + JSON.stringify(payload) + "\n");
- do_check_eq(payload.aud, "audience.example.com");
- do_check_eq(keyPair.validUntil, start + KEY_LIFETIME);
- do_check_eq(cert.validUntil, start + CERT_LIFETIME);
- _("delta: " + Date.parse(payload.exp - start) + "\n");
- let exp = Number(payload.exp);
-
- do_check_eq(exp, now + ASSERTION_LIFETIME);
-
- // Reset for next call.
- fxa.internal._d_signCertificate = Promise.defer();
-
- // Getting a new assertion "soon" (i.e., w/o incrementing "now"), even for
- // a new audience, should not provoke key generation or a signing request.
- assertion = yield fxa.getAssertion("other.example.com");
-
- // There were no additional calls - same number of getcert calls as before
- do_check_eq(fxa.internal._getCertificateSigned_calls.length, 1);
-
- // Wait an hour; assertion use period expires, but not the certificate
- now += ONE_HOUR_MS;
- fxa.internal._now_is = now;
-
- // This won't block on anything - will make an assertion, but not get a
- // new certificate.
- assertion = yield fxa.getAssertion("third.example.com");
-
- // Test will time out if that failed (i.e., if that had to go get a new cert)
- pieces = assertion.split("~");
- do_check_eq(pieces[0], "cert1");
- p2 = pieces[1].split(".");
- header = JSON.parse(atob(p2[0]));
- payload = JSON.parse(atob(p2[1]));
- do_check_eq(payload.aud, "third.example.com");
-
- // The keypair and cert should have the same validity as before, but the
- // expiration time of the assertion should be different. We compare this to
- // the initial start time, to which they are relative, not the current value
- // of "now".
- userData = yield fxa.getSignedInUser();
-
- keyPair = userData.keyPair;
- cert = userData.cert;
- do_check_eq(keyPair.validUntil, start + KEY_LIFETIME);
- do_check_eq(cert.validUntil, start + CERT_LIFETIME);
- exp = Number(payload.exp);
- do_check_eq(exp, now + ASSERTION_LIFETIME);
-
- // Now we wait even longer, and expect both assertion and cert to expire. So
- // we will have to get a new keypair and cert.
- now += ONE_DAY_MS;
- fxa.internal._now_is = now;
- d = fxa.getAssertion("fourth.example.com");
- fxa.internal._d_signCertificate.resolve("cert2");
- assertion = yield d;
- do_check_eq(fxa.internal._getCertificateSigned_calls.length, 2);
- do_check_eq(fxa.internal._getCertificateSigned_calls[1][0], "sessionToken");
- pieces = assertion.split("~");
- do_check_eq(pieces[0], "cert2");
- p2 = pieces[1].split(".");
- header = JSON.parse(atob(p2[0]));
- payload = JSON.parse(atob(p2[1]));
- do_check_eq(payload.aud, "fourth.example.com");
- userData = yield fxa.getSignedInUser();
- keyPair = userData.keyPair;
- cert = userData.cert;
- do_check_eq(keyPair.validUntil, now + KEY_LIFETIME);
- do_check_eq(cert.validUntil, now + CERT_LIFETIME);
- exp = Number(payload.exp);
-
- do_check_eq(exp, now + ASSERTION_LIFETIME);
- _("----- DONE ----\n");
-});
-
-add_task(function* test_resend_email_not_signed_in() {
- let fxa = new MockFxAccounts();
-
- try {
- yield fxa.resendVerificationEmail();
- } catch(err) {
- do_check_eq(err.message,
- "Cannot resend verification email; no signed-in user");
- return;
- }
- do_throw("Should not be able to resend email when nobody is signed in");
-});
-
-add_test(function test_accountStatus() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
-
- // If we have no user, we have no account server-side
- fxa.accountStatus().then(
- (result) => {
- do_check_false(result);
- }
- ).then(
- () => {
- fxa.setSignedInUser(alice).then(
- () => {
- fxa.accountStatus().then(
- (result) => {
- // FxAccounts.accountStatus() should match Client.accountStatus()
- do_check_true(result);
- fxa.internal.fxAccountsClient._deletedOnServer = true;
- fxa.accountStatus().then(
- (result) => {
- do_check_false(result);
- fxa.internal.fxAccountsClient._deletedOnServer = false;
- fxa.signOut().then(run_next_test);
- }
- );
- }
- )
- }
- );
- }
- );
-});
-
-add_task(function* test_resend_email_invalid_token() {
- let fxa = new MockFxAccounts();
- let sophia = getTestUser("sophia");
- do_check_neq(sophia.sessionToken, null);
-
- let client = fxa.internal.fxAccountsClient;
- client.resendVerificationEmail = () => {
- return Promise.reject({
- code: 401,
- errno: ERRNO_INVALID_AUTH_TOKEN,
- });
- };
- client.accountStatus = () => Promise.resolve(true);
-
- yield fxa.setSignedInUser(sophia);
- let user = yield fxa.internal.getUserAccountData();
- do_check_eq(user.email, sophia.email);
- do_check_eq(user.verified, false);
- log.debug("Sophia wants verification email resent");
-
- try {
- yield fxa.resendVerificationEmail();
- do_check_true(false, "resendVerificationEmail should reject invalid session token");
- } catch (err) {
- do_check_eq(err.code, 401);
- do_check_eq(err.errno, ERRNO_INVALID_AUTH_TOKEN);
- }
-
- user = yield fxa.internal.getUserAccountData();
- do_check_eq(user.email, sophia.email);
- do_check_eq(user.sessionToken, null);
-});
-
-add_test(function test_resend_email() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
-
- let initialState = fxa.internal.currentAccountState;
-
- // Alice is the user signing in; her email is unverified.
- fxa.setSignedInUser(alice).then(() => {
- log.debug("Alice signing in");
-
- // We're polling for the first email
- do_check_true(fxa.internal.currentAccountState !== initialState);
- let aliceState = fxa.internal.currentAccountState;
-
- // The polling timer is ticking
- do_check_true(fxa.internal.currentTimer > 0);
-
- fxa.internal.getUserAccountData().then(user => {
- do_check_eq(user.email, alice.email);
- do_check_eq(user.verified, false);
- log.debug("Alice wants verification email resent");
-
- fxa.resendVerificationEmail().then((result) => {
- // Mock server response; ensures that the session token actually was
- // passed to the client to make the hawk call
- do_check_eq(result, "alice's session token");
-
- // Timer was not restarted
- do_check_true(fxa.internal.currentAccountState === aliceState);
-
- // Timer is still ticking
- do_check_true(fxa.internal.currentTimer > 0);
-
- // Ok abort polling before we go on to the next test
- fxa.internal.abortExistingFlow();
- run_next_test();
- });
- });
- });
-});
-
-add_task(function* test_sign_out_with_device() {
- const fxa = new MockFxAccounts();
-
- const credentials = getTestUser("alice");
- yield fxa.internal.setSignedInUser(credentials);
-
- const user = yield fxa.internal.getUserAccountData();
- do_check_true(user);
- Object.keys(credentials).forEach(key => do_check_eq(credentials[key], user[key]));
-
- const spy = {
- signOut: { count: 0 },
- signOutAndDeviceDestroy: { count: 0, args: [] }
- };
- const client = fxa.internal.fxAccountsClient;
- client.signOut = function () {
- spy.signOut.count += 1;
- return Promise.resolve();
- };
- client.signOutAndDestroyDevice = function () {
- spy.signOutAndDeviceDestroy.count += 1;
- spy.signOutAndDeviceDestroy.args.push(arguments);
- return Promise.resolve();
- };
-
- const promise = new Promise(resolve => {
- makeObserver(ONLOGOUT_NOTIFICATION, () => {
- log.debug("test_sign_out_with_device observed onlogout");
- // user should be undefined after sign out
- fxa.internal.getUserAccountData().then(user2 => {
- do_check_eq(user2, null);
- do_check_eq(spy.signOut.count, 0);
- do_check_eq(spy.signOutAndDeviceDestroy.count, 1);
- do_check_eq(spy.signOutAndDeviceDestroy.args[0].length, 3);
- do_check_eq(spy.signOutAndDeviceDestroy.args[0][0], credentials.sessionToken);
- do_check_eq(spy.signOutAndDeviceDestroy.args[0][1], credentials.deviceId);
- do_check_true(spy.signOutAndDeviceDestroy.args[0][2]);
- do_check_eq(spy.signOutAndDeviceDestroy.args[0][2].service, "sync");
- resolve();
- });
- });
- });
-
- yield fxa.signOut();
-
- yield promise;
-});
-
-add_task(function* test_sign_out_without_device() {
- const fxa = new MockFxAccounts();
-
- const credentials = getTestUser("alice");
- delete credentials.deviceId;
- yield fxa.internal.setSignedInUser(credentials);
-
- const user = yield fxa.internal.getUserAccountData();
-
- const spy = {
- signOut: { count: 0, args: [] },
- signOutAndDeviceDestroy: { count: 0 }
- };
- const client = fxa.internal.fxAccountsClient;
- client.signOut = function () {
- spy.signOut.count += 1;
- spy.signOut.args.push(arguments);
- return Promise.resolve();
- };
- client.signOutAndDestroyDevice = function () {
- spy.signOutAndDeviceDestroy.count += 1;
- return Promise.resolve();
- };
-
- const promise = new Promise(resolve => {
- makeObserver(ONLOGOUT_NOTIFICATION, () => {
- log.debug("test_sign_out_without_device observed onlogout");
- // user should be undefined after sign out
- fxa.internal.getUserAccountData().then(user2 => {
- do_check_eq(user2, null);
- do_check_eq(spy.signOut.count, 1);
- do_check_eq(spy.signOut.args[0].length, 2);
- do_check_eq(spy.signOut.args[0][0], credentials.sessionToken);
- do_check_true(spy.signOut.args[0][1]);
- do_check_eq(spy.signOut.args[0][1].service, "sync");
- do_check_eq(spy.signOutAndDeviceDestroy.count, 0);
- resolve();
- });
- });
- });
-
- yield fxa.signOut();
-
- yield promise;
-});
-
-add_task(function* test_sign_out_with_remote_error() {
- let fxa = new MockFxAccounts();
- let client = fxa.internal.fxAccountsClient;
- let remoteSignOutCalled = false;
- // Force remote sign out to trigger an error
- client.signOutAndDestroyDevice = function() { remoteSignOutCalled = true; throw "Remote sign out error"; };
- let promiseLogout = new Promise(resolve => {
- makeObserver(ONLOGOUT_NOTIFICATION, function() {
- log.debug("test_sign_out_with_remote_error observed onlogout");
- resolve();
- });
- });
-
- let jane = getTestUser("jane");
- yield fxa.setSignedInUser(jane);
- yield fxa.signOut();
- yield promiseLogout;
-
- let user = yield fxa.internal.getUserAccountData();
- do_check_eq(user, null);
- do_check_true(remoteSignOutCalled);
-});
-
-add_test(function test_getOAuthToken() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
- let getTokenFromAssertionCalled = false;
-
- fxa.internal._d_signCertificate.resolve("cert1");
-
- // create a mock oauth client
- let client = new FxAccountsOAuthGrantClient({
- serverURL: "http://example.com/v1",
- client_id: "abc123"
- });
- client.getTokenFromAssertion = function () {
- getTokenFromAssertionCalled = true;
- return Promise.resolve({ access_token: "token" });
- };
-
- fxa.setSignedInUser(alice).then(
- () => {
- fxa.getOAuthToken({ scope: "profile", client: client }).then(
- (result) => {
- do_check_true(getTokenFromAssertionCalled);
- do_check_eq(result, "token");
- run_next_test();
- }
- )
- }
- );
-
-});
-
-add_test(function test_getOAuthTokenScoped() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
- let getTokenFromAssertionCalled = false;
-
- fxa.internal._d_signCertificate.resolve("cert1");
-
- // create a mock oauth client
- let client = new FxAccountsOAuthGrantClient({
- serverURL: "http://example.com/v1",
- client_id: "abc123"
- });
- client.getTokenFromAssertion = function (assertion, scopeString) {
- equal(scopeString, "foo bar");
- getTokenFromAssertionCalled = true;
- return Promise.resolve({ access_token: "token" });
- };
-
- fxa.setSignedInUser(alice).then(
- () => {
- fxa.getOAuthToken({ scope: ["foo", "bar"], client: client }).then(
- (result) => {
- do_check_true(getTokenFromAssertionCalled);
- do_check_eq(result, "token");
- run_next_test();
- }
- )
- }
- );
-
-});
-
-add_task(function* test_getOAuthTokenCached() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
- let numTokenFromAssertionCalls = 0;
-
- fxa.internal._d_signCertificate.resolve("cert1");
-
- // create a mock oauth client
- let client = new FxAccountsOAuthGrantClient({
- serverURL: "http://example.com/v1",
- client_id: "abc123"
- });
- client.getTokenFromAssertion = function () {
- numTokenFromAssertionCalls += 1;
- return Promise.resolve({ access_token: "token" });
- };
-
- yield fxa.setSignedInUser(alice);
- let result = yield fxa.getOAuthToken({ scope: "profile", client: client, service: "test-service" });
- do_check_eq(numTokenFromAssertionCalls, 1);
- do_check_eq(result, "token");
-
- // requesting it again should not re-fetch the token.
- result = yield fxa.getOAuthToken({ scope: "profile", client: client, service: "test-service" });
- do_check_eq(numTokenFromAssertionCalls, 1);
- do_check_eq(result, "token");
- // But requesting the same service and a different scope *will* get a new one.
- result = yield fxa.getOAuthToken({ scope: "something-else", client: client, service: "test-service" });
- do_check_eq(numTokenFromAssertionCalls, 2);
- do_check_eq(result, "token");
-});
-
-add_task(function* test_getOAuthTokenCachedScopeNormalization() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
- let numTokenFromAssertionCalls = 0;
-
- fxa.internal._d_signCertificate.resolve("cert1");
-
- // create a mock oauth client
- let client = new FxAccountsOAuthGrantClient({
- serverURL: "http://example.com/v1",
- client_id: "abc123"
- });
- client.getTokenFromAssertion = function () {
- numTokenFromAssertionCalls += 1;
- return Promise.resolve({ access_token: "token" });
- };
-
- yield fxa.setSignedInUser(alice);
- let result = yield fxa.getOAuthToken({ scope: ["foo", "bar"], client: client, service: "test-service" });
- do_check_eq(numTokenFromAssertionCalls, 1);
- do_check_eq(result, "token");
-
- // requesting it again with the scope array in a different order not re-fetch the token.
- result = yield fxa.getOAuthToken({ scope: ["bar", "foo"], client: client, service: "test-service" });
- do_check_eq(numTokenFromAssertionCalls, 1);
- do_check_eq(result, "token");
- // requesting it again with the scope array in different case not re-fetch the token.
- result = yield fxa.getOAuthToken({ scope: ["Bar", "Foo"], client: client, service: "test-service" });
- do_check_eq(numTokenFromAssertionCalls, 1);
- do_check_eq(result, "token");
- // But requesting with a new entry in the array does fetch one.
- result = yield fxa.getOAuthToken({ scope: ["foo", "bar", "etc"], client: client, service: "test-service" });
- do_check_eq(numTokenFromAssertionCalls, 2);
- do_check_eq(result, "token");
-});
-
-Services.prefs.setCharPref("identity.fxaccounts.remote.oauth.uri", "https://example.com/v1");
-add_test(function test_getOAuthToken_invalid_param() {
- let fxa = new MockFxAccounts();
-
- fxa.getOAuthToken()
- .then(null, err => {
- do_check_eq(err.message, "INVALID_PARAMETER");
- fxa.signOut().then(run_next_test);
- });
-});
-
-add_test(function test_getOAuthToken_invalid_scope_array() {
- let fxa = new MockFxAccounts();
-
- fxa.getOAuthToken({scope: []})
- .then(null, err => {
- do_check_eq(err.message, "INVALID_PARAMETER");
- fxa.signOut().then(run_next_test);
- });
-});
-
-add_test(function test_getOAuthToken_misconfigure_oauth_uri() {
- let fxa = new MockFxAccounts();
-
- Services.prefs.deleteBranch("identity.fxaccounts.remote.oauth.uri");
-
- fxa.getOAuthToken()
- .then(null, err => {
- do_check_eq(err.message, "INVALID_PARAMETER");
- // revert the pref
- Services.prefs.setCharPref("identity.fxaccounts.remote.oauth.uri", "https://example.com/v1");
- fxa.signOut().then(run_next_test);
- });
-});
-
-add_test(function test_getOAuthToken_no_account() {
- let fxa = new MockFxAccounts();
-
- fxa.internal.currentAccountState.getUserAccountData = function () {
- return Promise.resolve(null);
- };
-
- fxa.getOAuthToken({ scope: "profile" })
- .then(null, err => {
- do_check_eq(err.message, "NO_ACCOUNT");
- fxa.signOut().then(run_next_test);
- });
-});
-
-add_test(function test_getOAuthToken_unverified() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
-
- fxa.setSignedInUser(alice).then(() => {
- fxa.getOAuthToken({ scope: "profile" })
- .then(null, err => {
- do_check_eq(err.message, "UNVERIFIED_ACCOUNT");
- fxa.signOut().then(run_next_test);
- });
- });
-});
-
-add_test(function test_getOAuthToken_network_error() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
-
- fxa.internal._d_signCertificate.resolve("cert1");
-
- // create a mock oauth client
- let client = new FxAccountsOAuthGrantClient({
- serverURL: "http://example.com/v1",
- client_id: "abc123"
- });
- client.getTokenFromAssertion = function () {
- return Promise.reject(new FxAccountsOAuthGrantClientError({
- error: ERROR_NETWORK,
- errno: ERRNO_NETWORK
- }));
- };
-
- fxa.setSignedInUser(alice).then(() => {
- fxa.getOAuthToken({ scope: "profile", client: client })
- .then(null, err => {
- do_check_eq(err.message, "NETWORK_ERROR");
- do_check_eq(err.details.errno, ERRNO_NETWORK);
- run_next_test();
- });
- });
-});
-
-add_test(function test_getOAuthToken_auth_error() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
-
- fxa.internal._d_signCertificate.resolve("cert1");
-
- // create a mock oauth client
- let client = new FxAccountsOAuthGrantClient({
- serverURL: "http://example.com/v1",
- client_id: "abc123"
- });
- client.getTokenFromAssertion = function () {
- return Promise.reject(new FxAccountsOAuthGrantClientError({
- error: ERROR_INVALID_FXA_ASSERTION,
- errno: ERRNO_INVALID_FXA_ASSERTION
- }));
- };
-
- fxa.setSignedInUser(alice).then(() => {
- fxa.getOAuthToken({ scope: "profile", client: client })
- .then(null, err => {
- do_check_eq(err.message, "AUTH_ERROR");
- do_check_eq(err.details.errno, ERRNO_INVALID_FXA_ASSERTION);
- run_next_test();
- });
- });
-});
-
-add_test(function test_getOAuthToken_unknown_error() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
-
- fxa.internal._d_signCertificate.resolve("cert1");
-
- // create a mock oauth client
- let client = new FxAccountsOAuthGrantClient({
- serverURL: "http://example.com/v1",
- client_id: "abc123"
- });
- client.getTokenFromAssertion = function () {
- return Promise.reject("boom");
- };
-
- fxa.setSignedInUser(alice).then(() => {
- fxa.getOAuthToken({ scope: "profile", client: client })
- .then(null, err => {
- do_check_eq(err.message, "UNKNOWN_ERROR");
- run_next_test();
- });
- });
-});
-
-add_test(function test_getSignedInUserProfile() {
- let alice = getTestUser("alice");
- alice.verified = true;
-
- let mockProfile = {
- getProfile: function () {
- return Promise.resolve({ avatar: "image" });
- },
- tearDown: function() {},
- };
- let fxa = new FxAccounts({
- _signOutServer() { return Promise.resolve(); },
- _registerOrUpdateDevice() { return Promise.resolve(); }
- });
-
- fxa.setSignedInUser(alice).then(() => {
- fxa.internal._profile = mockProfile;
- fxa.getSignedInUserProfile()
- .then(result => {
- do_check_true(!!result);
- do_check_eq(result.avatar, "image");
- run_next_test();
- });
- });
-});
-
-add_test(function test_getSignedInUserProfile_error_uses_account_data() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
-
- fxa.internal.getSignedInUser = function () {
- return Promise.resolve({ email: "foo@bar.com" });
- };
-
- let teardownCalled = false;
- fxa.setSignedInUser(alice).then(() => {
- fxa.internal._profile = {
- getProfile: function () {
- return Promise.reject("boom");
- },
- tearDown: function() {
- teardownCalled = true;
- }
- };
-
- fxa.getSignedInUserProfile()
- .catch(error => {
- do_check_eq(error.message, "UNKNOWN_ERROR");
- fxa.signOut().then(() => {
- do_check_true(teardownCalled);
- run_next_test();
- });
- });
- });
-});
-
-add_test(function test_getSignedInUserProfile_unverified_account() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
-
- fxa.setSignedInUser(alice).then(() => {
- fxa.getSignedInUserProfile()
- .catch(error => {
- do_check_eq(error.message, "UNVERIFIED_ACCOUNT");
- fxa.signOut().then(run_next_test);
- });
- });
-
-});
-
-add_test(function test_getSignedInUserProfile_no_account_data() {
- let fxa = new MockFxAccounts();
-
- fxa.internal.getSignedInUser = function () {
- return Promise.resolve(null);
- };
-
- fxa.getSignedInUserProfile()
- .catch(error => {
- do_check_eq(error.message, "NO_ACCOUNT");
- fxa.signOut().then(run_next_test);
- });
-
-});
-
-add_task(function* test_checkVerificationStatusFailed() {
- let fxa = new MockFxAccounts();
- let alice = getTestUser("alice");
- alice.verified = true;
-
- let client = fxa.internal.fxAccountsClient;
- client.recoveryEmailStatus = () => {
- return Promise.reject({
- code: 401,
- errno: ERRNO_INVALID_AUTH_TOKEN,
- });
- };
- client.accountStatus = () => Promise.resolve(true);
-
- yield fxa.setSignedInUser(alice);
- let user = yield fxa.internal.getUserAccountData();
- do_check_neq(alice.sessionToken, null);
- do_check_eq(user.email, alice.email);
- do_check_eq(user.verified, true);
-
- yield fxa.checkVerificationStatus();
-
- user = yield fxa.internal.getUserAccountData();
- do_check_eq(user.email, alice.email);
- do_check_eq(user.sessionToken, null);
-});
-
-/*
- * End of tests.
- * Utility functions follow.
- */
-
-function expandHex(two_hex) {
- // Return a 64-character hex string, encoding 32 identical bytes.
- let eight_hex = two_hex + two_hex + two_hex + two_hex;
- let thirtytwo_hex = eight_hex + eight_hex + eight_hex + eight_hex;
- return thirtytwo_hex + thirtytwo_hex;
-};
-
-function expandBytes(two_hex) {
- return CommonUtils.hexToBytes(expandHex(two_hex));
-};
-
-function getTestUser(name) {
- return {
- email: name + "@example.com",
- uid: "1ad7f502-4cc7-4ec1-a209-071fd2fae348",
- deviceId: name + "'s device id",
- sessionToken: name + "'s session token",
- keyFetchToken: name + "'s keyfetch token",
- unwrapBKey: expandHex("44"),
- verified: false
- };
-}
-
-function makeObserver(aObserveTopic, aObserveFunc) {
- let observer = {
- // nsISupports provides type management in C++
- // nsIObserver is to be an observer
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
-
- observe: function (aSubject, aTopic, aData) {
- log.debug("observed " + aTopic + " " + aData);
- if (aTopic == aObserveTopic) {
- removeMe();
- aObserveFunc(aSubject, aTopic, aData);
- }
- }
- };
-
- function removeMe() {
- log.debug("removing observer for " + aObserveTopic);
- Services.obs.removeObserver(observer, aObserveTopic);
- }
-
- Services.obs.addObserver(observer, aObserveTopic, false);
- return removeMe;
-}
-
-function do_check_throws(func, result, stack)
-{
- if (!stack)
- stack = Components.stack.caller;
-
- try {
- func();
- } catch (ex) {
- if (ex.name == result) {
- return;
- }
- do_throw("Expected result " + result + ", caught " + ex.name, stack);
- }
-
- if (result) {
- do_throw("Expected result " + result + ", none thrown", stack);
- }
-}