tor-browser

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

commit 316685cef67b05ddb400b8ec64b2eb0cf3a8c74e
parent 566e4283c6b13cec5a7837c93822ba4b64e3fae1
Author: Sebastian Streich <sstreich@mozilla.com>
Date:   Tue, 18 Nov 2025 21:17:02 +0000

Bug 1997912 - IPProtectionServerlist should update on RemoteSettings Sync r=ip-protection-reviewers,baku

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

Diffstat:
Mbrowser/components/ipprotection/IPProtectionServerlist.sys.mjs | 21++++++++++++++++-----
Mbrowser/components/ipprotection/tests/xpcshell/test_IPProtectionServerlist.js | 32++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/browser/components/ipprotection/IPProtectionServerlist.sys.mjs b/browser/components/ipprotection/IPProtectionServerlist.sys.mjs @@ -186,6 +186,7 @@ class Country { class IPProtectionServerlistSingleton { #list = null; #runningPromise = null; + #bucket = null; constructor() { this.handleEvent = this.#handleEvent.bind(this); @@ -201,7 +202,11 @@ class IPProtectionServerlistSingleton { ); } - async initOnStartupCompleted() {} + async initOnStartupCompleted() { + this.bucket.on("sync", async () => { + await this.maybeFetchList(true); + }); + } uninit() { lazy.IPProtectionService.removeEventListener( @@ -216,8 +221,8 @@ class IPProtectionServerlistSingleton { } } - maybeFetchList() { - if (this.#list.length !== 0) { + maybeFetchList(forceUpdate = false) { + if (this.#list.length !== 0 && !forceUpdate) { return Promise.resolve(); } @@ -226,9 +231,8 @@ class IPProtectionServerlistSingleton { } const fetchList = async () => { - const bucket = lazy.RemoteSettings("vpn-serverlist"); this.#list = IPProtectionServerlistSingleton.#dataToList( - await bucket.get() + await this.bucket.get() ); lazy.IPPStartupCache.storeLocationList(this.#list); @@ -287,6 +291,13 @@ class IPProtectionServerlistSingleton { return this.#list.length !== 0; } + get bucket() { + if (!this.#bucket) { + this.#bucket = lazy.RemoteSettings("vpn-serverlist"); + } + return this.#bucket; + } + static #dataToList(list) { if (!Array.isArray(list)) { return []; diff --git a/browser/components/ipprotection/tests/xpcshell/test_IPProtectionServerlist.js b/browser/components/ipprotection/tests/xpcshell/test_IPProtectionServerlist.js @@ -85,6 +85,7 @@ add_setup(async function () { await client.db.importChanges({}, Date.now()); await IPProtectionServerlist.maybeFetchList(); + await IPProtectionServerlist.initOnStartupCompleted(); }); add_task(async function test_getDefaultLocation() { @@ -145,3 +146,34 @@ add_task(async function test_selectServer() { selected = IPProtectionServerlist.selectServer(cityWithNoServers); Assert.equal(selected, null, "No server should be selected"); }); + +add_task(async function test_syncRespected() { + let { country, city } = IPProtectionServerlist.getDefaultLocation(); + Assert.equal(country.code, "US", "The default country should be US"); + Assert.deepEqual(city, TEST_US_CITY, "The correct city should be returned"); + + // Now, update the server list to remove the US entry + const updated_server = { + ...TEST_SERVER_1, + hostname: "updated.example.com", + }; + const updated_city = { + ...TEST_US_CITY, + servers: [updated_server], + }; + const updated_country = { + ...TEST_COUNTRIES[0], + cities: [updated_city], + }; + + await client.db.clear(); + await client.db.create(updated_country); + await client.db.importChanges({}, Date.now()); + await client.emit("sync", { data: {} }); + + await IPProtectionServerlist.maybeFetchList(); + + ({ country, city } = IPProtectionServerlist.getDefaultLocation()); + Assert.equal(country.code, "US", "The default country should be US"); + Assert.deepEqual(city, updated_city, "The updated city should be returned"); +});