tor-browser

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

commit 9e73c5b09f47b8b24bd02bbf8a9bd58adfa1649a
parent f5f68709dddcf4abbe3b59b58ab275c3633a8cc9
Author: Sandor Molnar <smolnar@mozilla.com>
Date:   Thu, 13 Nov 2025 17:44:26 +0200

Revert "Bug 1997664 - Connect allow-list from RS to Actor pair r=thecount,home-newtab-reviewers" for causing build bustages

This reverts commit c3bbb8785ea008a8fb07bca7c9df812799eb9f74.

Diffstat:
Mbrowser/extensions/newtab/content-src/components/DiscoveryStreamAdmin/DiscoveryStreamAdmin.jsx | 18------------------
Mbrowser/extensions/newtab/data/content/activity-stream.bundle.js | 19+------------------
Mbrowser/extensions/newtab/lib/NewTabActorRegistry.sys.mjs | 2+-
Mbrowser/extensions/newtab/lib/actors/NewTabAttributionParent.sys.mjs | 85++-----------------------------------------------------------------------------
Mbrowser/extensions/newtab/test/browser/browser_attribution_actor.js | 107-------------------------------------------------------------------------------
5 files changed, 4 insertions(+), 227 deletions(-)

diff --git a/browser/extensions/newtab/content-src/components/DiscoveryStreamAdmin/DiscoveryStreamAdmin.jsx b/browser/extensions/newtab/content-src/components/DiscoveryStreamAdmin/DiscoveryStreamAdmin.jsx @@ -149,7 +149,6 @@ export class DiscoveryStreamAdminUI extends React.PureComponent { this.refreshTopicSelectionCache.bind(this); this.handleSectionsToggle = this.handleSectionsToggle.bind(this); this.toggleIABBanners = this.toggleIABBanners.bind(this); - this.sendConversionEvent = this.sendConversionEvent.bind(this); this.state = { toggledStories: {}, weatherQuery: "", @@ -358,20 +357,6 @@ export class DiscoveryStreamAdminUI extends React.PureComponent { ); } - sendConversionEvent() { - const detail = { - partnerId: "demo-partner", - lookbackDays: 7, - impressionType: "default", - }; - const event = new CustomEvent("FirefoxConversionNotification", { - detail, - bubbles: true, - composed: true, - }); - window?.dispatchEvent(event); - } - renderComponent(width, component) { return ( <table> @@ -721,9 +706,6 @@ export class DiscoveryStreamAdminUI extends React.PureComponent { /> </div> </details> - <button className="button" onClick={this.sendConversionEvent}> - Send conversion event - </button> <table> <tbody> {prefToggles.map(pref => ( diff --git a/browser/extensions/newtab/data/content/activity-stream.bundle.js b/browser/extensions/newtab/data/content/activity-stream.bundle.js @@ -725,7 +725,6 @@ class DiscoveryStreamAdminUI extends (external_React_default()).PureComponent { this.refreshTopicSelectionCache = this.refreshTopicSelectionCache.bind(this); this.handleSectionsToggle = this.handleSectionsToggle.bind(this); this.toggleIABBanners = this.toggleIABBanners.bind(this); - this.sendConversionEvent = this.sendConversionEvent.bind(this); this.state = { toggledStories: {}, weatherQuery: "" @@ -890,19 +889,6 @@ class DiscoveryStreamAdminUI extends (external_React_default()).PureComponent { this.props.dispatch(actionCreators.SetPref("discoverystream.sections.cards.enabled", pressed)); this.props.dispatch(actionCreators.SetPref("discoverystream.sections.cards.thumbsUpDown.enabled", pressed)); } - sendConversionEvent() { - const detail = { - partnerId: "demo-partner", - lookbackDays: 7, - impressionType: "default" - }; - const event = new CustomEvent("FirefoxConversionNotification", { - detail, - bubbles: true, - composed: true - }); - window?.dispatchEvent(event); - } renderComponent(width, component) { return /*#__PURE__*/external_React_default().createElement("table", null, /*#__PURE__*/external_React_default().createElement("tbody", null, /*#__PURE__*/external_React_default().createElement(Row, null, /*#__PURE__*/external_React_default().createElement("td", { className: "min" @@ -1127,10 +1113,7 @@ class DiscoveryStreamAdminUI extends (external_React_default()).PureComponent { pressed: mediumRectangleEnabledPressed || null, onToggle: this.toggleIABBanners, label: "Enable IAB Medium Rectangle (MREC)" - }))), /*#__PURE__*/external_React_default().createElement("button", { - className: "button", - onClick: this.sendConversionEvent - }, "Send conversion event"), /*#__PURE__*/external_React_default().createElement("table", null, /*#__PURE__*/external_React_default().createElement("tbody", null, prefToggles.map(pref => /*#__PURE__*/external_React_default().createElement(Row, { + }))), /*#__PURE__*/external_React_default().createElement("table", null, /*#__PURE__*/external_React_default().createElement("tbody", null, prefToggles.map(pref => /*#__PURE__*/external_React_default().createElement(Row, { key: pref }, /*#__PURE__*/external_React_default().createElement("td", null, /*#__PURE__*/external_React_default().createElement(TogglePrefCheckbox, { checked: config[pref], diff --git a/browser/extensions/newtab/lib/NewTabActorRegistry.sys.mjs b/browser/extensions/newtab/lib/NewTabActorRegistry.sys.mjs @@ -40,7 +40,7 @@ export const NewTabActorRegistry = { }, /** - * Registers the Attribution actor. + * Registers the Attribution actor to handle conversion events from advertiser websites. * Called by NewTabAttributionFeed when attribution is enabled. */ registerAttributionActor() { diff --git a/browser/extensions/newtab/lib/actors/NewTabAttributionParent.sys.mjs b/browser/extensions/newtab/lib/actors/NewTabAttributionParent.sys.mjs @@ -16,10 +16,6 @@ ChromeUtils.defineLazyGetter(lazy, "logConsole", function () { }); }); -ChromeUtils.defineESModuleGetters(lazy, { - RemoteSettings: "resource://services-settings/remote-settings.sys.mjs", -}); - /** * Allowed fields in the conversion event payload from advertisers. * - partnerId: Mozilla-generated UUID associated with the advertiser @@ -49,10 +45,9 @@ function isPlainObject(obj) { ); } -const ATTRIBUTION_ALLOWLIST_COLLECTION = "newtab-attribution-allowlist"; - +// RS collection: https://bugzilla.mozilla.org/show_bug.cgi?id=1994040 +// TODO: connect to RS collection when created let gAllowList = new Set([]); -let gAllowListClient = null; /** * Parent-side JSWindowActor for handling attribution conversion events. @@ -62,11 +57,6 @@ let gAllowListClient = null; * Upon successful validation, the conversion data is passed to NewTabAttributionService */ export class AttributionParent extends JSWindowActorParent { - constructor() { - super(); - this._onSync = this.onSync.bind(this); - } - /** * TEST-ONLY: Override the allowlist from a test. * @@ -77,73 +67,6 @@ export class AttributionParent extends JSWindowActorParent { } /** - * TEST-ONLY: Reset the Remote Settings client. - */ - resetRemoteSettingsClientForTest() { - gAllowListClient = null; - } - - /** - * This thin wrapper around lazy.RemoteSettings makes it easier for us to write - * automated tests that simulate responses from this fetch. - */ - RemoteSettings(...args) { - return lazy.RemoteSettings(...args); - } - - /** - * Updates the global allowlist with the provided records. - * - * @param {Array} records - Array of Remote Settings records containing domain fields. - */ - updateAllowList(records) { - if (records?.length) { - const domains = records.map(record => record.domain); - gAllowList = new Set(domains); - } else { - gAllowList = new Set([]); - } - } - - /** - * Retrieves the allow list of advertiser origins from Remote Settings. - * Populates the internal gAllowList set with the retrieved origins. - */ - async retrieveAllowList() { - try { - if (!gAllowListClient) { - gAllowListClient = this.RemoteSettings( - ATTRIBUTION_ALLOWLIST_COLLECTION - ); - gAllowListClient.on("sync", this._onSync); - const records = await gAllowListClient.get(); - this.updateAllowList(records); - } - } catch (error) { - lazy.logConsole.error( - `AttributionParent: failed to retrieve allow list: ${error}` - ); - } - } - - /** - * Handles Remote Settings sync events. - * Updates the allow list when the collection changes. - * - * @param {object} event - The sync event object. - * @param {Array} event.data.current - The current records after sync. - */ - onSync({ data: { current } }) { - this.updateAllowList(current); - } - - didDestroy() { - if (gAllowListClient) { - gAllowListClient.off("sync", this._onSync); - } - } - - /** * Validates a conversion event payload from an advertiser. * Ensures all required fields are present, correctly typed, and within valid ranges. * @@ -217,10 +140,6 @@ export class AttributionParent extends JSWindowActorParent { return; } - if (!gAllowList.size) { - await this.retrieveAllowList(); - } - // Only accept conversion events from allowlisted origins if (!gAllowList.has(principal.originNoSuffix)) { lazy.logConsole.error( diff --git a/browser/extensions/newtab/test/browser/browser_attribution_actor.js b/browser/extensions/newtab/test/browser/browser_attribution_actor.js @@ -11,18 +11,10 @@ ChromeUtils.defineESModuleGetters(this, { "resource://newtab/lib/NewTabAttributionService.sys.mjs", }); -const { AttributionParent } = ChromeUtils.importESModule( - "resource://newtab/lib/actors/NewTabAttributionParent.sys.mjs" -); - const { DAPSender } = ChromeUtils.importESModule( "resource://gre/modules/DAPSender.sys.mjs" ); -const { RemoteSettings } = ChromeUtils.importESModule( - "resource://services-settings/remote-settings.sys.mjs" -); - let sandbox; let dapStub; let conversionStub; @@ -258,102 +250,3 @@ add_task(async function test_parent_blocks_missing_detail() { Assert.ok(!conversionStub.called, "onAttributionConversion was not called"); }); }); - -/** - * Test that Remote Settings client uses get() and registers onSync handler. - */ -add_task(async function test_remote_settings_sync_and_handler() { - await resetTestState(); - - const mockClient = { - get: sandbox - .stub() - .resolves([ - { domain: "https://example.com" }, - { domain: "https://partner.com" }, - ]), - on: sandbox.stub(), - off: sandbox.stub(), - }; - - await BrowserTestUtils.withNewTab(TEST_URL, async browser => { - const parent = await getParentActor(browser); - parent.resetRemoteSettingsClientForTest(); - sandbox.stub(parent, "RemoteSettings").returns(mockClient); - - await parent.retrieveAllowList(); - - Assert.ok(mockClient.get.calledOnce, "get() was called once"); - Assert.ok(mockClient.on.calledOnce, "on() was called once"); - Assert.equal( - mockClient.on.firstCall.args[0], - "sync", - "on() was called with 'sync' event" - ); - }); -}); - -/** - * Test that onSync updates the allowlist when Remote Settings syncs. - */ -add_task(async function test_onSync_updates_allowlist() { - await resetTestState(); - - await BrowserTestUtils.withNewTab(TEST_URL, async browser => { - const parent = await getParentActor(browser); - const testOrigin = "https://test-partner.com"; - - parent.setAllowListForTest([]); - - parent.onSync({ - data: { - current: [{ domain: "https://example.com" }, { domain: testOrigin }], - }, - }); - - const origin = parent.manager.documentPrincipal.originNoSuffix; - parent.setAllowListForTest([origin]); - - await dispatchAttributionEvent(browser, { - partnerId: "test-partner", - lookbackDays: 7, - impressionType: "view", - }); - - await BrowserTestUtils.waitForCondition(() => conversionStub.calledOnce); - Assert.ok( - conversionStub.calledOnce, - "onAttributionConversion was called after onSync updated allowlist" - ); - }); -}); - -/** - * Test that didDestroy removes the onSync event listener. - */ -add_task(async function test_didDestroy_removes_listener() { - await resetTestState(); - - const mockClient = { - get: sandbox.stub().resolves([]), - on: sandbox.stub(), - off: sandbox.stub(), - }; - - await BrowserTestUtils.withNewTab(TEST_URL, async browser => { - const parent = await getParentActor(browser); - parent.resetRemoteSettingsClientForTest(); - sandbox.stub(parent, "RemoteSettings").returns(mockClient); - - await parent.retrieveAllowList(); - - parent.didDestroy(); - - Assert.ok(mockClient.off.calledOnce, "off() was called once"); - Assert.equal( - mockClient.off.firstCall.args[0], - "sync", - "off() was called with 'sync' event" - ); - }); -});