зеркало из https://github.com/mozilla/gecko-dev.git
559 строки
18 KiB
JavaScript
559 строки
18 KiB
JavaScript
/* 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/FxAccounts.jsm");
|
|
Cu.import("resource://gre/modules/FxAccountsClient.jsm");
|
|
Cu.import("resource://gre/modules/FxAccountsCommon.js");
|
|
Cu.import("resource://gre/modules/Promise.jsm");
|
|
Cu.import("resource://gre/modules/Log.jsm");
|
|
|
|
initTestLogging("Trace");
|
|
|
|
var log = Log.repository.getLogger("Services.FxAccounts.test");
|
|
log.level = Log.Level.Debug;
|
|
|
|
const BOGUS_PUBLICKEY = "BBXOKjUb84pzws1wionFpfCBjDuCh4-s_1b52WA46K5wYL2gCWEOmFKWn_NkS5nmJwTBuO8qxxdjAIDtNeklvQc";
|
|
const BOGUS_AUTHKEY = "GSsIiaD2Mr83iPqwFNK4rw";
|
|
|
|
Services.prefs.setCharPref("identity.fxaccounts.loglevel", "Trace");
|
|
Log.repository.getLogger("FirefoxAccounts").level = Log.Level.Trace;
|
|
|
|
Services.prefs.setCharPref("identity.fxaccounts.remote.oauth.uri", "https://example.com/v1");
|
|
Services.prefs.setCharPref("identity.fxaccounts.oauth.client_id", "abc123");
|
|
Services.prefs.setCharPref("identity.fxaccounts.remote.profile.uri", "http://example.com/v1");
|
|
Services.prefs.setCharPref("identity.fxaccounts.settings.uri", "http://accounts.example.com/");
|
|
|
|
const DEVICE_REGISTRATION_VERSION = 42;
|
|
|
|
function MockStorageManager() {
|
|
}
|
|
|
|
MockStorageManager.prototype = {
|
|
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(device) {
|
|
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;
|
|
};
|
|
|
|
const { id: deviceId, name: deviceName, type: deviceType, sessionToken } = device;
|
|
|
|
this.registerDevice = (st, name, type) => Promise.resolve({ id: deviceId, name });
|
|
this.updateDevice = (st, id, name) => Promise.resolve({ id, name });
|
|
this.signOutAndDestroyDevice = () => Promise.resolve({});
|
|
this.getDeviceList = (st) =>
|
|
Promise.resolve([
|
|
{ id: deviceId, name: deviceName, type: deviceType, isCurrentDevice: st === sessionToken }
|
|
]);
|
|
|
|
FxAccountsClient.apply(this);
|
|
}
|
|
MockFxAccountsClient.prototype = {
|
|
__proto__: FxAccountsClient.prototype
|
|
}
|
|
|
|
function MockFxAccounts(device = {}) {
|
|
return new FxAccounts({
|
|
_getDeviceName() {
|
|
return device.name || "mock device name";
|
|
},
|
|
fxAccountsClient: new MockFxAccountsClient(device),
|
|
fxaPushService: {
|
|
registerPushEndpoint() {
|
|
return new Promise((resolve) => {
|
|
resolve({
|
|
endpoint: "http://mochi.test:8888",
|
|
getKey(type) {
|
|
return ChromeUtils.base64URLDecode(
|
|
type === "auth" ? BOGUS_AUTHKEY : BOGUS_PUBLICKEY,
|
|
{ padding: "ignore" });
|
|
}
|
|
});
|
|
});
|
|
},
|
|
unsubscribe() {
|
|
return Promise.resolve();
|
|
}
|
|
},
|
|
DEVICE_REGISTRATION_VERSION
|
|
});
|
|
}
|
|
|
|
add_task(function* test_updateDeviceRegistration_with_new_device() {
|
|
const deviceName = "foo";
|
|
const deviceType = "bar";
|
|
|
|
const credentials = getTestUser("baz");
|
|
delete credentials.deviceId;
|
|
const fxa = new MockFxAccounts({ name: deviceName });
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = {
|
|
registerDevice: { count: 0, args: [] },
|
|
updateDevice: { count: 0, args: [] },
|
|
getDeviceList: { count: 0, args: [] }
|
|
};
|
|
const client = fxa.internal.fxAccountsClient;
|
|
client.registerDevice = function() {
|
|
spy.registerDevice.count += 1;
|
|
spy.registerDevice.args.push(arguments);
|
|
return Promise.resolve({
|
|
id: "newly-generated device id",
|
|
createdAt: Date.now(),
|
|
name: deviceName,
|
|
type: deviceType
|
|
});
|
|
};
|
|
client.updateDevice = function() {
|
|
spy.updateDevice.count += 1;
|
|
spy.updateDevice.args.push(arguments);
|
|
return Promise.resolve({});
|
|
};
|
|
client.getDeviceList = function() {
|
|
spy.getDeviceList.count += 1;
|
|
spy.getDeviceList.args.push(arguments);
|
|
return Promise.resolve([]);
|
|
};
|
|
|
|
const result = yield fxa.updateDeviceRegistration();
|
|
|
|
do_check_eq(result, "newly-generated device id");
|
|
do_check_eq(spy.updateDevice.count, 0);
|
|
do_check_eq(spy.getDeviceList.count, 0);
|
|
do_check_eq(spy.registerDevice.count, 1);
|
|
do_check_eq(spy.registerDevice.args[0].length, 4);
|
|
do_check_eq(spy.registerDevice.args[0][0], credentials.sessionToken);
|
|
do_check_eq(spy.registerDevice.args[0][1], deviceName);
|
|
do_check_eq(spy.registerDevice.args[0][2], "desktop");
|
|
do_check_eq(spy.registerDevice.args[0][3].pushCallback, "http://mochi.test:8888");
|
|
do_check_eq(spy.registerDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY);
|
|
do_check_eq(spy.registerDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY);
|
|
|
|
const state = fxa.internal.currentAccountState;
|
|
const data = yield state.getUserAccountData();
|
|
|
|
do_check_eq(data.deviceId, "newly-generated device id");
|
|
do_check_eq(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION);
|
|
});
|
|
|
|
add_task(function* test_updateDeviceRegistration_with_existing_device() {
|
|
const deviceName = "phil's device";
|
|
|
|
const credentials = getTestUser("pb");
|
|
const fxa = new MockFxAccounts({ name: deviceName });
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = {
|
|
registerDevice: { count: 0, args: [] },
|
|
updateDevice: { count: 0, args: [] },
|
|
getDeviceList: { count: 0, args: [] }
|
|
};
|
|
const client = fxa.internal.fxAccountsClient;
|
|
client.registerDevice = function() {
|
|
spy.registerDevice.count += 1;
|
|
spy.registerDevice.args.push(arguments);
|
|
return Promise.resolve({});
|
|
};
|
|
client.updateDevice = function() {
|
|
spy.updateDevice.count += 1;
|
|
spy.updateDevice.args.push(arguments);
|
|
return Promise.resolve({
|
|
id: credentials.deviceId,
|
|
name: deviceName
|
|
});
|
|
};
|
|
client.getDeviceList = function() {
|
|
spy.getDeviceList.count += 1;
|
|
spy.getDeviceList.args.push(arguments);
|
|
return Promise.resolve([]);
|
|
};
|
|
const result = yield fxa.updateDeviceRegistration();
|
|
|
|
do_check_eq(result, credentials.deviceId);
|
|
do_check_eq(spy.registerDevice.count, 0);
|
|
do_check_eq(spy.getDeviceList.count, 0);
|
|
do_check_eq(spy.updateDevice.count, 1);
|
|
do_check_eq(spy.updateDevice.args[0].length, 4);
|
|
do_check_eq(spy.updateDevice.args[0][0], credentials.sessionToken);
|
|
do_check_eq(spy.updateDevice.args[0][1], credentials.deviceId);
|
|
do_check_eq(spy.updateDevice.args[0][2], deviceName);
|
|
do_check_eq(spy.updateDevice.args[0][3].pushCallback, "http://mochi.test:8888");
|
|
do_check_eq(spy.updateDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY);
|
|
do_check_eq(spy.updateDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY);
|
|
|
|
const state = fxa.internal.currentAccountState;
|
|
const data = yield state.getUserAccountData();
|
|
|
|
do_check_eq(data.deviceId, credentials.deviceId);
|
|
do_check_eq(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION);
|
|
});
|
|
|
|
add_task(function* test_updateDeviceRegistration_with_unknown_device_error() {
|
|
const deviceName = "foo";
|
|
const deviceType = "bar";
|
|
|
|
const credentials = getTestUser("baz");
|
|
const fxa = new MockFxAccounts({ name: deviceName });
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = {
|
|
registerDevice: { count: 0, args: [] },
|
|
updateDevice: { count: 0, args: [] },
|
|
getDeviceList: { count: 0, args: [] }
|
|
};
|
|
const client = fxa.internal.fxAccountsClient;
|
|
client.registerDevice = function() {
|
|
spy.registerDevice.count += 1;
|
|
spy.registerDevice.args.push(arguments);
|
|
return Promise.resolve({
|
|
id: "a different newly-generated device id",
|
|
createdAt: Date.now(),
|
|
name: deviceName,
|
|
type: deviceType
|
|
});
|
|
};
|
|
client.updateDevice = function() {
|
|
spy.updateDevice.count += 1;
|
|
spy.updateDevice.args.push(arguments);
|
|
return Promise.reject({
|
|
code: 400,
|
|
errno: ERRNO_UNKNOWN_DEVICE
|
|
});
|
|
};
|
|
client.getDeviceList = function() {
|
|
spy.getDeviceList.count += 1;
|
|
spy.getDeviceList.args.push(arguments);
|
|
return Promise.resolve([]);
|
|
};
|
|
|
|
const result = yield fxa.updateDeviceRegistration();
|
|
|
|
do_check_null(result);
|
|
do_check_eq(spy.getDeviceList.count, 0);
|
|
do_check_eq(spy.registerDevice.count, 0);
|
|
do_check_eq(spy.updateDevice.count, 1);
|
|
do_check_eq(spy.updateDevice.args[0].length, 4);
|
|
do_check_eq(spy.updateDevice.args[0][0], credentials.sessionToken);
|
|
do_check_eq(spy.updateDevice.args[0][1], credentials.deviceId);
|
|
do_check_eq(spy.updateDevice.args[0][2], deviceName);
|
|
do_check_eq(spy.updateDevice.args[0][3].pushCallback, "http://mochi.test:8888");
|
|
do_check_eq(spy.updateDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY);
|
|
do_check_eq(spy.updateDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY);
|
|
|
|
|
|
const state = fxa.internal.currentAccountState;
|
|
const data = yield state.getUserAccountData();
|
|
|
|
do_check_null(data.deviceId);
|
|
do_check_eq(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION);
|
|
});
|
|
|
|
add_task(function* test_deleteDeviceRegistration() {
|
|
const credentials = getTestUser("pb");
|
|
const fxa = new MockFxAccounts({ name: "my device" });
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const state = fxa.internal.currentAccountState;
|
|
let data = yield state.getUserAccountData();
|
|
do_check_eq(data.deviceId, credentials.deviceId);
|
|
do_check_eq(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION);
|
|
|
|
const spy = {
|
|
signOutAndDestroyDevice: { count: 0, args: [] }
|
|
};
|
|
const client = fxa.internal.fxAccountsClient;
|
|
client.signOutAndDestroyDevice = function() {
|
|
spy.signOutAndDestroyDevice.count += 1;
|
|
spy.signOutAndDestroyDevice.args.push(arguments);
|
|
return Promise.resolve({});
|
|
};
|
|
yield fxa.deleteDeviceRegistration(credentials.sessionToken, credentials.deviceId);
|
|
|
|
do_check_eq(spy.signOutAndDestroyDevice.count, 1);
|
|
do_check_eq(spy.signOutAndDestroyDevice.args[0].length, 2);
|
|
do_check_eq(spy.signOutAndDestroyDevice.args[0][0], credentials.sessionToken);
|
|
do_check_eq(spy.signOutAndDestroyDevice.args[0][1], credentials.deviceId);
|
|
|
|
data = yield state.getUserAccountData();
|
|
|
|
do_check_false(data.deviceId);
|
|
do_check_false(data.deviceRegistrationVersion);
|
|
});
|
|
|
|
add_task(function* test_updateDeviceRegistration_with_device_session_conflict_error() {
|
|
const deviceName = "foo";
|
|
const deviceType = "bar";
|
|
|
|
const credentials = getTestUser("baz");
|
|
const fxa = new MockFxAccounts({ name: deviceName });
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = {
|
|
registerDevice: { count: 0, args: [] },
|
|
updateDevice: { count: 0, args: [], times: [] },
|
|
getDeviceList: { count: 0, args: [] }
|
|
};
|
|
const client = fxa.internal.fxAccountsClient;
|
|
client.registerDevice = function() {
|
|
spy.registerDevice.count += 1;
|
|
spy.registerDevice.args.push(arguments);
|
|
return Promise.resolve({});
|
|
};
|
|
client.updateDevice = function() {
|
|
spy.updateDevice.count += 1;
|
|
spy.updateDevice.args.push(arguments);
|
|
spy.updateDevice.time = Date.now();
|
|
if (spy.updateDevice.count === 1) {
|
|
return Promise.reject({
|
|
code: 400,
|
|
errno: ERRNO_DEVICE_SESSION_CONFLICT
|
|
});
|
|
}
|
|
return Promise.resolve({
|
|
id: credentials.deviceId,
|
|
name: deviceName
|
|
});
|
|
};
|
|
client.getDeviceList = function() {
|
|
spy.getDeviceList.count += 1;
|
|
spy.getDeviceList.args.push(arguments);
|
|
spy.getDeviceList.time = Date.now();
|
|
return Promise.resolve([
|
|
{ id: "ignore", name: "ignore", type: "ignore", isCurrentDevice: false },
|
|
{ id: credentials.deviceId, name: deviceName, type: deviceType, isCurrentDevice: true }
|
|
]);
|
|
};
|
|
|
|
const result = yield fxa.updateDeviceRegistration();
|
|
|
|
do_check_eq(result, credentials.deviceId);
|
|
do_check_eq(spy.registerDevice.count, 0);
|
|
do_check_eq(spy.updateDevice.count, 1);
|
|
do_check_eq(spy.updateDevice.args[0].length, 4);
|
|
do_check_eq(spy.updateDevice.args[0][0], credentials.sessionToken);
|
|
do_check_eq(spy.updateDevice.args[0][1], credentials.deviceId);
|
|
do_check_eq(spy.updateDevice.args[0][2], deviceName);
|
|
do_check_eq(spy.updateDevice.args[0][3].pushCallback, "http://mochi.test:8888");
|
|
do_check_eq(spy.updateDevice.args[0][3].pushPublicKey, BOGUS_PUBLICKEY);
|
|
do_check_eq(spy.updateDevice.args[0][3].pushAuthKey, BOGUS_AUTHKEY);
|
|
do_check_eq(spy.getDeviceList.count, 1);
|
|
do_check_eq(spy.getDeviceList.args[0].length, 1);
|
|
do_check_eq(spy.getDeviceList.args[0][0], credentials.sessionToken);
|
|
do_check_true(spy.getDeviceList.time >= spy.updateDevice.time);
|
|
|
|
const state = fxa.internal.currentAccountState;
|
|
const data = yield state.getUserAccountData();
|
|
|
|
do_check_eq(data.deviceId, credentials.deviceId);
|
|
do_check_eq(data.deviceRegistrationVersion, null);
|
|
});
|
|
|
|
add_task(function* test_updateDeviceRegistration_with_unrecoverable_error() {
|
|
const deviceName = "foo";
|
|
|
|
const credentials = getTestUser("baz");
|
|
delete credentials.deviceId;
|
|
const fxa = new MockFxAccounts({ name: deviceName });
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = {
|
|
registerDevice: { count: 0, args: [] },
|
|
updateDevice: { count: 0, args: [] },
|
|
getDeviceList: { count: 0, args: [] }
|
|
};
|
|
const client = fxa.internal.fxAccountsClient;
|
|
client.registerDevice = function() {
|
|
spy.registerDevice.count += 1;
|
|
spy.registerDevice.args.push(arguments);
|
|
return Promise.reject({
|
|
code: 400,
|
|
errno: ERRNO_TOO_MANY_CLIENT_REQUESTS
|
|
});
|
|
};
|
|
client.updateDevice = function() {
|
|
spy.updateDevice.count += 1;
|
|
spy.updateDevice.args.push(arguments);
|
|
return Promise.resolve({});
|
|
};
|
|
client.getDeviceList = function() {
|
|
spy.getDeviceList.count += 1;
|
|
spy.getDeviceList.args.push(arguments);
|
|
return Promise.resolve([]);
|
|
};
|
|
|
|
const result = yield fxa.updateDeviceRegistration();
|
|
|
|
do_check_null(result);
|
|
do_check_eq(spy.getDeviceList.count, 0);
|
|
do_check_eq(spy.updateDevice.count, 0);
|
|
do_check_eq(spy.registerDevice.count, 1);
|
|
do_check_eq(spy.registerDevice.args[0].length, 4);
|
|
|
|
const state = fxa.internal.currentAccountState;
|
|
const data = yield state.getUserAccountData();
|
|
|
|
do_check_null(data.deviceId);
|
|
});
|
|
|
|
add_task(function* test_getDeviceId_with_no_device_id_invokes_device_registration() {
|
|
const credentials = getTestUser("foo");
|
|
credentials.verified = true;
|
|
delete credentials.deviceId;
|
|
const fxa = new MockFxAccounts();
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = { count: 0, args: [] };
|
|
fxa.internal.currentAccountState.getUserAccountData =
|
|
() => Promise.resolve({ email: credentials.email,
|
|
deviceRegistrationVersion: DEVICE_REGISTRATION_VERSION });
|
|
fxa.internal._registerOrUpdateDevice = function() {
|
|
spy.count += 1;
|
|
spy.args.push(arguments);
|
|
return Promise.resolve("bar");
|
|
};
|
|
|
|
const result = yield fxa.internal.getDeviceId();
|
|
|
|
do_check_eq(spy.count, 1);
|
|
do_check_eq(spy.args[0].length, 1);
|
|
do_check_eq(spy.args[0][0].email, credentials.email);
|
|
do_check_null(spy.args[0][0].deviceId);
|
|
do_check_eq(result, "bar");
|
|
});
|
|
|
|
add_task(function* test_getDeviceId_with_registration_version_outdated_invokes_device_registration() {
|
|
const credentials = getTestUser("foo");
|
|
credentials.verified = true;
|
|
const fxa = new MockFxAccounts();
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = { count: 0, args: [] };
|
|
fxa.internal.currentAccountState.getUserAccountData =
|
|
() => Promise.resolve({ deviceId: credentials.deviceId, deviceRegistrationVersion: 0 });
|
|
fxa.internal._registerOrUpdateDevice = function() {
|
|
spy.count += 1;
|
|
spy.args.push(arguments);
|
|
return Promise.resolve("wibble");
|
|
};
|
|
|
|
const result = yield fxa.internal.getDeviceId();
|
|
|
|
do_check_eq(spy.count, 1);
|
|
do_check_eq(spy.args[0].length, 1);
|
|
do_check_eq(spy.args[0][0].deviceId, credentials.deviceId);
|
|
do_check_eq(result, "wibble");
|
|
});
|
|
|
|
add_task(function* test_getDeviceId_with_device_id_and_uptodate_registration_version_doesnt_invoke_device_registration() {
|
|
const credentials = getTestUser("foo");
|
|
credentials.verified = true;
|
|
const fxa = new MockFxAccounts();
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = { count: 0 };
|
|
fxa.internal.currentAccountState.getUserAccountData =
|
|
() => Promise.resolve({ deviceId: credentials.deviceId, deviceRegistrationVersion: DEVICE_REGISTRATION_VERSION });
|
|
fxa.internal._registerOrUpdateDevice = function() {
|
|
spy.count += 1;
|
|
return Promise.resolve("bar");
|
|
};
|
|
|
|
const result = yield fxa.internal.getDeviceId();
|
|
|
|
do_check_eq(spy.count, 0);
|
|
do_check_eq(result, "foo's device id");
|
|
});
|
|
|
|
add_task(function* test_getDeviceId_with_device_id_and_with_no_registration_version_invokes_device_registration() {
|
|
const credentials = getTestUser("foo");
|
|
credentials.verified = true;
|
|
const fxa = new MockFxAccounts();
|
|
yield fxa.internal.setSignedInUser(credentials);
|
|
|
|
const spy = { count: 0, args: [] };
|
|
fxa.internal.currentAccountState.getUserAccountData =
|
|
() => Promise.resolve({ deviceId: credentials.deviceId });
|
|
fxa.internal._registerOrUpdateDevice = function() {
|
|
spy.count += 1;
|
|
spy.args.push(arguments);
|
|
return Promise.resolve("wibble");
|
|
};
|
|
|
|
const result = yield fxa.internal.getDeviceId();
|
|
|
|
do_check_eq(spy.count, 1);
|
|
do_check_eq(spy.args[0].length, 1);
|
|
do_check_eq(spy.args[0][0].deviceId, credentials.deviceId);
|
|
do_check_eq(result, "wibble");
|
|
});
|
|
|
|
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
|
|
};
|
|
}
|
|
|