Bug 1448165 p1 - Simplify and factorize FxAccounts signout mechanism. r?markh
Since FxA's /session/destroy now also removes the current device registration,
there's no need to differenciate signouts w/ and w/o device registration.
MozReview-Commit-ID: 3lHV3JC1NU6
--- a/services/fxaccounts/FxAccounts.jsm
+++ b/services/fxaccounts/FxAccounts.jsm
@@ -65,17 +65,16 @@ var publicProperties = [
"removeCachedOAuthToken",
"resendVerificationEmail",
"resetCredentials",
"sessionStatus",
"setProfileCache",
"setSignedInUser",
"signOut",
"updateDeviceRegistration",
- "deleteDeviceRegistration",
"updateUserAccountData",
"whenVerified",
];
// An AccountState object holds all state related to one specific account.
// Only one AccountState is ever "current" in the FxAccountsInternal object -
// whenever a user logs out or logs in, the current AccountState is discarded,
// making it impossible for the wrong state or state data to be accidentally
@@ -114,46 +113,40 @@ AccountState.prototype = {
},
abort() {
if (this.whenVerifiedDeferred) {
this.whenVerifiedDeferred.reject(
new Error("Verification aborted; Another user signing in"));
this.whenVerifiedDeferred = null;
}
-
if (this.whenKeysReadyDeferred) {
this.whenKeysReadyDeferred.reject(
new Error("Verification aborted; Another user signing in"));
this.whenKeysReadyDeferred = null;
}
+ return this.signOut();
+ },
+ // Clobber all cached data and write that empty data to storage.
+ async signOut() {
this.cert = null;
this.keyPair = null;
this.oauthTokens = null;
+
// Avoid finalizing the storageManager multiple times (ie, .signOut()
// followed by .abort())
if (!this.storageManager) {
- return Promise.resolve();
+ return;
}
- let storageManager = this.storageManager;
+ const storageManager = this.storageManager;
this.storageManager = null;
- return storageManager.finalize();
- },
- // Clobber all cached data and write that empty data to storage.
- signOut() {
- this.cert = null;
- this.keyPair = null;
- this.oauthTokens = null;
- let storageManager = this.storageManager;
- this.storageManager = null;
- return storageManager.deleteAccountData().then(() => {
- return storageManager.finalize();
- });
+ await storageManager.deleteAccountData();
+ await storageManager.finalize();
},
// Get user account data. Optionally specify explicit field names to fetch
// (and note that if you require an in-memory field you *must* specify the
// field name(s).)
getUserAccountData(fieldNames = null) {
if (!this.isCurrent) {
return Promise.reject(new Error("Another user has signed in"));
@@ -567,17 +560,17 @@ FxAccountsInternal.prototype = {
*/
async setSignedInUser(credentials) {
if (!FXA_ENABLED) {
throw new Error("Cannot call setSignedInUser when FxA is disabled.");
}
log.debug("setSignedInUser - aborting any existing flows");
const signedInUser = await this.getSignedInUser();
if (signedInUser) {
- await this.deleteDeviceRegistration(signedInUser.sessionToken, signedInUser.deviceId);
+ await this._signOutServer(signedInUser.sessionToken, signedInUser.oauthTokens);
}
await this.abortExistingFlow();
let currentAccountState = this.currentAccountState = this.newAccountState(
Cu.cloneInto(credentials, {}) // Pass a clone of the credentials object.
);
// This promise waits for storage, but not for verification.
// We're telling the caller that this is durable now (although is that
// really something we should commit to? Why not let the write happen in
@@ -714,17 +707,17 @@ FxAccountsInternal.prototype = {
}
throw new Error("Cannot resend verification email; no signed-in user");
});
},
/*
* Reset state such that any previous flow is canceled.
*/
- abortExistingFlow: function abortExistingFlow() {
+ abortExistingFlow() {
if (this.currentTimer) {
log.debug("Polling aborted; Another user signing in");
clearTimeout(this.currentTimer);
this.currentTimer = 0;
}
if (this._profile) {
this._profile.tearDown();
this._profile = null;
@@ -764,104 +757,84 @@ FxAccountsInternal.prototype = {
let client = new FxAccountsOAuthGrantClient({
serverURL: tokenData.server,
client_id: FX_OAUTH_CLIENT_ID
});
return client.destroyToken(tokenData.token);
},
_destroyAllOAuthTokens(tokenInfos) {
+ if (!tokenInfos) {
+ return Promise.resolve();
+ }
// let's just destroy them all in parallel...
let promises = [];
- for (let tokenInfo of Object.values(tokenInfos || {})) {
+ for (let tokenInfo of Object.values(tokenInfos)) {
promises.push(this._destroyOAuthToken(tokenInfo));
}
return Promise.all(promises);
},
- signOut: function signOut(localOnly) {
- let currentState = this.currentAccountState;
+ async signOut(localOnly) {
let sessionToken;
let tokensToRevoke;
- let deviceId;
- return currentState.getUserAccountData().then(data => {
- // Save the session token, tokens to revoke and the
- // device id for use in the call to signOut below.
- if (data) {
- sessionToken = data.sessionToken;
- tokensToRevoke = data.oauthTokens;
- deviceId = data.deviceId;
- }
- return this._signOutLocal();
- }).then(() => {
- // FxAccountsManager calls here, then does its own call
- // to FxAccountsClient.signOut().
- if (!localOnly) {
- // Wrap this in a promise so *any* errors in signOut won't
- // block the local sign out. This is *not* returned.
- Promise.resolve().then(() => {
- // This can happen in the background and shouldn't block
- // the user from signing out. The server must tolerate
- // clients just disappearing, so this call should be best effort.
- if (sessionToken) {
- return this._signOutServer(sessionToken, deviceId);
- }
- log.warn("Missing session token; skipping remote sign out");
- return null;
- }).catch(err => {
- log.error("Error during remote sign out of Firefox Accounts", err);
- }).then(() => {
- return this._destroyAllOAuthTokens(tokensToRevoke);
- }).catch(err => {
- log.error("Error during destruction of oauth tokens during signout", err);
- }).then(() => {
- FxAccountsConfig.resetConfigURLs();
- // just for testing - notifications are cheap when no observers.
- return this.notifyObservers("testhelper-fxa-signout-complete");
- });
- } else {
- // We want to do this either way -- but if we're signing out remotely we
- // need to wait until we destroy the oauth tokens if we want that to succeed.
+ const data = await this.currentAccountState.getUserAccountData();
+ // Save the sessionToken, tokens before resetting them in _signOutLocal().
+ if (data) {
+ sessionToken = data.sessionToken;
+ tokensToRevoke = data.oauthTokens;
+ }
+ await this._signOutLocal();
+ if (!localOnly) {
+ // Do this in the background so *any* slow request won't
+ // block the local sign out.
+ Services.tm.dispatchToMainThread(async () => {
+ await this._signOutServer(sessionToken, tokensToRevoke);
FxAccountsConfig.resetConfigURLs();
- }
- }).then(() => {
- return this.notifyObservers(ONLOGOUT_NOTIFICATION);
- });
+ this.notifyObservers("testhelper-fxa-signout-complete");
+ });
+ } else {
+ // We want to do this either way -- but if we're signing out remotely we
+ // need to wait until we destroy the oauth tokens if we want that to succeed.
+ FxAccountsConfig.resetConfigURLs();
+ }
+ return this.notifyObservers(ONLOGOUT_NOTIFICATION);
},
- /**
- * This function should be called in conjunction with a server-side
- * signOut via FxAccountsClient.
- */
- _signOutLocal: function signOutLocal() {
- let currentAccountState = this.currentAccountState;
- return currentAccountState.signOut().then(() => {
- // this "aborts" this.currentAccountState but doesn't make a new one.
- return this.abortExistingFlow();
- }).then(() => {
- this.currentAccountState = this.newAccountState();
- return this.currentAccountState.promiseInitialized;
- });
+ async _signOutLocal() {
+ await this.currentAccountState.signOut();
+ // this "aborts" this.currentAccountState but doesn't make a new one.
+ await this.abortExistingFlow();
+ this.currentAccountState = this.newAccountState();
+ return this.currentAccountState.promiseInitialized;
},
- _signOutServer(sessionToken, deviceId) {
- // For now we assume the service being logged out from is Sync, so
- // we must tell the server to either destroy the device or sign out
- // (if no device exists). We might need to revisit this when this
- // FxA code is used in a context that isn't Sync.
-
- const options = { service: "sync" };
-
- if (deviceId) {
- log.debug("destroying device, session and unsubscribing from FxA push");
- return this.deleteDeviceRegistration(sessionToken, deviceId);
+ async _signOutServer(sessionToken, tokensToRevoke) {
+ log.debug("Unsubscribing from FxA push.");
+ try {
+ await this.fxaPushService.unsubscribe();
+ } catch (err) {
+ log.error("Could not unsubscribe from push.", err);
}
-
- log.debug("destroying session");
- return this.fxAccountsClient.signOut(sessionToken, options);
+ if (sessionToken) {
+ log.debug("Destroying session and device.");
+ try {
+ await this.fxAccountsClient.signOut(sessionToken, {service: "sync"});
+ } catch (err) {
+ log.error("Error during remote sign out of Firefox Accounts", err);
+ }
+ } else {
+ log.warn("Missing session token; skipping remote sign out");
+ }
+ log.debug("Destroying all OAuth tokens.");
+ try {
+ await this._destroyAllOAuthTokens(tokensToRevoke);
+ } catch (err) {
+ log.error("Error during destruction of oauth tokens during signout", err);
+ }
},
/**
* Check the status of the current session using cached credentials.
*
* @return Promise
* Resolves with a boolean indicating if the session is still valid
*/
@@ -1581,41 +1554,16 @@ FxAccountsInternal.prototype = {
return this.getSignedInUser().then(signedInUser => {
if (signedInUser) {
return this._registerOrUpdateDevice(signedInUser);
}
return null;
}).catch(error => this._logErrorAndResetDeviceRegistrationVersion(error));
},
- // Delete the Push Subscription and the device registration on the auth server.
- // Returns a promise that always resolves, never rejects.
- async deleteDeviceRegistration(sessionToken, deviceId) {
- try {
- // Allow tests to skip device registration because it makes remote requests to the auth server.
- if (Services.prefs.getBoolPref("identity.fxaccounts.skipDeviceRegistration")) {
- return Promise.resolve();
- }
- } catch (ignore) {}
-
- try {
- await this.fxaPushService.unsubscribe();
- if (sessionToken && deviceId) {
- await this.fxAccountsClient.signOutAndDestroyDevice(sessionToken, deviceId);
- }
- await this.currentAccountState.updateUserAccountData({
- deviceId: null,
- deviceRegistrationVersion: null
- });
- } catch (err) {
- log.error("Could not delete the device registration", err);
- }
- return Promise.resolve();
- },
-
async handleDeviceDisconnection(deviceId) {
const accountData = await this.currentAccountState.getUserAccountData();
const localDeviceId = accountData ? accountData.deviceId : null;
const isLocalDevice = (deviceId == localDeviceId);
if (isLocalDevice) {
this.signOut(true);
}
const data = JSON.stringify({ isLocalDevice });
--- a/services/fxaccounts/FxAccountsClient.jsm
+++ b/services/fxaccounts/FxAccountsClient.jsm
@@ -197,17 +197,18 @@ this.FxAccountsClient.prototype = {
return Promise.resolve(false);
}
throw error;
}
);
},
/**
- * Destroy the current session with the Firefox Account API server
+ * Destroy the current session with the Firefox Account API server and its
+ * associated device.
*
* @param sessionTokenHex
* The session token encoded in hex
* @return Promise
*/
signOut(sessionTokenHex, options = {}) {
let path = "/session/destroy";
if (options.service) {
@@ -482,46 +483,16 @@ this.FxAccountsClient.prototype = {
body.pushPublicKey = options.pushPublicKey;
body.pushAuthKey = options.pushAuthKey;
}
return this._request(path, "POST", creds, body);
},
/**
- * Delete a device and its associated session token, signing the user
- * out of the server.
- *
- * @method signOutAndDestroyDevice
- * @param sessionTokenHex
- * Session token obtained from signIn
- * @param id
- * Device identifier
- * @param [options]
- * Options object
- * @param [options.service]
- * `service` query parameter
- * @return Promise
- * Resolves to an empty object:
- * {}
- */
- signOutAndDestroyDevice(sessionTokenHex, id, options = {}) {
- let path = "/account/device/destroy";
-
- if (options.service) {
- path += "?service=" + encodeURIComponent(options.service);
- }
-
- let creds = deriveHawkCredentials(sessionTokenHex, "sessionToken");
- let body = { id };
-
- return this._request(path, "POST", creds, body);
- },
-
- /**
* Get a list of currently registered devices
*
* @method getDeviceList
* @param sessionTokenHex
* Session token obtained from signIn
* @return Promise
* Resolves to an array of objects:
* [
--- a/services/fxaccounts/tests/xpcshell/test_accounts.js
+++ b/services/fxaccounts/tests/xpcshell/test_accounts.js
@@ -108,17 +108,16 @@ function MockFxAccountsClient() {
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 new Error("no"); };
this.signOut = () => Promise.resolve();
- this.signOutAndDestroyDevice = () => Promise.resolve({});
FxAccountsClient.apply(this);
}
MockFxAccountsClient.prototype = {
__proto__: FxAccountsClient.prototype
};
/*
@@ -222,40 +221,40 @@ add_task(async function test_get_signed_
let localOnly = true;
await account.signOut(localOnly);
// user should be undefined after sign out
result = await account.getSignedInUser();
Assert.equal(result, null);
});
-add_task(async function test_set_signed_in_user_deletes_previous_device() {
- _("Check setSignedInUser tries to delete a previous registered device");
+add_task(async function test_set_signed_in_user_signs_out_previous_account() {
+ _("Check setSignedInUser signs out the previous account.");
let account = MakeFxAccounts();
- let deleteDeviceRegistrationCalled = false;
+ let signOutServerCalled = false;
let credentials = {
email: "foo@example.com",
uid: "1234@lcip.org",
assertion: "foobar",
sessionToken: "dead",
kSync: "beef",
kXCS: "cafe",
kExtSync: "bacon",
kExtKbHash: "cheese",
verified: true
};
await account.setSignedInUser(credentials);
- account.internal.deleteDeviceRegistration = () => {
- deleteDeviceRegistrationCalled = true;
+ account.internal._signOutServer = () => {
+ signOutServerCalled = true;
return Promise.resolve(true);
};
await account.setSignedInUser(credentials);
- Assert.ok(deleteDeviceRegistrationCalled);
+ Assert.ok(signOutServerCalled);
});
add_task(async function test_update_account_data() {
_("Check updateUserAccountData does the right thing.");
let account = MakeFxAccounts();
let credentials = {
email: "foo@example.com",
uid: "1234@lcip.org",
@@ -1074,133 +1073,16 @@ add_test(function test_resend_email() {
// Ok abort polling before we go on to the next test
fxa.internal.abortExistingFlow();
run_next_test();
});
});
});
});
-add_task(async function test_sign_out_with_device() {
- const fxa = new MockFxAccounts();
-
- const credentials = getTestUser("alice");
- await fxa.internal.setSignedInUser(credentials);
-
- const user = await fxa.internal.getUserAccountData();
- Assert.ok(user);
- Object.keys(credentials).forEach(key => Assert.equal(credentials[key], user[key]));
-
- const spy = {
- signOut: { count: 0 },
- deleteDeviceRegistration: { count: 0, args: [] }
- };
- const client = fxa.internal.fxAccountsClient;
- client.signOut = function() {
- spy.signOut.count += 1;
- return Promise.resolve();
- };
- fxa.internal.deleteDeviceRegistration = function() {
- spy.deleteDeviceRegistration.count += 1;
- spy.deleteDeviceRegistration.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 => {
- Assert.equal(user2, null);
- Assert.equal(spy.signOut.count, 0);
- Assert.equal(spy.deleteDeviceRegistration.count, 1);
- Assert.equal(spy.deleteDeviceRegistration.args[0].length, 2);
- Assert.equal(spy.deleteDeviceRegistration.args[0][0], credentials.sessionToken);
- Assert.equal(spy.deleteDeviceRegistration.args[0][1], credentials.deviceId);
- resolve();
- });
- });
- });
-
- await fxa.signOut();
-
- await promise;
-});
-
-add_task(async function test_sign_out_without_device() {
- const fxa = new MockFxAccounts();
-
- const credentials = getTestUser("alice");
- delete credentials.deviceId;
- await fxa.internal.setSignedInUser(credentials);
-
- await fxa.internal.getUserAccountData();
-
- const spy = {
- signOut: { count: 0, args: [] },
- deleteDeviceRegistration: { count: 0 }
- };
- const client = fxa.internal.fxAccountsClient;
- client.signOut = function() {
- spy.signOut.count += 1;
- spy.signOut.args.push(arguments);
- return Promise.resolve();
- };
- fxa.internal.deleteDeviceRegistration = function() {
- spy.deleteDeviceRegistration.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 => {
- Assert.equal(user2, null);
- Assert.equal(spy.signOut.count, 1);
- Assert.equal(spy.signOut.args[0].length, 2);
- Assert.equal(spy.signOut.args[0][0], credentials.sessionToken);
- Assert.ok(spy.signOut.args[0][1]);
- Assert.equal(spy.signOut.args[0][1].service, "sync");
- Assert.equal(spy.deleteDeviceRegistration.count, 0);
- resolve();
- });
- });
- });
-
- await fxa.signOut();
-
- await promise;
-});
-
-add_task(async function test_sign_out_with_remote_error() {
- let fxa = new MockFxAccounts();
- let remoteSignOutCalled = false;
- // Force remote sign out to trigger an error
- fxa.internal.deleteDeviceRegistration = function() {
- remoteSignOutCalled = true;
- throw new Error("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");
- await fxa.setSignedInUser(jane);
- await fxa.signOut();
- await promiseLogout;
-
- let user = await fxa.internal.getUserAccountData();
- Assert.equal(user, null);
- Assert.ok(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");
--- a/services/fxaccounts/tests/xpcshell/test_accounts_device_registration.js
+++ b/services/fxaccounts/tests/xpcshell/test_accounts_device_registration.js
@@ -73,17 +73,17 @@ function MockFxAccountsClient(device) {
this.accountStatus = function(uid) {
return Promise.resolve(!!uid && (!this._deletedOnServer));
};
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.signOut = () => Promise.resolve({});
this.getDeviceList = (st) =>
Promise.resolve([
{ id: deviceId, name: deviceName, type: deviceType, isCurrentDevice: st === sessionToken }
]);
FxAccountsClient.apply(this);
}
MockFxAccountsClient.prototype = {
@@ -281,48 +281,16 @@ add_task(async function test_updateDevic
const state = fxa.internal.currentAccountState;
const data = await state.getUserAccountData();
Assert.equal(null, data.deviceId);
Assert.equal(data.deviceRegistrationVersion, DEVICE_REGISTRATION_VERSION);
});
-add_task(async function test_deleteDeviceRegistration() {
- const credentials = getTestUser("pb");
- const fxa = new MockFxAccounts({ name: "my device" });
- await fxa.internal.setSignedInUser(credentials);
-
- const state = fxa.internal.currentAccountState;
- let data = await state.getUserAccountData();
- Assert.equal(data.deviceId, credentials.deviceId);
- Assert.equal(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({});
- };
- await fxa.deleteDeviceRegistration(credentials.sessionToken, credentials.deviceId);
-
- Assert.equal(spy.signOutAndDestroyDevice.count, 1);
- Assert.equal(spy.signOutAndDestroyDevice.args[0].length, 2);
- Assert.equal(spy.signOutAndDestroyDevice.args[0][0], credentials.sessionToken);
- Assert.equal(spy.signOutAndDestroyDevice.args[0][1], credentials.deviceId);
-
- data = await state.getUserAccountData();
-
- Assert.ok(!data.deviceId);
- Assert.ok(!data.deviceRegistrationVersion);
-});
-
add_task(async function test_updateDeviceRegistration_with_device_session_conflict_error() {
const deviceName = "foo";
const deviceType = "bar";
const credentials = getTestUser("baz");
const fxa = new MockFxAccounts({ name: deviceName });
await fxa.internal.setSignedInUser(credentials);
--- a/services/fxaccounts/tests/xpcshell/test_client.js
+++ b/services/fxaccounts/tests/xpcshell/test_client.js
@@ -727,58 +727,16 @@ add_task(async function test_updateDevic
do_throw("Expected to catch an exception");
} catch (unexpectedError) {
Assert.equal(unexpectedError.code, 500);
}
await promiseStopServer(server);
});
-add_task(async function test_signOutAndDestroyDevice() {
- const DEVICE_ID = "device id";
- const ERROR_ID = "test that the client promise rejects";
- let emptyMessage = "{}";
-
- const server = httpd_setup({
- "/account/device/destroy": function(request, response) {
- const body = JSON.parse(CommonUtils.readBytesFromInputStream(request.bodyInputStream));
-
- if (!body.id) {
- response.setStatusLine(request.httpVersion, 400, "Invalid request");
- response.bodyOutputStream.write(emptyMessage, emptyMessage.length);
- return;
- }
-
- if (body.id === ERROR_ID) {
- response.setStatusLine(request.httpVersion, 500, "Alas");
- response.bodyOutputStream.write("{}", 2);
- return;
- }
-
- response.setStatusLine(request.httpVersion, 200, "OK");
- response.bodyOutputStream.write("{}", 2);
- },
- });
-
- const client = new FxAccountsClient(server.baseURI);
- const result = await client.signOutAndDestroyDevice(FAKE_SESSION_TOKEN, DEVICE_ID);
-
- Assert.ok(result);
- Assert.equal(Object.keys(result).length, 0);
-
- try {
- await client.signOutAndDestroyDevice(FAKE_SESSION_TOKEN, ERROR_ID);
- do_throw("Expected to catch an exception");
- } catch (unexpectedError) {
- Assert.equal(unexpectedError.code, 500);
- }
-
- await promiseStopServer(server);
-});
-
add_task(async function test_getDeviceList() {
let canReturnDevices;
const server = httpd_setup({
"/account/devices": function(request, response) {
if (canReturnDevices) {
response.setStatusLine(request.httpVersion, 200, "OK");
response.bodyOutputStream.write("[]", 2);
--- a/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js
+++ b/services/fxaccounts/tests/xpcshell/test_loginmgr_storage.js
@@ -41,17 +41,17 @@ function createFxAccounts() {
return new FxAccounts({
_fxAccountsClient: {
async registerDevice() {
return { id: "deviceAAAAAA" };
},
async recoveryEmailStatus() {
return { verified: true };
},
- async signOutAndDestroyDevice() {},
+ async signOut() {},
},
_getDeviceName() {
return "mock device name";
},
observerPreloads: [],
fxaPushService: {
async registerPushEndpoint() {
return {
--- a/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm
+++ b/services/sync/tps/extensions/tps/resource/auth/fxaccounts.jsm
@@ -194,21 +194,14 @@ var Authentication = {
* Sign out of Firefox Accounts. It also clears out the device ID, if we find one.
*/
async signOut() {
if (await Authentication.isLoggedIn()) {
let user = await Authentication.getSignedInUser();
if (!user) {
throw new Error("Failed to get signed in user!");
}
+ let { sessionToken } = user;
let fxc = new FxAccountsClient();
- let { sessionToken, deviceId } = user;
- if (deviceId) {
- Logger.logInfo("Destroying device " + deviceId);
- await fxAccounts.deleteDeviceRegistration(sessionToken, deviceId);
- await fxAccounts.signOut(true);
- } else {
- Logger.logError("No device found.");
- await fxc.signOut(sessionToken, { service: "sync" });
- }
+ await fxc.signOut(sessionToken, { service: "sync" });
}
}
};