tor-browser

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

commit 6512de7a7f6b516881ba5940ca38b40436c47575
parent c11470f66f0e49c02f44966df725cd246dbabafb
Author: Pier Angelo Vendrame <pierov@torproject.org>
Date:   Tue,  7 Oct 2025 20:27:03 +0000

Bug 1987183 - Automatically check the addon PBM checkbox when in always-on PBM. r=robwu

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

Diffstat:
Mbrowser/components/extensions/test/browser/browser-private.toml | 2++
Abrowser/components/extensions/test/browser/browser_always_on_pbm_prompt.js | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbrowser/modules/ExtensionsUI.sys.mjs | 4+++-
3 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/browser/components/extensions/test/browser/browser-private.toml b/browser/components/extensions/test/browser/browser-private.toml @@ -6,6 +6,8 @@ tags = "webextensions" prefs = ["browser.privatebrowsing.autostart=true"] support-files = ["head.js"] +["browser_always_on_pbm_prompt.js"] + ["browser_ext_tabs_cookieStoreId_private.js"] ["browser_ext_tabs_newtab_private.js"] diff --git a/browser/components/extensions/test/browser/browser_always_on_pbm_prompt.js b/browser/components/extensions/test/browser/browser_always_on_pbm_prompt.js @@ -0,0 +1,95 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { AddonTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/AddonTestUtils.sys.mjs" +); + +AddonTestUtils.initMochitest(this); + +const addonId = "test@pbm-checkbox"; +let xpi; + +async function testCheckbox(allowPbm, expectedCheckboxValue) { + const readyPromise = AddonTestUtils.promiseWebExtensionStartup(addonId); + + window.gURLBar.value = xpi.path; + window.gURLBar.focus(); + EventUtils.synthesizeKey("KEY_Enter", {}, window); + + const panel = await promisePopupNotificationShown("addon-webext-permissions"); + const checkbox = panel.querySelector( + "li.webext-perm-privatebrowsing > moz-checkbox" + ); + ok(checkbox, "We found the PBM checkbox"); + + is( + checkbox.checked, + expectedCheckboxValue, + `We expected the PBM checkbox ${expectedCheckboxValue ? "" : "not "}to be checked for this test case.` + ); + + if (checkbox.checked != allowPbm) { + let { promise, resolve } = Promise.withResolvers(); + checkbox.addEventListener("change", resolve, { once: true }); + checkbox.click(); + await promise; + } + + is(checkbox.checked, allowPbm, "The checkbox matches allowPbm."); + + // Accept the installation + panel.button.click(); + + await readyPromise; + + let policy = WebExtensionPolicy.getByID(addonId); + is( + policy.privateBrowsingAllowed, + allowPbm, + `Private browsing permission has ${allowPbm ? "" : "not "}been granted` + ); +} + +async function uninstall() { + const addon = await AddonManager.getAddonByID(addonId); + await addon.uninstall(); +} + +add_task(async function () { + is( + PrivateBrowsingUtils.permanentPrivateBrowsing, + true, + "We are in permanent PBM for this test" + ); + + xpi = AddonTestUtils.createTempWebExtensionFile({ + manifest: { + browser_specific_settings: { gecko: { id: addonId } }, + }, + }); + + await BrowserTestUtils.withNewTab({ gBrowser: window.gBrowser }, async () => { + // First run: install the addon for the first time. We do not let it run in + // PBM. + await testCheckbox(false, true); + // Second run: reinstall the already installed addon, to check the + // permission denial prevails on being in always-on PBM. + await testCheckbox(false, false); + }); + + await uninstall(); + + await BrowserTestUtils.withNewTab({ gBrowser: window.gBrowser }, async () => { + // Third run: install the addon for the first time, and let it run also in + // PBM. + await testCheckbox(true, true); + // Fourth run: reinstall the already installed addon, to check permission + // approval is persisted. + await testCheckbox(true, true); + }); + + await uninstall(); +}); diff --git a/browser/modules/ExtensionsUI.sys.mjs b/browser/modules/ExtensionsUI.sys.mjs @@ -16,6 +16,7 @@ ChromeUtils.defineESModuleGetters(lazy, { AppMenuNotifications: "resource://gre/modules/AppMenuNotifications.sys.mjs", ExtensionData: "resource://gre/modules/Extension.sys.mjs", ExtensionPermissions: "resource://gre/modules/ExtensionPermissions.sys.mjs", + PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs", OriginControls: "resource://gre/modules/ExtensionPermissions.sys.mjs", QuarantinedDomains: "resource://gre/modules/ExtensionPermissions.sys.mjs", }); @@ -420,7 +421,8 @@ export var ExtensionsUI = { !!strings.dataCollectionPermissions?.collectsTechnicalAndInteractionData; const incognitoPermissionName = "internal:privateBrowsingAllowed"; - let grantPrivateBrowsingAllowed = false; + let grantPrivateBrowsingAllowed = + lazy.PrivateBrowsingUtils.permanentPrivateBrowsing; if ( showIncognitoCheckbox && // Usually false, unless the user tries to install a XPI file whose ID