tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit b55b57caba523eacf6dfd35b6e69a6de48c05348
parent f5038bfe19515c12c73c8124dec668fc2e115b36
Author: Sammy Khamis <skhamis@mozilla.com>
Date:   Wed, 31 Dec 2025 21:36:15 +0000

Bug 2008264 - Dont destroy session if user is already logged in r=bdk

Differential Revision: https://phabricator.services.mozilla.com/D277716

Diffstat:
Mservices/fxaccounts/FxAccountsWebChannel.sys.mjs | 13+++++++++++--
Mservices/fxaccounts/tests/xpcshell/test_web_channel.js | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/services/fxaccounts/FxAccountsWebChannel.sys.mjs b/services/fxaccounts/FxAccountsWebChannel.sys.mjs @@ -667,8 +667,17 @@ FxAccountsWebChannelHelpers.prototype = { accountData.requestedServices = JSON.stringify(requestedServices); this.setPreviousAccountHashPref(accountData.uid); - await this._fxAccounts._internal.setSignedInUser(accountData); - log.debug("Webchannel finished logging a user in."); + + // For scenarios like user is logged in via third-party but wants + // to enable sync (password) the server will send an additional login command + // we need to ensure we don't destroy the existing session + if (signedInUser && signedInUser.uid === accountData.uid) { + await this._fxAccounts._internal.updateUserAccountData(accountData); + log.debug("Webchannel finished updating already logged in user."); + } else { + await this._fxAccounts._internal.setSignedInUser(accountData); + log.debug("Webchannel finished logging a user in."); + } }, /** diff --git a/services/fxaccounts/tests/xpcshell/test_web_channel.js b/services/fxaccounts/tests/xpcshell/test_web_channel.js @@ -657,6 +657,65 @@ add_task(async function test_helpers_login_another_user_signed_in() { Assert.ok(helpers._disconnect.called); }); +// The FxA server sends the `login` command after the user is signed in +// when upgrading from third-party auth to password + sync +add_task(async function test_helpers_login_same_user_signed_in() { + let updateUserAccountDataCalled = false; + let setSignedInUserCalled = false; + + let helpers = new FxAccountsWebChannelHelpers({ + fxAccounts: { + getSignedInUser() { + return Promise.resolve({ + uid: "testuser", + email: "testuser@testuser.com", + }); + }, + _internal: { + updateUserAccountData(accountData) { + updateUserAccountDataCalled = true; + Assert.equal(accountData.email, "testuser@testuser.com"); + Assert.equal(accountData.uid, "testuser"); + return Promise.resolve(); + }, + setSignedInUser() { + setSignedInUserCalled = true; + return Promise.resolve(); + }, + }, + telemetry: { + recordConnection: sinon.spy(), + }, + }, + weaveXPCOM: { + whenLoaded() {}, + Weave: { + Service: { + configure() {}, + }, + }, + }, + }); + helpers._disconnect = sinon.spy(); + + await helpers.login({ + uid: "testuser", + email: "testuser@testuser.com", + verifiedCanLinkAccount: true, + customizeSync: false, + }); + + Assert.ok( + updateUserAccountDataCalled, + "updateUserAccountData should be called" + ); + Assert.ok(!setSignedInUserCalled, "setSignedInUser should not be called"); + Assert.ok(!helpers._disconnect.called, "_disconnect should not be called"); + Assert.ok( + helpers._fxAccounts.telemetry.recordConnection.calledWith([], "webchannel") + ); +}); + add_task(async function test_helpers_login_with_customize_sync() { let helpers = new FxAccountsWebChannelHelpers({ fxAccounts: { @@ -710,6 +769,10 @@ add_task(async function test_helpers_persist_requested_services() { accountData = newAccountData; return accountData; }, + async updateUserAccountData(updatedFields) { + accountData = { ...accountData, ...updatedFields }; + return accountData; + }, }, async getSignedInUser() { return accountData;