From 73c28bc29ee59a5a33d4f2ba1a72a9abeea070c1 Mon Sep 17 00:00:00 2001 From: bill-auger Date: Mon, 11 Jan 2021 02:05:56 -0500 Subject: [iceweasel]: housekeeping --- ...ways-sync-remote-settings-with-local-dump.patch | 987 +++++++++++++++++++++ libre/iceweasel/9002-misc-libre.patch | 387 ++++++++ libre/iceweasel/PKGBUILD | 71 +- ...ways-sync-remote-settings-with-local-dump.patch | 987 --------------------- libre/iceweasel/libre-process-json-files.py | 174 ---- libre/iceweasel/libre.patch | 387 -------- libre/iceweasel/process-json-files.py | 174 ++++ 7 files changed, 1584 insertions(+), 1583 deletions(-) create mode 100644 libre/iceweasel/9001-always-sync-remote-settings-with-local-dump.patch create mode 100644 libre/iceweasel/9002-misc-libre.patch delete mode 100644 libre/iceweasel/libre-0001-always-sync-remote-settings-with-local-dump.patch delete mode 100644 libre/iceweasel/libre-process-json-files.py delete mode 100644 libre/iceweasel/libre.patch create mode 100644 libre/iceweasel/process-json-files.py diff --git a/libre/iceweasel/9001-always-sync-remote-settings-with-local-dump.patch b/libre/iceweasel/9001-always-sync-remote-settings-with-local-dump.patch new file mode 100644 index 000000000..d22b7e35d --- /dev/null +++ b/libre/iceweasel/9001-always-sync-remote-settings-with-local-dump.patch @@ -0,0 +1,987 @@ +From c115ebc66ae779c18128e0b815fcf29da268a4f8 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 17:20:39 +0200 +Subject: [PATCH 01/13] Point to local omni.ja files, not remote server + +Basically replace every occurrence of Remote Settings server domain name +with URIs that point to built-in local files within omni.ja. + +Some links to json files may point to non-existing files, but that's OK +because it's better than leave them point to Remote Settings server. +If necessary, missing files can be added later. +--- + .../components/ASRouterAdmin/ASRouterAdmin.jsx | 2 +- + .../newtab/data/content/activity-stream.bundle.js | 2 +- + modules/libpref/init/all.js | 2 +- + services/settings/Utils.jsm | 4 ++-- + .../periodic-updates/scripts/periodic_file_updates.sh | 2 +- + toolkit/components/search/SearchUtils.jsm | 8 ++++---- + toolkit/components/search/docs/DefaultSearchEngines.rst | 2 +- + .../components/search/docs/SearchEngineConfiguration.rst | 2 +- + toolkit/mozapps/defaultagent/RemoteSettings.cpp | 2 +- + 9 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx b/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx +index 8c5e540bd2..329e4e66f9 100644 +--- a/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx ++++ b/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx +@@ -1260,7 +1260,7 @@ export class ASRouterAdminInner extends React.PureComponent { + + nimbus-desktop-experiments +diff --git a/browser/components/newtab/data/content/activity-stream.bundle.js b/browser/components/newtab/data/content/activity-stream.bundle.js +index fb6d64d432..d8213e7e20 100644 +--- a/browser/components/newtab/data/content/activity-stream.bundle.js ++++ b/browser/components/newtab/data/content/activity-stream.bundle.js +@@ -1835,7 +1835,7 @@ class ASRouterAdminInner extends react__WEBPACK_IMPORTED_MODULE_4___default.a.Pu + label = react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("span", null, "remote settings (", react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("a", { + className: "providerUrl", + target: "_blank", +- href: "https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/nimbus-desktop-experiments/records", ++ href: "resource://app/defaults/settings/main/nimbus-desktop-experiments.json", + rel: "noopener noreferrer" + }, "nimbus-desktop-experiments"), ")"); + } +diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js +index 2406affed4..907e8ebcef 100644 +--- a/modules/libpref/init/all.js ++++ b/modules/libpref/init/all.js +@@ -2250,7 +2250,7 @@ pref("security.cert_pinning.hpkp.enabled", false); + // Remote settings preferences + // Note: if you change this, make sure to also review security.onecrl.maximum_staleness_in_seconds + pref("services.settings.poll_interval", 86400); // 24H +-pref("services.settings.server", "https://firefox.settings.services.mozilla.com/v1"); ++pref("services.settings.server", "resource://app/defaults/settings"); + pref("services.settings.default_bucket", "main"); + + // The percentage of clients who will report uptake telemetry as +diff --git a/services/settings/Utils.jsm b/services/settings/Utils.jsm +index 66df850904..0df0fdc677 100644 +--- a/services/settings/Utils.jsm ++++ b/services/settings/Utils.jsm +@@ -60,11 +60,11 @@ var Utils = { + ); + const isXpcshell = env.exists("XPCSHELL_TEST_PROFILE_DIR"); + return AppConstants.RELEASE_OR_BETA && !Cu.isInAutomation && !isXpcshell +- ? "https://firefox.settings.services.mozilla.com/v1" ++ ? "resource://app/defaults/settings" + : gServerURL; + }, + +- CHANGES_PATH: "/buckets/monitor/collections/changes/records", ++ CHANGES_PATH: "/monitor/changes.json", + + /** + * Logger instance. +diff --git a/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh b/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh +index c2492615e0..2b10ad01f6 100755 +--- a/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh ++++ b/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh +@@ -279,7 +279,7 @@ function compare_suffix_lists { + } + + function compare_remote_settings_files { +- REMOTE_SETTINGS_SERVER="https://firefox.settings.services.mozilla.com/v1" ++ REMOTE_SETTINGS_SERVER="resource://app/defaults/settings" + + # 1. List remote settings collections from server. + echo "INFO: fetch remote settings list from server" +diff --git a/toolkit/components/search/SearchUtils.jsm b/toolkit/components/search/SearchUtils.jsm +index 278f9f9c08..7bac023c11 100644 +--- a/toolkit/components/search/SearchUtils.jsm ++++ b/toolkit/components/search/SearchUtils.jsm +@@ -139,13 +139,13 @@ var SearchUtils = { + + ENGINES_URLS: { + "prod-main": +- "https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-config/records", ++ "resource://app/defaults/settings/main/search-config.json", + "prod-preview": +- "https://firefox.settings.services.mozilla.com/v1/buckets/main-preview/collections/search-config/records", ++ "resource://app/defaults/settings/main/search-config.json", + "stage-main": +- "https://settings.stage.mozaws.net/v1/buckets/main/collections/search-config/records", ++ "resource://app/defaults/settings/main/search-config.json", + "stage-preview": +- "https://settings.stage.mozaws.net/v1/buckets/main-preview/collections/search-config/records", ++ "resource://app/defaults/settings/main/search-config.json", + }, + + // The following constants are left undocumented in nsISearchService.idl +diff --git a/toolkit/components/search/docs/DefaultSearchEngines.rst b/toolkit/components/search/docs/DefaultSearchEngines.rst +index 5668646648..deb7d20185 100644 +--- a/toolkit/components/search/docs/DefaultSearchEngines.rst ++++ b/toolkit/components/search/docs/DefaultSearchEngines.rst +@@ -63,4 +63,4 @@ is updated. + + .. _configuration schema: SearchConfigurationSchema.html + .. _remote settings: /services/common/services/RemoteSettings.html +-.. _search-default-override-allowlist bucket: https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-default-override-allowlist/records ++.. _search-default-override-allowlist bucket: resource://app/defaults/settings/main/search-default-override-allowlist.json +diff --git a/toolkit/components/search/docs/SearchEngineConfiguration.rst b/toolkit/components/search/docs/SearchEngineConfiguration.rst +index e9041affb8..7a9466d294 100644 +--- a/toolkit/components/search/docs/SearchEngineConfiguration.rst ++++ b/toolkit/components/search/docs/SearchEngineConfiguration.rst +@@ -68,5 +68,5 @@ related. As a result several situations may occur: + .. _JSON schema: https://json-schema.org/ + .. _stored in mozilla-central: https://searchfox.org/mozilla-central/source/toolkit/components/search/schema/ + .. _Search Configuration Schema: SearchConfigurationSchema.html +-.. _viewed live: https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-config/records ++.. _viewed live: resource://app/defaults/settings/main/search-config.json + .. _Normandy: /toolkit/components/normandy/normandy/services.html +diff --git a/toolkit/mozapps/defaultagent/RemoteSettings.cpp b/toolkit/mozapps/defaultagent/RemoteSettings.cpp +index 667d9fc628..b2bf628f29 100644 +--- a/toolkit/mozapps/defaultagent/RemoteSettings.cpp ++++ b/toolkit/mozapps/defaultagent/RemoteSettings.cpp +@@ -23,7 +23,7 @@ extern "C" { + HRESULT IsAgentRemoteDisabledRust(const char* szUrl, DWORD* lpdwDisabled); + } + +-#define PROD_ENDPOINT "https://firefox.settings.services.mozilla.com/v1" ++#define PROD_ENDPOINT "resource://app/defaults/settings" + #define PROD_BID "main" + #define PROD_CID "windows-default-browser-agent" + #define PROD_ID "state" +-- +2.30.0 + + +From f76e1c055def541e358886d0e73ba4710d3e5084 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 17:34:08 +0200 +Subject: [PATCH 02/13] Remove polling triggered by push broadcasts + +When initialized, remote-settings.js adds a listener to push broadcasts, +that let Remote Settings server send push messages to trigger polling +for changes from the client side. This is not needed for local-only +setup. Remove the record from broadcast-listeners.json file stored in +the user profile, so that it doesn't get picked up by push broadcast +service. +--- + dom/push/PushBroadcastService.jsm | 13 +++++++++++++ + services/settings/remote-settings.js | 7 ++----- + 2 files changed, 15 insertions(+), 5 deletions(-) + +diff --git a/dom/push/PushBroadcastService.jsm b/dom/push/PushBroadcastService.jsm +index 27ed31ee9c..71f1316994 100644 +--- a/dom/push/PushBroadcastService.jsm ++++ b/dom/push/PushBroadcastService.jsm +@@ -179,6 +179,19 @@ var BroadcastService = class { + } + } + ++ async deleteListener(broadcastId) { ++ await this.initializePromise; ++ ++ if (this.jsonFile.data.listeners.hasOwnProperty(broadcastId)) { ++ console.info( ++ "deleteListener: deleting listener", ++ broadcastId ++ ); ++ delete this.jsonFile.data.listeners[broadcastId]; ++ this.jsonFile.saveSoon(); ++ } ++ } ++ + /** + * Call the listeners of the specified broadcasts. + * +diff --git a/services/settings/remote-settings.js b/services/settings/remote-settings.js +index 6d0185faf9..aae93fa440 100644 +--- a/services/settings/remote-settings.js ++++ b/services/settings/remote-settings.js +@@ -441,7 +441,7 @@ function remoteSettingsFunction() { + moduleURI: __URI__, + symbolName: "remoteSettingsBroadcastHandler", + }; +- pushBroadcastService.addListener(BROADCAST_ID, currentVersion, moduleInfo); ++ pushBroadcastService.deleteListener(BROADCAST_ID); + }; + + return remoteSettings; +@@ -461,9 +461,6 @@ var remoteSettingsBroadcastHandler = { + `Push notification received (version=${version} phase=${phase})` + ); + +- return RemoteSettings.pollChanges({ +- expectedTimestamp: version, +- trigger: isStartup ? "startup" : "broadcast", +- }); ++ return; + }, + }; +-- +2.30.0 + + +From fcf60ef5835e673e03807d898f90e48907f44e63 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 17:41:54 +0200 +Subject: [PATCH 03/13] Remove timer that triggers polling for changes + +That is not needed for local-only setup. +--- + services/settings/components.conf | 9 +-------- + services/settings/servicesSettings.manifest | 4 ---- + 2 files changed, 1 insertion(+), 12 deletions(-) + +diff --git a/services/settings/components.conf b/services/settings/components.conf +index 9a737802ee..25109415a7 100644 +--- a/services/settings/components.conf ++++ b/services/settings/components.conf +@@ -4,11 +4,4 @@ + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + +-Classes = [ +- { +- 'cid': '{5e756573-234a-49ea-bbe4-59ec7a70657d}', +- 'contract_ids': ['@mozilla.org/services/settings;1'], +- 'jsm': 'resource://services-settings/RemoteSettingsComponents.jsm', +- 'constructor': 'RemoteSettingsTimer', +- }, +-] ++Classes = [] +diff --git a/services/settings/servicesSettings.manifest b/services/settings/servicesSettings.manifest +index 3bfed26ea4..807eb220ec 100644 +--- a/services/settings/servicesSettings.manifest ++++ b/services/settings/servicesSettings.manifest +@@ -1,7 +1,3 @@ + # Register resource aliases + resource services-settings resource://gre/modules/services-settings/ + +-# Schedule polling of remote settings changes +-# (default 24H, max 72H) +-# see syntax https://searchfox.org/mozilla-central/rev/cc280c4be94ff8cf64a27cc9b3d6831ffa49fa45/toolkit/components/timermanager/UpdateTimerManager.jsm#155 +-category update-timer RemoteSettingsComponents @mozilla.org/services/settings;1,getService,services-settings-poll-changes,services.settings.poll_interval,86400,259200 +-- +2.30.0 + + +From 8600d50c402f523973f67dfb03c1ea8614fcf48c Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 17:47:41 +0200 +Subject: [PATCH 04/13] Utils: fetch timestamps of each collection locally + +Utils.CHANGES_PATH points to +services/settings/dumps/monitor/changes.json +which will be generated later by JSON processing script. Fetch the +timestamps from that file and mock response headers to not confuse any +code that expects them. +--- + browser/installer/package-manifest.in | 1 + + services/settings/Utils.jsm | 14 ++++++++++++-- + services/settings/dumps/monitor/moz.build | 8 ++++++++ + services/settings/dumps/moz.build | 1 + + 4 files changed, 22 insertions(+), 2 deletions(-) + create mode 100644 services/settings/dumps/monitor/moz.build + +diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in +index 75c79a7168..ac01689596 100644 +--- a/browser/installer/package-manifest.in ++++ b/browser/installer/package-manifest.in +@@ -295,6 +295,7 @@ + @RESPATH@/browser/defaults/settings/blocklists + @RESPATH@/browser/defaults/settings/pinning + @RESPATH@/browser/defaults/settings/main ++@RESPATH@/browser/defaults/settings/monitor + @RESPATH@/browser/defaults/settings/security-state + + ; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325) +diff --git a/services/settings/Utils.jsm b/services/settings/Utils.jsm +index 0df0fdc677..0e631ddc0d 100644 +--- a/services/settings/Utils.jsm ++++ b/services/settings/Utils.jsm +@@ -145,7 +145,7 @@ var Utils = { + // "collection":"certificates" + // }]} + +- let url = serverUrl + Utils.CHANGES_PATH; ++ let url = Utils.SERVER_URL + Utils.CHANGES_PATH; + + // Use ETag to obtain a `304 Not modified` when no change occurred, + // and `?_since` parameter to only keep entries that weren't processed yet. +@@ -166,6 +166,9 @@ var Utils = { + .join("&"); + } + const response = await fetch(url, { headers }); ++ const responseDate = new Date().toUTCString() ++ response.headers.set("Date", responseDate); ++ response.headers.set("Last-Modified", responseDate); + + let changes = []; + // If no changes since last time, go on with empty list of changes. +@@ -203,7 +206,14 @@ var Utils = { + ); + } + } else { +- changes = payload.data; ++ const { bucket, collection } = filters; ++ if (!bucket || !collection) { ++ throw new Error('Unable to fetch latest change without bucket or collection'); ++ } ++ const change = payload.data.find( ++ change => change.bucket === bucket && change.collection === collection ++ ) ?? { last_modified: 0, bucket, collection }; ++ changes = [change]; + } + } + // The server should always return ETag. But we've had situations where the CDN +diff --git a/services/settings/dumps/monitor/moz.build b/services/settings/dumps/monitor/moz.build +new file mode 100644 +index 0000000000..d3d017fda5 +--- /dev/null ++++ b/services/settings/dumps/monitor/moz.build +@@ -0,0 +1,8 @@ ++# This Source Code Form is subject to the terms of the Mozilla Public ++# License, v. 2.0. If a copy of the MPL was not distributed with this ++# file, You can obtain one at http://mozilla.org/MPL/2.0/. ++ ++FINAL_TARGET_FILES.defaults.settings.monitor += ["changes.json"] ++ ++if CONFIG["MOZ_BUILD_APP"] == "browser": ++ DIST_SUBDIR = "browser" +diff --git a/services/settings/dumps/moz.build b/services/settings/dumps/moz.build +index 3cc9436f61..3742da5667 100644 +--- a/services/settings/dumps/moz.build ++++ b/services/settings/dumps/moz.build +@@ -5,6 +5,7 @@ + DIRS += [ + "blocklists", + "main", ++ "monitor", + "pinning", + "security-state", + ] +-- +2.30.0 + + +From 99af961e47d810c965c0145f19a92eedec1abafc Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 17:52:10 +0200 +Subject: [PATCH 05/13] Utils: disable offline checking + +Since only local data is read now, it should always return false for the +current any any future code that relies on it. +--- + services/settings/Utils.jsm | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/services/settings/Utils.jsm b/services/settings/Utils.jsm +index 0e631ddc0d..d034d8ea78 100644 +--- a/services/settings/Utils.jsm ++++ b/services/settings/Utils.jsm +@@ -80,15 +80,6 @@ var Utils = { + * @return {bool} Whether network is down or not. + */ + get isOffline() { +- try { +- return ( +- Services.io.offline || +- CaptivePortalService.state == CaptivePortalService.LOCKED_PORTAL || +- !gNetworkLinkService.isLinkUp +- ); +- } catch (ex) { +- log.warn("Could not determine network status.", ex); +- } + return false; + }, + +-- +2.30.0 + + +From 55830695a1e2457aecca1392d46c98c3e210d58a Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 17:56:02 +0200 +Subject: [PATCH 06/13] Refactor hashing logic to a separate function + +It is used instead of internal signature validation mechanism, for +integrity checking of the locally cached data. +--- + services/settings/RemoteSettingsWorker.jsm | 4 ++++ + services/settings/SharedUtils.jsm | 9 +++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/services/settings/RemoteSettingsWorker.jsm b/services/settings/RemoteSettingsWorker.jsm +index 147ebb6b13..c86e218fd3 100644 +--- a/services/settings/RemoteSettingsWorker.jsm ++++ b/services/settings/RemoteSettingsWorker.jsm +@@ -189,6 +189,10 @@ class Worker { + // task on the current thread instead of the worker thread. + return SharedUtils.checkContentHash(buffer, size, hash); + } ++ ++ async getContentHash(bytes) { ++ return SharedUtils.getContentHash(bytes); ++ } + } + + // Now, first add a shutdown blocker. If that fails, we must have +diff --git a/services/settings/SharedUtils.jsm b/services/settings/SharedUtils.jsm +index db5017a742..1a8e83c2e8 100644 +--- a/services/settings/SharedUtils.jsm ++++ b/services/settings/SharedUtils.jsm +@@ -28,11 +28,16 @@ var SharedUtils = { + return false; + } + // Has expected content? ++ const hashStr = await this.getContentHash(bytes); ++ return hashStr == hash; ++ }, ++ ++ async getContentHash(bytes) { + const hashBuffer = await crypto.subtle.digest("SHA-256", bytes); + const hashBytes = new Uint8Array(hashBuffer); + const toHex = b => b.toString(16).padStart(2, "0"); +- const hashStr = Array.from(hashBytes, toHex).join(""); +- return hashStr == hash; ++ ++ return Array.from(hashBytes, toHex).join(""); + }, + + /** +-- +2.30.0 + + +From 9dc19397aebfb6b9f74afa0fb4d653a29e14e964 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 18:05:02 +0200 +Subject: [PATCH 07/13] Client: Fetch and hash records from local dump + +Read the records from local dumps. See [1] for details on how to prepare +custom dumps). Records are cached in the local IndexedDB, and the client +updates cached records each time there's a change. Also it verifies +integrity of the data. Then the list of current / created / updated / +deleted records is generated and emitted to every registered listener. + +Change upstream signature validation mechanism to a simpler one. +Otherwise, it'd be necessary to sign local records, which is redundant, +because the application package should be signed already by the distro. + +Instead of signature property from metadata records, json_dump_metadata +has been introduced. It contains the checksum of the records and size in +bytes. Also added app_build_id property for version checking and updates +of cached data. + +Although it's possible to disable integrity checking via preference, it +seems to be not a good idea, because the logic that detects invalid +local data relies on it. In the context of local-only setup, data that +has been received from real Remote Settings server will not contain the +custom metadata, and thus will be considered invalid and then discarded, +while the client gets a chance to gracefully inform registered listeners +about these changes so that they can discard the data received before +the upgrade to local-only setup. + +[1] https://firefox-source-docs.mozilla.org/services/common/services/RemoteSettings.html#initial-data +--- + services/settings/RemoteSettingsClient.jsm | 62 ++++++++++------------ + 1 file changed, 27 insertions(+), 35 deletions(-) + +diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm +index 80dd563e11..1025ab33a2 100644 +--- a/services/settings/RemoteSettingsClient.jsm ++++ b/services/settings/RemoteSettingsClient.jsm +@@ -556,11 +556,9 @@ class RemoteSettingsClient extends EventEmitter { + + // If the data is up-to-date but don't have metadata (records loaded from dump), + // we fetch them and validate the signature immediately. +- if (this.verifySignature && ObjectUtils.isEmpty(localMetadata)) { ++ if (this.verifySignature && ObjectUtils.isEmpty(localMetadata?.json_dump_metadata)) { + console.debug(`${this.identifier} pull collection metadata`); +- const metadata = await this.httpClient().getData({ +- query: { _expected: expectedTimestamp }, +- }); ++ const { metadata } = await this._fetchChangeset(expectedTimestamp); + await this.db.importChanges(metadata); + // We don't bother validating the signature if the dump was just loaded. We do + // if the dump was loaded at some other point (eg. from .get()). +@@ -813,32 +811,23 @@ class RemoteSettingsClient extends EventEmitter { + async _validateCollectionSignature(records, timestamp, metadata) { + const start = Cu.now() * 1000; + +- if (!metadata?.signature) { ++ if (!metadata?.json_dump_metadata) { + throw new MissingSignatureError(this.identifier); + } + +- if (!this._verifier) { +- this._verifier = Cc[ +- "@mozilla.org/security/contentsignatureverifier;1" +- ].createInstance(Ci.nsIContentSignatureVerifier); +- } +- +- // This is a content-signature field from an autograph response. + const { +- signature: { x5u, signature }, ++ json_dump_metadata: { hash, size }, + } = metadata; +- const certChain = await (await fetch(x5u)).text(); + // Merge remote records with local ones and serialize as canonical JSON. + const serialized = await RemoteSettingsWorker.canonicalStringify( + records, + timestamp + ); + if ( +- !(await this._verifier.asyncVerifyContentSignature( +- serialized, +- "p384ecdsa=" + signature, +- certChain, +- this.signerName ++ !(await RemoteSettingsWorker.checkContentHash( ++ new TextEncoder().encode(serialized), ++ size, ++ hash + )) + ) { + throw new InvalidSignatureError(this.identifier); +@@ -1030,24 +1019,27 @@ class RemoteSettingsClient extends EventEmitter { + * @param since timestamp of last sync (optional) + */ + async _fetchChangeset(expectedTimestamp, since) { +- const client = this.httpClient(); +- const { +- metadata, +- timestamp: remoteTimestamp, +- changes: remoteRecords, +- } = await client.execute( +- { +- path: `/buckets/${this.bucketName}/collections/${this.collectionName}/changeset`, +- }, +- { +- query: { +- _expected: expectedTimestamp, +- _since: since, +- }, +- } ++ const { data } = await SharedUtils.loadJSONDump( ++ this.bucketName, ++ this.collectionName + ); ++ const remoteRecords = data ?? []; ++ ++ const serialized = await RemoteSettingsWorker.canonicalStringify( ++ remoteRecords, ++ expectedTimestamp ++ ); ++ const bytes = new TextEncoder().encode(serialized); ++ const metadata = { ++ app_build_id: Services.appinfo.appBuildID, ++ json_dump_metadata: { ++ hash: await RemoteSettingsWorker.getContentHash(bytes), ++ size: bytes.length, ++ }, ++ } ++ + return { +- remoteTimestamp, ++ remoteTimestamp: expectedTimestamp, + metadata, + remoteRecords, + }; +-- +2.30.0 + + +From 4dfbb2ccacd011b05839c19127942b497141f2a1 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 18:42:56 +0200 +Subject: [PATCH 08/13] Client: start deferred sync on get() or on() + +The users of the RemoteSettingsClient.jsm can receive records from it in +two ways: by calling get(), and by subscribing to events by calling +on(). + +So hook a deferred sync whenever something calls these methods. Because +multiple of those calls can be made quite early and in very short time, +set up a deferred task that will be armed only when needed and only once +in a second. When the task is running it first checks if the local data +came from the dump of the current app build, and no-ops if true. If +false, it triggers a sync. Then adds a flag if the client has been +correctly synchronized with the dump, so that no metadata checking +occurs during the session. +--- + services/settings/RemoteSettingsClient.jsm | 32 ++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm +index 1025ab33a2..253251823a 100644 +--- a/services/settings/RemoteSettingsClient.jsm ++++ b/services/settings/RemoteSettingsClient.jsm +@@ -16,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { + ClientEnvironmentBase: + "resource://gre/modules/components-utils/ClientEnvironment.jsm", + Database: "resource://services-settings/Database.jsm", ++ DeferredTask: "resource://gre/modules/DeferredTask.jsm", + Downloader: "resource://services-settings/Attachments.jsm", + IDBHelpers: "resource://services-settings/IDBHelpers.jsm", + KintoHttpClient: "resource://services-common/kinto-http-client.js", +@@ -30,6 +31,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { + XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]); + + const TELEMETRY_COMPONENT = "remotesettings"; ++const DEFERRED_SYNC_DELAY_MILLISECONDS = 1000; + + XPCOMUtils.defineLazyGetter(this, "console", () => Utils.log); + +@@ -259,6 +261,14 @@ class RemoteSettingsClient extends EventEmitter { + this._lastCheckTimePref = lastCheckTimePref; + this._verifier = null; + this._syncRunning = false; ++ this._deferredSync = new DeferredTask( ++ async () => { ++ if (!this._syncRunning && !(await this._isSynced())) { ++ await this.sync(); ++ } ++ }, ++ DEFERRED_SYNC_DELAY_MILLISECONDS ++ ); + + // This attribute allows signature verification to be disabled, when running tests + // or when pulling data from a dev server. +@@ -290,6 +300,11 @@ class RemoteSettingsClient extends EventEmitter { + ); + } + ++ on(event, callback) { ++ super.on(event, callback); ++ this._deferredSync.arm(); ++ } ++ + get identifier() { + return `${this.bucketName}/${this.collectionName}`; + } +@@ -353,7 +368,11 @@ class RemoteSettingsClient extends EventEmitter { + try { + let hasLocalData = await Utils.hasLocalData(this); + +- if (syncIfEmpty && !hasLocalData) { ++ if (!(await this._isSynced())) { ++ throw new MissingSignatureError(this.identifier); ++ } ++ ++ if (syncIfEmpty && !hasLocalData) { + // .get() was called before we had the chance to synchronize the local database. + // We'll try to avoid returning an empty list. + if (!this._importingPromise) { +@@ -414,7 +433,10 @@ class RemoteSettingsClient extends EventEmitter { + // No need to verify signature on JSON dumps. + // If local DB cannot be read, then we don't even try to do anything, + // we return results early. +- return this._filterEntries(data); ++ const filtered = this._filterEntries(data); ++ this._deferredSync.arm(); ++ ++ return filtered; + } + + console.debug( +@@ -452,6 +474,12 @@ class RemoteSettingsClient extends EventEmitter { + return final; + } + ++ async _isSynced() { ++ this._synced ||= ++ Services.appinfo.appBuildID === (await this.db.getMetadata())?.app_build_id; ++ return this._synced; ++ } ++ + /** + * Synchronize the local database with the remote server. + * +-- +2.30.0 + + +From 89dc912d08b7d4eed113439efa17dce57eda106e Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 18:53:51 +0200 +Subject: [PATCH 09/13] Client: deep compare records if timestamps match + +When the list of current / updated / deleted records is generated, their +modification timestamps are compared to detect the updates. + +Although in practice this is unlikely to happen, in theory the +timestamp of some older record received from Remote Settings can match +with the modified record in the dump. Although JSON processing script +makes sure to add unique timestamps to each of the modified records, +it's still possible to update dumps manually and simply forget to update +timestamps. So serialize the records and compare them as strings to be +on the safe side. This should happen only once after upgrading to each +new version of the application, so is not likely to introduce any +noticeable performance issues. +--- + services/settings/RemoteSettingsClient.jsm | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm +index 253251823a..b45a55919c 100644 +--- a/services/settings/RemoteSettingsClient.jsm ++++ b/services/settings/RemoteSettingsClient.jsm +@@ -13,6 +13,7 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + + XPCOMUtils.defineLazyModuleGetters(this, { + AppConstants: "resource://gre/modules/AppConstants.jsm", ++ CanonicalJSON: "resource://gre/modules/CanonicalJSON.jsm", + ClientEnvironmentBase: + "resource://gre/modules/components-utils/ClientEnvironment.jsm", + Database: "resource://services-settings/Database.jsm", +@@ -1022,7 +1023,10 @@ class RemoteSettingsClient extends EventEmitter { + const old = oldById.get(r.id); + if (old) { + oldById.delete(r.id); +- if (r.last_modified != old.last_modified) { ++ if ( ++ r.last_modified != old.last_modified || ++ CanonicalJSON.stringify(r) != CanonicalJSON.stringify(old) ++ ) { + syncResult.updated.push({ old, new: r }); + } + } else { +-- +2.30.0 + + +From 5f4207fd155c2dae802522070627c34ced6a192e Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 19:01:39 +0200 +Subject: [PATCH 10/13] Client: delete more data on cleanup + +When the client detects the local data is invalid (i.e. it came from +real Remote Settings and can have unwanted records), delete not only +the records, but also the attachments that came with them, because they +too can be problematic. And last check time preference, because it's not +useful anyway when remote-settings.js doesn't do any polling for changes. + +Note that attachments should be deleted before the records, because the +logic gets the data about the attachments from those records. +--- + services/settings/RemoteSettingsClient.jsm | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm +index b45a55919c..3dbd972f87 100644 +--- a/services/settings/RemoteSettingsClient.jsm ++++ b/services/settings/RemoteSettingsClient.jsm +@@ -221,7 +221,10 @@ class AttachmentDownloader extends Downloader { + async deleteAll() { + let allRecords = await this._client.db.list(); + return Promise.all( +- allRecords.filter(r => !!r.attachment).map(r => this.delete(r)) ++ allRecords.filter(r => !!r.attachment).map(r => { ++ this.delete(r); ++ this.deleteCached(r.id); ++ }) + ); + } + } +@@ -982,7 +985,7 @@ class RemoteSettingsClient extends EventEmitter { + // Signature failed, clear local DB because it contains + // bad data (local + remote changes). + console.debug(`${this.identifier} clear local data`); +- await this.db.clear(); ++ await this._clearAll(); + // Local data was tampered, throw and it will retry from empty DB. + console.error(`${this.identifier} local data was corrupted`); + throw new CorruptedDataError(this.identifier); +@@ -1004,7 +1007,7 @@ class RemoteSettingsClient extends EventEmitter { + // _importJSONDump() only clears DB if dump is available, + // therefore do it here! + if (imported < 0) { +- await this.db.clear(); ++ await this._clearAll(); + } + } + } +@@ -1044,6 +1047,12 @@ class RemoteSettingsClient extends EventEmitter { + return syncResult; + } + ++ async _clearAll() { ++ await this.attachments.deleteAll(); ++ await this.db.clear(); ++ Services.prefs.clearUserPref(this.lastCheckTimePref); ++ } ++ + /** + * Fetch information from changeset endpoint. + * +-- +2.30.0 + + +From b3c304e2fe95d0a75c524a5aa96a68a34ce2ae34 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 19:07:56 +0200 +Subject: [PATCH 11/13] Client: remove comparison of collection timestamps + +In case if the cached data that came from real Remote Settings server +(before the upgrade to local-only setup) has collection timestamp, that +is newer than the packaged local dump, then this comparison logic can +lead to early return of old data, skipping the integrity checking and +necessary cleanup. So remove the checks. +--- + services/settings/RemoteSettingsClient.jsm | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm +index 3dbd972f87..d319a77c27 100644 +--- a/services/settings/RemoteSettingsClient.jsm ++++ b/services/settings/RemoteSettingsClient.jsm +@@ -917,14 +917,9 @@ class RemoteSettingsClient extends EventEmitter { + updated: [], + deleted: [], + }; +- // If data wasn't changed, return empty sync result. +- // This can happen when we update the signature but not the data. + console.debug( + `${this.identifier} local timestamp: ${localTimestamp}, remote: ${remoteTimestamp}` + ); +- if (localTimestamp && remoteTimestamp < localTimestamp) { +- return syncResult; +- } + + const start = Cu.now() * 1000; + await this.db.importChanges(metadata, remoteTimestamp, remoteRecords, { +-- +2.30.0 + + +From 804007d2861f829315e575660d47b9a4c430d151 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 19:15:44 +0200 +Subject: [PATCH 12/13] Attachments: load only from dump and drop cached + +--- + services/settings/Attachments.jsm | 35 +++++++------------------------ + 1 file changed, 8 insertions(+), 27 deletions(-) + +diff --git a/services/settings/Attachments.jsm b/services/settings/Attachments.jsm +index 0eeb632799..eaa7db8c81 100644 +--- a/services/settings/Attachments.jsm ++++ b/services/settings/Attachments.jsm +@@ -143,10 +143,11 @@ class Downloader { + checkHash, + attachmentId = record?.id, + useCache = false, +- fallbackToCache = false, + fallbackToDump = false, + } = options || {}; + ++ const fallbackToCache = false; ++ + if (!useCache) { + // For backwards compatibility. + // WARNING: Its return type is different from what's documented. +@@ -206,6 +207,7 @@ class Downloader { + const newBuffer = await this.downloadAsBytes(record, { + retries, + checkHash, ++ dumpInfo, + }); + const blob = new Blob([newBuffer]); + if (useCache) { +@@ -241,7 +243,7 @@ class Downloader { + } + + try { +- return { ...(await cacheInfo.getResult()), _source: "cache_fallback" }; ++ await this.cacheImpl.delete(attachmentId); + } catch (e) { + // Failed to read from cache, e.g. IndexedDB unusable. + Cu.reportError(e); +@@ -278,7 +280,7 @@ class Downloader { + * @returns {String} the absolute file path to the downloaded attachment. + */ + async downloadToDisk(record, options = {}) { +- const { retries = 3 } = options; ++ const retries = 0; + const { + attachment: { filename, size, hash }, + } = record; +@@ -335,31 +337,10 @@ class Downloader { + */ + async downloadAsBytes(record, options = {}) { + const { +- attachment: { location, hash, size }, +- } = record; +- +- const remoteFileUrl = (await this._baseAttachmentsURL()) + location; ++ dumpInfo = new LazyRecordAndBuffer(() => this._readAttachmentDump(attachmentId)) ++ } = options; + +- const { retries = 3, checkHash = true } = options; +- let retried = 0; +- while (true) { +- try { +- const buffer = await this._fetchAttachment(remoteFileUrl); +- if (!checkHash) { +- return buffer; +- } +- if (await RemoteSettingsWorker.checkContentHash(buffer, size, hash)) { +- return buffer; +- } +- // Content is corrupted. +- throw new Downloader.BadContentError(location); +- } catch (e) { +- if (retried >= retries) { +- throw e; +- } +- } +- retried++; +- } ++ return (await dumpInfo.getResult()).buffer; + } + + /** +-- +2.30.0 + + +From 4ee3b715e10a5f9a5ef7830b047ae7f64e55e5f4 Mon Sep 17 00:00:00 2001 +From: grizzlyuser +Date: Wed, 30 Dec 2020 19:22:20 +0200 +Subject: [PATCH 13/13] Disable CRLite entirely for now + +It's designed to fetch the data from Remote Settings. One of the main +selling points is that new revocations can be pushed to the clients +within minutes. That won't work with local-only setup. Although (some?) +of the JSON dumps for it are in place, obviously the updates won't +happen that fast. + +Right now CRLite doesn't enforce anything, and works just for telemetry +collection (which is hopefully disabled anyway). So disable the +preference right in the source code, so that the patch fails to apply +when the upstream decides to set it to enforcing mode by default. + +The solution with CRLite is up for discussion. If necessary, it's +possible to make clients for blessed collections to communicate to real +Remote Settings server. For example, for collections related to +certificate revocations. +--- + modules/libpref/init/all.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js +index 907e8ebcef..65db6bd04c 100644 +--- a/modules/libpref/init/all.js ++++ b/modules/libpref/init/all.js +@@ -186,7 +186,7 @@ pref("security.pki.distrust_ca_policy", 2); + #if defined(NIGHTLY_BUILD) + pref("security.pki.crlite_mode", 2); + #else +-pref("security.pki.crlite_mode", 1); ++pref("security.pki.crlite_mode", 0); + #endif + + // Represents the expected certificate transparency log merge delay (including +-- +2.30.0 + diff --git a/libre/iceweasel/9002-misc-libre.patch b/libre/iceweasel/9002-misc-libre.patch new file mode 100644 index 000000000..124ff00f2 --- /dev/null +++ b/libre/iceweasel/9002-misc-libre.patch @@ -0,0 +1,387 @@ +diff --git a/browser/app/permissions b/browser/app/permissions +index 991284081d..888cc811ce 100644 +--- a/browser/app/permissions ++++ b/browser/app/permissions +@@ -15,11 +15,5 @@ origin uitour 1 https://support.mozilla.org + origin uitour 1 about:home + origin uitour 1 about:newtab + +-# XPInstall +-origin install 1 https://addons.mozilla.org +- + # Remote troubleshooting + origin remote-troubleshooting 1 https://support.mozilla.org +- +-# addon install +-origin install 1 https://fpn.firefox.com +diff --git a/browser/components/preferences/sync.inc.xhtml b/browser/components/preferences/sync.inc.xhtml +index 7d37d26..4ebbc06 100644 +--- a/browser/components/preferences/sync.inc.xhtml ++++ b/browser/components/preferences/sync.inc.xhtml +@@ -35,22 +35,6 @@ + + + +- + + + +diff --git a/browser/locales/en-US/browser/policies/policies-descriptions.ftl b/browser/locales/en-US/browser/policies/policies-descriptions.ftl +index dabfadc..3ce732e 100644 +--- a/browser/locales/en-US/browser/policies/policies-descriptions.ftl ++++ b/browser/locales/en-US/browser/policies/policies-descriptions.ftl +@@ -96,7 +96,7 @@ policy-ExtensionSettings = Manage all aspects of extension installation. + + policy-ExtensionUpdate = Enable or disable automatic extension updates. + +-policy-FirefoxHome = Configure Firefox Home. ++policy-FirefoxHome = Configure Iceweasel Home. + + policy-FlashPlugin = Allow or deny usage of the Flash plugin. + +diff --git a/browser/locales/en-US/browser/preferences/preferences.ftl b/browser/locales/en-US/browser/preferences/preferences.ftl +index 1b29e8d..6f7566c 100644 +--- a/browser/locales/en-US/browser/preferences/preferences.ftl ++++ b/browser/locales/en-US/browser/preferences/preferences.ftl +@@ -550,7 +550,7 @@ home-restore-defaults = + # "Firefox" should be treated as a brand and kept in English, + # while "Home" and "(Default)" can be localized. + home-mode-choice-default = +- .label = Firefox Home (Default) ++ .label = Iceweasel Home (Default) + + home-mode-choice-custom = + .label = Custom URLs… +@@ -577,10 +577,10 @@ choose-bookmark = + .label = Use Bookmark… + .accesskey = B + +-## Home Section - Firefox Home Content Customization ++## Home Section - Iceweasel Home Content Customization + +-home-prefs-content-header = Firefox Home Content +-home-prefs-content-description = Choose what content you want on your Firefox Home screen. ++home-prefs-content-header = Iceweasel Home Content ++home-prefs-content-description = Choose what content you want on your Iceweasel Home screen. + + home-prefs-search-header = + .label = Web Search +@@ -714,16 +714,6 @@ sync-signedout-account-signin2 = + .label = Sign in to { -sync-brand-short-name }… + .accesskey = i + +-# This message contains two links and two icon images. +-# `` - Android logo icon +-# `` - Link to Android Download +-# `` - iOS logo icon +-# `` - Link to iOS Download +-# +-# They can be moved within the sentence as needed to adapt +-# to your language, but should not be changed or translated. +-sync-mobile-promo = Download Firefox for Android or iOS to sync with your mobile device. +- + ## Firefox Account - Signed in + + sync-profile-picture = +diff --git a/browser/locales/generic/profile/bookmarks.html.in b/browser/locales/generic/profile/bookmarks.html.in +index 2d3c7b4..00221d3 100644 +--- a/browser/locales/generic/profile/bookmarks.html.in ++++ b/browser/locales/generic/profile/bookmarks.html.in +@@ -1,15 +1,15 @@ + #filter substitution + #include @BOOKMARKS_INCLUDE_PATH@ + +-#define mozilla_icon data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E %3Cpath d='M0 0h16v16H0z'/%3E %3Cpath d='M13.994 10.356H15V12h-3.171V7.741c0-1.308-.435-1.81-1.29-1.81-1.04 0-1.46.737-1.46 1.8v2.63h1.006V12H6.918V7.741c0-1.308-.435-1.81-1.291-1.81-1.039 0-1.459.737-1.459 1.8v2.63h1.441V12H1v-1.644h1.006V6.079H1V4.435h3.168v1.139a2.507 2.507 0 0 1 2.3-1.29A2.452 2.452 0 0 1 8.931 5.91 2.535 2.535 0 0 1 11.4 4.284 2.448 2.448 0 0 1 14 6.9v3.458z' fill='%23fff'/%3E %3C/svg%3E ++#define parabola_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABL0lEQVQ4jWNgoCcoq16VU1GzygnEBtEVDWuV8GooKFuhWVG3uiM3d5UokG4qr1szAaa5vGbVt4ralacwNDU0rGIrr10VBVG0+lxhwyqVsqqVtRW1q6eD5IvL19oB2V+B+D9QzQu4xtDQVZylVavygRKHqurWOlbUrknKK12qWlCwWLK8elUFA8N/xvLy5VYVtas+gzWDDVi9E2QjT1XdcufymjWpQJt1cXmnvHwVP1DzR7hmIC6vW+kOtpnYQKysW30arrlm9RVi9cFBRfXKJTADympWJZNsQFnN6rUQA1adAQU2SZqBXmUGBtozUDiU1qxQJtl2oCY3kO2l1avCSdYMAsBAWwyM2plkaS4p6eYGOv1YQ0MDB1kGlFWuDChuWKZBlmYQqK5eJU22ZkIAAEIlnQZQkzITAAAAAElFTkSuQmCC + +-#define firefox_icon data:image/png;base64,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 ++#define fsf_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAADG0lEQVQoFQEQA+/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQECAAAAAAAAAAAAAAAAAAAA2qOp7tTXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAP///wAAAAAAAOCyt7pUXQcSEgcQDwAAAP///wAAAAAAAAD//x9NSDqNhQEBAQQAAAAAAAAAAAAAAAAQJiQGDQ0aPToZPjoAAQEAAAAAAAAAAAABAQEpZV4AAAAAAAAAAAAA////////////////pSIv05KZ////////////////////////////////AAAAAQAAAP///6krNwAAAAAAAPHc3ggSEQcSEQAAAAAAAAAAABY3NEGelQAAAAAAAAEBAQEAAAD///+YARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDg1g690CBgYAAAABAQEEAAAAAAAAS7etAAAAAAAAwGVtHklFIlJOAAAAAAAAAAAAAAAA+/X2BwYGAAAAAAAABAAAAAAAAB1IQwAAAAAAAAYNDBAmJB1IQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAgL//v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAQEB//7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAECAv/+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////////////cqK3qzM////////////////////////////////8AAAABAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGuLjDf9F8oBAAAAAElFTkSuQmCC + +-#define bugzilla_icon data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnYCL7J0pY9wwETY9kYEM9AAAAAEBAYAhVVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1bjTOS1Vb/wAA2/8JEqT/Q0g8kQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJnMqoiJtJ/0haST/NEkp/yQnW/8AAPD8AAHY/RsgP/JZUI+GKitih4ObUEAAAAAAAAAAAAAAAAAAAAAAKnouwip5Lv9ooW//a6Jz/y9GIv8JBXb/AADO/gEBvf8AAK7/FRJp/z9BfP8iLGj1AAAAAAAAAAAAAAAAL4YzwiB0I/+UwJ3/bK+C/02eZ/9CTjz/DBa1/wABxf8BAOj/AACp/w8Oc/sJCv//EhCN9AAAAAAAAAAANJA6iC2MMv93tYL/TZ5U/3mzjP9NoWr/NEss/wYIU/8CBOn/ARCX/wwNqP0TD6X/Cgyex5qacDAAAAAAAAAAADKUN/ZirWj/d76R/0SgXf9Ln1P/eLSM/1mda/8rOkb/CQiD/wMQvf8UEnT/MTAt4P//MwUhZyN8AAAAAAAAAAAznDf5UqlZ/228jP9NqnD/Qp9c/0yiVP+Dv5b/VaVw/0VxXf9PZXD/S3pQ/y54Nf8jcCf/I2wn/wAAAAA0ozjIM6E4/zOeOP+Uz6z/XLR+/06scv9BoV3/TqZX/4XBmP9XqHP/hr6Z/yp+Lf8leSr1JXUqbQAAAAA3rTz7Nqo7/zWmOqM3oz7rUK1W/43Mpf9etYD/T61z/0KjXf9Rqln/msup/46/lf8pgy7/JFg6sAAAAAAAAAAAOK8+8jqvOiMAAAAAAAAAADSlOv85pT//kM6o/2K5hP9Ysnv/YLJ2/ziXPv8piS3/V6Ri/yZQQ9wAAAAAAAAAAAAAAAAAAAAAAAAAADetP0E2qzz/OKg98UWsS/+e1K3/pNe4/4XDjv8ojy3/T7df/5fIqv8sjTH/K4kw/yqFLv8AAAAAAAAAAAAAAAA4sT3xN7A8+QAAAAA4qz3yNag6/zSlOf80oTn/csJ+/6/jwv9fjHj/MmRMdQAAAAAAAAAAAAAAAAAAAAAAAAAAOrdA/zm0QHQAAAAAAAAAADasO/k2qTvuRX5lpjqGT/gznDr/O3FXigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADq9QiMAAAAAAAAAAAAAAAA4sj7/Nq09s0uOaSI1qTplM6U68wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrc//zu0P0EAAAAAOK4+UjWsPPgAAAAAAAAAAAAAAAAAAAAA/48AAP8HAAD4AQAA8AAAAOAAAADAAQAAwAMAAMAAAACAAwAAAAMAAHADAADwAAAA5AcAAO4HAAD+bwAA/u8AAA== ++#define gnu_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAGFBMVEVFRUV+fn6mpqa/v7/Ozs7Y2Njg4OD8/Pwuhn+TAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEQAACxEBf2RfkQAAAAd0SU1FB9MBDhQ6Gd8s57cAAAEVSURBVBgZBcGxVtpgGADQL9gHSBzqSognzMixmcWWzB6pmRHhnyvku6/fewMAIPD3TwHmQxHs6vr+A16bphNum/vV0x429201hcPjAGBTDZGnR/Kw1U181+u4HXvOdSxjUcztz8jjg1xGVBG9XPYxt4PviKiaWLg168iXtbrq+mPT1utjNcR1U73deRnL43M2sRgj3+oYs8uL3rLphPd2QWmHbMu/VS/cnk6UdtSW657g9yBlcZ0UAkUWzPvyRaAYmfd+HT4IZtvC59ibEJxXiqJjQpBpNEufBYE0McoOAunGhRMEFIPc7h4goJigQEBxk8u7AgEpL3IEAUZfcgAByGFXQACm5+4MAuB19QMEgI8CAgDgP4rivVgoKP6ZAAAAAElFTkSuQmCC + +-#define mdn_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAABgElEQVR4AWPouPiRpmjUAjgatSBj+aG0OVuyVhymsgWl2y475zXySikwwIC4lpFDVk3avG0BrXP9mmeV7bhCvgXuxW3M7JwMeAGfpByZFpjHFzAQB2KmrSfZAtuMKgaiAZ+MUuLc7SRY4FbYwkA60HAJiJm8uubQAwIWeJV1MlAAOAREHDJrcFqQMG+ngIK6oKyykLwqAyMjeXZwiUjgtKD+yGMIwyGzmoGBTAs4hcXrgObgi4OiVkpCiUtYov7YU5wW1B194t0ww69ldvjktYouwWRYIGdkQ1Q+iJ28hp2Xn7B5zKzIPAlNw6S52wlbkL3mJJecOq+CBqeIJC6TjUJTMlcdz9lwLmriSuPgJBVbj/D+5SSXRequQVhNN4nIoEJhV77jKgs7B6bprJw85XtuU8GCpNlbSS3gSA4ii4QiTAvElDWpWeH41kxg5eZDSypUrtFKd1zTcA1EpHRDS5rUyQEts+VN7JjYOGR0TWhY6RdsOhc/Y9NoswUJjVoAAE+h555Rgcg2AAAAAElFTkSuQmCC ++#define libreplanet_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACfElEQVQ4jZXTS0hUcRTH8f+9M3fGd0gRRq1a2bZdBAotWtS6TQtB6IHgKzRy0UKqjRaRCAq+R21MDMsUR83JR5fJxhmaK2lzsWAWw+ToEHJxgnFm7reFIgza66z/58P/dzhHcESZpsluIsFPwyCVSmGa5lHPEEIIkdGYTqPPvqUlP4fK8nJ2DINYNEq71YJ3fv4QlAGkUynaj+VRdfUK7580M52rEN/ZYWNjg2GrjEMSPFXsmOn0YcA0TZ4V5tNZUkJTTTWfJiZIJhJ8U1VczwcZs0o4JUHzufM0ZGcf/OQASCaTxGIxDMNA00P8iEbpuXyJ8Tw77+wWJhWZQYuVbiHoFIKwpmUC4XCYzc1NDMMgHo9z8+IFvl6/xsf7D9ArbjOpyAxLEt1C0CUErfvJDwBd14lEImxvb/N9fR1fgY3egmyWsq0sO/poUyw4pb3mLiFolyRM09wDEokEfr+fUChEJBJh4HgBS7kKn92zLIy9ZriqklFZwiEEHfsRRp1O0un0HpDa3cU9M8PKygp3Tp5AzbKgZlmYt1uYtkn02q0MyYKmnBxWNI27Nhtut5tkMrkHmKZJbWkpqqryQpFxKTJTisyEVeaVRWJIlqgpLuZRWRkejwe/34/P58ucwZvWVhYXF5l2uejIzeHGqbM4ZYmB/dy1hUV8mJpibm4On8/H1tbW4T1YXV3F6/WysLDA5Pg4nfsDe5yfz8OiIjweD5qmEQwGf7/KwWCQtbU1NE2jRZbpEoI2SWKqr49lVUXX9T/fAkAgEKC/e5SW6mo6hKD+zGn6e0bw+/x/PyaA9S/rvOwfobGukfpbddyraMDR7iCwHPg34H9KCCF+Abts3KCj/p6aAAAAAElFTkSuQmCC + +-#define addon_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAABOFBMVEUAAAAAzdwAydcAyNgA//8AzOYAydcAyNgAyNgA2NgAytoAzNkAytgAydgA29sA0egAyNgAyNgA//8AyNgAydgA//8Ay9cAydcAytkAz90Ay9gA1eoAydgAytsAyNgAytgAydkAydgAydgAyNgAydgAyNcAy9oAydgA//8AytsAy9kAytkAyNgAydgAydkAy9kAzP8AydgAydgAydgAz98AzN0AyNcAyNsAydcAydgAydgAydcAytgAytcAydcAydcAytcAydcAyNcAydcAy9gAztgAydcAydgAzOAAydcAyNgAyNgAytwAyNcAyNgAy9wAyNcAyNcAyNgAydgAyNcAydcAydgA0uEAydkAyNgAyeQA4+MAyNgAydkAzN0AyNsA1f8AyNgAydgAydcA1eMAydgAydcAyNdj6PGJAAAAZ3RSTlMAJFpBAQqm8qwNPiiPygcLv8QEw5cDQMA1JU4MwiuDbl/+6+m4+0XLAj9KePz9cjYFvervEA/IDsfFr+xcgeaOYIDo+ica1OMZ9bXlHe73LM3M35itxs8Rf5ATCbFeHjgGttC5ErzO3WvwaAAAAWxJREFUOMt9kudCwkAQhFcITQWCoaggiBqxoaixYUVsYMMGCmLXff838LIXCJAL84fvmCHsTg4AYMDhlIDkcnu8Po4w6BjiIA0joj+gY1BmGKLEiMIwHNFR9xGjuh8jpMQoYZjRGBGOA8QTHDEUB4hynABwcEqCT8GW2DNSnCYBnJzSoSk0NT2jcphlM/rRXpk5NkRgfmFxSWBml6MrOWNlWBUEEmDKtyYIrGttP66gSP4Nww8mUKzNLd5/zHaJbb1Tl9xnzR2WcGM/5QE8BLvJvf0Dc4HDo8IxUVECL5Vywv7s9Mzwz/WLcFHSsWy8w0sa9+qa/JtbOlUY3mnGLbjnCz9Q4JEfnhCrNb5nXi3w754p8MIPKVWpt6psGJ+vFJBbBUO3GlozzYdsSmCV1NlntiTnegNvPQ29Wx7h7fKrEUvg47PD/6oLpgh8m7//AZEav4b/J/bbb75SAzvR3crY+6y8fLGsQV9ZSvwHF4LQIhDjT+8AAAAASUVORK5CYII= ++#define hnode_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABgElEQVQ4jaXRz2uSARzHcb0vlRGEzTVWISU1BVkFYTIyjNK1pKcxHA+yhWMWIamHYikFgpoLIi9jwegi3QbL9SzdLmMbM9J+DkJBgm5RDvEPeHeQHOyQz0OH9+V7ePGBr0pqpPmfVPsP8a0AR4MnMEwf48x9K0s/E8oAY9iEMOvD+8yP2qVjrhhRBnSN61n5sIpULqC+pGHh8wNlgEY8jPQXcGh4VXukDND5evYAl46odIuXtYdKAANSudAChO52/XeMZMohecCbcoGdH99Y+7LO72adT9+/4nh8nYOjBl7/SsoB8gBkpHk8T0S2K++pN3fRin3cfnFDHvCuWkI9rEMvHGEo5gbAHnXhnLF1BpZLeRaLOVT2A8Q3A5wMngXgWtKLxX9KPqC+rCWQvYkpeK4NWKcGOgO50ts2MJJ0cPreeQDciTHMchZYIhcwh2wcuqjn+ccwGm9v6wsTxxn0dVgQXZ7Ek3Agpq6QrcaQGmmebtxFSDkRU1fJVmL/BpT2ByV/3eDMhinRAAAAAElFTkSuQmCC + +@@ -21,29 +21,21 @@ +

+

@bookmarks_toolbarfolder@

+
@bookmarks_toolbarfolder_description@ +-#ifndef NIGHTLY_BUILD +
+-

@getting_started@
++

Parabola GNU/Linux-libre
+
+-

@firefox_heading@

++

Parabola GNU/Linux-libre

+

+-

@firefox_help@ +-
@firefox_customize@ +-
@firefox_community@ +-
@firefox_about@ ++
Parabola GNU/Linux-libre ++
Parabola GNU/Linux-libre Packages ++
Parabola GNU/Linux-libre Wiki ++
Parabola GNU/Linux-libre Labs +
+-#else +-
+-

@firefox_community@ +-
+-

@nightly_heading@

++

Free Software Foundation

+

+-

@nightly_blog@ +-
@bugzilla@ +-
@mdn@ +-
@nightly_tester_tools@ +-
@crashes@ +-
@planet@ ++
Free Software Foundation ++
The GNU Operating System and the Free Software Movement ++
LibrePlanet ++
h-node +
+-#endif +
+diff --git a/devtools/startup/aboutdevtools/aboutdevtools.xhtml b/devtools/startup/aboutdevtools/aboutdevtools.xhtml +index 5b0709e..38ea275 100644 +--- a/devtools/startup/aboutdevtools/aboutdevtools.xhtml ++++ b/devtools/startup/aboutdevtools/aboutdevtools.xhtml +@@ -89,19 +89,6 @@ + + +- +-
+- +- +-
+ + + +diff --git a/devtools/startup/locales/en-US/aboutDevTools.ftl b/devtools/startup/locales/en-US/aboutDevTools.ftl +index db2146d..e02ab58 100644 +--- a/devtools/startup/locales/en-US/aboutDevTools.ftl ++++ b/devtools/startup/locales/en-US/aboutDevTools.ftl +@@ -3,18 +3,18 @@ + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + + head-title = About Developer Tools +-enable-title = Enable Firefox Developer Tools +-enable-inspect-element-title = Enable Firefox Developer Tools to use Inspect Element ++enable-title = Enable Iceweasel Developer Tools ++enable-inspect-element-title = Enable Iceweasel Developer Tools to use Inspect Element + enable-inspect-element-message = Examine and edit HTML and CSS with the Developer Tools’ Inspector. +-enable-about-debugging-message = Develop and debug WebExtensions, web workers, service workers and more with Firefox Developer Tools. ++enable-about-debugging-message = Develop and debug WebExtensions, web workers, service workers and more with Iceweasel Developer Tools. + enable-key-shortcut-message = You activated a Developer Tools shortcut. If that was a mistake, you can close this Tab. + enable-menu-message = Perfect your website’s HTML, CSS, and JavaScript with tools like Inspector and Debugger. +-enable-common-message = Firefox Developer Tools are disabled by default to give you more control over your browser. ++enable-common-message = Iceweasel Developer Tools are disabled by default to give you more control over your browser. + enable-learn-more-link = Learn more about Developer Tools + enable-enable-button = Enable Developer Tools + enable-close-button = Close this Tab + +-welcome-title = Welcome to Firefox Developer Tools! ++welcome-title = Welcome to Iceweasel Developer Tools! + newsletter-title = Mozilla Developer Newsletter + newsletter-message = Get developer news, tricks and resources sent straight to your inbox. + newsletter-email-placeholder = +@@ -24,8 +24,6 @@ newsletter-subscribe-button = Subscribe + newsletter-thanks-title = Thanks! + newsletter-thanks-message = If you haven’t previously confirmed a subscription to a Mozilla-related newsletter you may have to do so. Please check your inbox or your spam filter for an email from us. + +-footer-title = Firefox Developer Edition +-footer-message = Looking for more than just Developer Tools? Check out the Firefox browser that is built specifically for developers and modern workflows. + footer-learn-more-link = Learn more + + features-learn-more = Learn more +diff --git a/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl b/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl +index edd871b..77870fe 100644 +--- a/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl ++++ b/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl +@@ -7,7 +7,7 @@ addons-window = + addons-page-title = Add-ons Manager + + search-header = +- .placeholder = Search addons.mozilla.org ++ .placeholder = Search www.parabola.nu/packages + .searchbuttonlabel = Search + + search-header-shortcut = +@@ -482,7 +482,7 @@ theme-heading-search-label = Find more themes + + default-heading-search-label = Find more add-ons + addons-heading-search-input = +- .placeholder = Search addons.mozilla.org ++ .placeholder = Search www.parabola.nu/packages + + addon-page-options-button = + .title = Tools for all add-ons +diff --git a/browser/components/newtab/lib/OnboardingMessageProvider.jsm b/browser/components/newtab/lib/OnboardingMessageProvider.jsm +index 02eb150..abb3af9 100644 +--- a/browser/components/newtab/lib/OnboardingMessageProvider.jsm ++++ b/browser/components/newtab/lib/OnboardingMessageProvider.jsm +@@ -270,7 +270,7 @@ const ONBOARDING_MESSAGES = () => [ + action: { type: "OPEN_PRIVATE_BROWSER_WINDOW" }, + }, + }, +- targeting: "'dynamic' in trailheadTriplet", ++ targeting: "trailheadTriplet in ['supercharge', 'static'] || 'dynamic' in trailheadTriplet", + trigger: { id: "showOnboarding" }, + }, + { +@@ -314,7 +314,7 @@ const ONBOARDING_MESSAGES = () => [ + }, + }, + targeting: +- "trailheadTriplet in ['supercharge', 'static'] || ('dynamic' in trailheadTriplet && sync.mobileDevices < 1)", ++ "false", + trigger: { id: "showOnboarding" }, + }, + { +diff --git a/browser/locales/en-US/chrome/browser-region/region.properties b/browser/locales/en-US/chrome/browser-region/region.properties +index 4c4ea76..e0f2880 100644 +--- a/browser/locales/en-US/chrome/browser-region/region.properties ++++ b/browser/locales/en-US/chrome/browser-region/region.properties +@@ -9,16 +9,3 @@ + # don't make any spelling errors here. + gecko.handlerService.defaultHandlersVersion=4 + +-# The default set of protocol handlers for mailto: +-gecko.handlerService.schemes.mailto.0.name=Yahoo! Mail +-gecko.handlerService.schemes.mailto.0.uriTemplate=https://compose.mail.yahoo.com/?To=%s +-gecko.handlerService.schemes.mailto.1.name=Gmail +-gecko.handlerService.schemes.mailto.1.uriTemplate=https://mail.google.com/mail/?extsrc=mailto&url=%s +- +-# The default set of protocol handlers for irc: +-gecko.handlerService.schemes.irc.0.name=Mibbit +-gecko.handlerService.schemes.irc.0.uriTemplate=https://www.mibbit.com/?url=%s +- +-# The default set of protocol handlers for ircs: +-gecko.handlerService.schemes.ircs.0.name=Mibbit +-gecko.handlerService.schemes.ircs.0.uriTemplate=https://www.mibbit.com/?url=%s +diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js +index 2588a53cf2..e818b254d2 100644 +--- a/browser/app/profile/firefox.js ++++ b/browser/app/profile/firefox.js +@@ -1726,15 +1726,15 @@ pref("browser.contentblocking.report.monitor.enabled", true); + pref("browser.contentblocking.report.proxy.enabled", false); + + // Disable the mobile promotion by default. +-pref("browser.contentblocking.report.show_mobile_app", true); ++pref("browser.contentblocking.report.show_mobile_app", false); + + // Enable the vpn card by default. +-pref("browser.contentblocking.report.vpn.enabled", true); ++pref("browser.contentblocking.report.vpn.enabled", false); + // Only show vpn card to certain regions. Comma separated string of two letter ISO 3166-1 country codes. + pref("browser.contentblocking.report.vpn_regions", "us,ca,nz,sg,my,gb"); + // Comma separated string of mozilla vpn supported platforms. + pref("browser.contentblocking.report.vpn_platforms", "win"); +-pref("browser.contentblocking.report.hide_vpn_banner", false); ++pref("browser.contentblocking.report.hide_vpn_banner", true); + pref("browser.contentblocking.report.vpn_sub_id", "sub_HrfCZF7VPHzZkA"); + + pref("browser.contentblocking.report.monitor.url", "https://monitor.firefox.com/?entrypoint=protection_report_monitor&utm_source=about-protections"); +@@ -1745,12 +1745,12 @@ pref("browser.contentblocking.report.monitor.home_page_url", "https://monitor.fi + pref("browser.contentblocking.report.manage_devices.url", "https://accounts.firefox.com/settings/clients"); + pref("browser.contentblocking.report.endpoint_url", "https://monitor.firefox.com/user/breach-stats?includeResolved=true"); + pref("browser.contentblocking.report.proxy_extension.url", "https://fpn.firefox.com/browser?utm_source=firefox-desktop&utm_medium=referral&utm_campaign=about-protections&utm_content=about-protections"); +-pref("browser.contentblocking.report.mobile-ios.url", "https://apps.apple.com/app/firefox-private-safe-browser/id989804926"); +-pref("browser.contentblocking.report.mobile-android.url", "https://play.google.com/store/apps/details?id=org.mozilla.firefox&referrer=utm_source%3Dprotection_report%26utm_content%3Dmobile_promotion"); +-pref("browser.contentblocking.report.vpn.url", "https://vpn.mozilla.org/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=about-protections-card"); +-pref("browser.contentblocking.report.vpn-promo.url", "https://vpn.mozilla.org/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=about-protections-top-promo"); +-pref("browser.contentblocking.report.vpn-android.url", "https://play.google.com/store/apps/details?id=org.mozilla.firefox.vpn&referrer=utm_source%3Dfirefox-browser%26utm_medium%3Dfirefox-browser%26utm_campaign%3Dabout-protections-mobile-vpn%26anid%3D--"); +-pref("browser.contentblocking.report.vpn-ios.url", "https://apps.apple.com/us/app/firefox-private-network-vpn/id1489407738"); ++pref("browser.contentblocking.report.mobile-ios.url", ""); ++pref("browser.contentblocking.report.mobile-android.url", ""); ++pref("browser.contentblocking.report.vpn.url", ""); ++pref("browser.contentblocking.report.vpn-promo.url", ""); ++pref("browser.contentblocking.report.vpn-android.url", ""); ++pref("browser.contentblocking.report.vpn-ios.url", ""); + + // Protection Report's SUMO urls + pref("browser.contentblocking.report.lockwise.how_it_works.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/password-manager-report"); +diff --git a/browser/components/protections/content/protections.ftl b/browser/components/protections/content/protections.ftl +index 5ac8a7b08c..fec81698e3 100644 +--- a/browser/components/protections/content/protections.ftl ++++ b/browser/components/protections/content/protections.ftl +@@ -18,7 +18,7 @@ get-vpn-link = Get { -mozilla-vpn-brand-name } + + vpn-title-subscribed = VPN: Subscribed + # Note This text is not being translated, and the
will need to be removed if or when it does get translated +-vpn-header-content-subscribed = Using the { -mozilla-vpn-brand-name } encrypts all your traffic and hides your location — on up to 5 devices. Get the most from your subscription — add it from
the Google Play Store or Apple App Store. ++vpn-header-content-subscribed = Using the { -mozilla-vpn-brand-name } encrypts all your traffic and hides your location — on up to 5 devices. + + vpn-banner-header = Protection that extends beyond the browser + # Note This text is not being translated, and the
will need to be removed if or when it does get translated +diff --git a/browser/components/protections/content/protections.html b/browser/components/protections/content/protections.html +index e33c814f62..5698f2b3e9 100644 +--- a/browser/components/protections/content/protections.html ++++ b/browser/components/protections/content/protections.html +@@ -303,8 +303,6 @@ + +

+

+- +- +

+ + +diff --git a/browser/components/protections/content/vpn-card.js b/browser/components/protections/content/vpn-card.js +index 2417f1a641..698c48ccc3 100644 +--- a/browser/components/protections/content/vpn-card.js ++++ b/browser/components/protections/content/vpn-card.js +@@ -23,22 +23,6 @@ export default class VPNCard { + vpnLink.addEventListener("click", () => { + this.doc.sendTelemetryEvent("click", "vpn_card_link"); + }); +- let androidVPNAppLink = document.getElementById( +- "vpn-google-playstore-link" +- ); +- androidVPNAppLink.href = RPMGetStringPref( +- "browser.contentblocking.report.vpn-android.url" +- ); +- androidVPNAppLink.addEventListener("click", () => { +- document.sendTelemetryEvent("click", "vpn_app_link_android"); +- }); +- let iosVPNAppLink = document.getElementById("vpn-app-store-link"); +- iosVPNAppLink.href = RPMGetStringPref( +- "browser.contentblocking.report.vpn-ios.url" +- ); +- iosVPNAppLink.addEventListener("click", () => { +- document.sendTelemetryEvent("click", "vpn_app_link_ios"); +- }); + + const vpnBanner = this.doc.querySelector(".vpn-banner"); + const exitIcon = vpnBanner.querySelector(".exit-icon"); diff --git a/libre/iceweasel/PKGBUILD b/libre/iceweasel/PKGBUILD index 7dfaf626a..08f9952e9 100644 --- a/libre/iceweasel/PKGBUILD +++ b/libre/iceweasel/PKGBUILD @@ -74,9 +74,9 @@ source=(https://archive.mozilla.org/pub/firefox/releases/$pkgver/source/firefox- 0001-Use-remoting-name-for-GDK-application-names.patch $pkgname.desktop) source+=(https://repo.parabola.nu/other/iceweasel/${pkgname}_${_brandingver}-${_brandingrel}.branding.tar.xz{,.sig} - libre.patch - libre-0001-always-sync-remote-settings-with-local-dump.patch - libre-process-json-files.py + 9001-always-sync-remote-settings-with-local-dump.patch + 9002-misc-libre.patch + process-json-files.py vendor.js.in) source_armv7h=(arm.patch build-arm-libopus.patch) @@ -86,10 +86,10 @@ sha256sums=('92bfd518d4f9760c897388a8e06130b171c1c43524d8af181add9daac2be7b37' 'SKIP' '8b236bbf3ae5cb28d1dd742f543c0079fac06af5aa80bc2051defeba95f0ae21' '44be8e819b8334ed36e9410d62dbc6c16dd8f8329a191403bfdce3cf2e9181fc' - 'faf0faa5cc318515880e1c9854938f73e586b590c9696e95db323eea65d67a77' + '12c2c1a9e71a83fb0afa0c7baa2b4567796cff9b678a2f8c3ce7cdbe2c721357' 'SKIP' + '2a76ef07190ed545510c638a2491409c27af9bb0c90146924074859cb107cedd' 'e4fc091da84f75f701e1f3e336a8d42b746075caf7cb5f23dbb4d8fdd0ac4708' - '926082110e92bdc8ca53b930f4717a5294b64f6ebcc4d22d46d97088c5e862f0' 'e9d1b74971d58c5b860601bd8c0c11df332dab8be2f61f5d238ba50a5c4efdde' '714998c5fc379f54a66ff80a845b7880169cd5b4094b77b719a99d33b65c0940') sha256sums_i686=('2f0c81a38c4578f68f5456b618fe84a78974072821488173eb55e0e72287e353' @@ -260,6 +260,12 @@ END cp "${brandingdestdir}"/iceweasel_logo.svg "${brandingdestdir}"/content/aboutlogins.svg cp "${brandingdestdir}"/iceweasel_logo.svg "${brandingdestdir}"/content/about-logo.svg + # produce icons + for i in 16 22 24 32 48 64 128 192 256 384; do + rsvg-convert -w ${i} -h ${i} "${brandingsrcdir}"/branding/${pkgname}_icon.svg \ + -o "${brandingdestdir}"/default${i}.png + done + # custom new tab page # FIXME: the newtab page (aka "Start Page") has changed significantly # the new upstream start page ('activity-streams') is an add-on now @@ -277,40 +283,35 @@ END #install -m644 -t browser/extensions/onboarding/content/img -- \ # "${brandingsrcdir}/branding/watermark.svg" - # produce icons - for i in 16 22 24 32 48 64 128 192 256 384; do - rsvg-convert -w $i -h $i "${brandingsrcdir}/branding/${pkgname}_icon.svg" \ - -o "${brandingdestdir}/default$i.png" - done - # process default Top Sites and their icons local tippytopdir=browser/components/newtab/data/content/tippytop - find "${tippytopdir}" -type f \ - -not -name 'wikipedia-org*' \ - -not -name 'top_sites.json' \ - -exec rm -v {} \; + find ${tippytopdir} -type f \ + -not -name 'wikipedia-org*' \ + -not -name 'top_sites.json' \ + -exec rm -v {} \; for image in "${brandingsrcdir}"/tippytop/*.svg; do local outname=$(basename -s .svg "${image}") + local size=$(identify -format '%wx%h' ${tippytopdir}/images/wikipedia-org@2x.png) + local background=$( [[ "${outname}" == 'gnu' ]] && echo 'white' || echo 'none' ) + magick -density 300 ${image} \ + -gravity center -resize ${size} -extent ${size} \ + "${tippytopdir}/images/${outname}@2x.png" - local size=$(identify -format '%wx%h' "${tippytopdir}"/images/wikipedia-org@2x.png) - magick -density 300 $image -gravity center -resize $size -extent $size \ - "${tippytopdir}/images/${outname}@2x.png" - - local background='none' - if [[ $outname == 'gnu' ]]; then background='white'; fi size=256x256 - magick -density 300 -background $background $image -gravity center \ - -resize $size -extent $size -define icon:auto-resize=64,48,32,16 \ - "${tippytopdir}/favicons/${outname}.ico" + magick -density 300 -background ${background} ${image} \ + -gravity center -resize ${size} -extent ${size} \ + -define icon:auto-resize=64,48,32,16 \ + "${tippytopdir}/favicons/${outname}.ico" done # apply branding patches export QUILT_PATCHES="${brandingsrcdir}"/patches export QUILT_REFRESH_ARGS='-p ab --no-timestamps --no-index' export QUILT_DIFF_ARGS='--no-timestamps' - export QUILT_PC=$srcdir/.pc + export QUILT_PC="${srcdir}"/.pc quilt push -av + ## searchengines ## pushd browser/components/search/extensions @@ -324,10 +325,11 @@ END ! diff manifest.json.tmp ddg/manifest.json > /dev/null mv manifest.json.tmp ddg/manifest.json + # Delete unused search engine configs find -mindepth 1 -maxdepth 1 \ - -not -name ddg \ - -not -name wikipedia \ - -exec rm -frv {} \; + -not -name ddg \ + -not -name wikipedia \ + -exec rm -frv {} \; popd @@ -351,11 +353,10 @@ END rm testing/mozbase/mozproxy/tests/files/mitm5-linux-firefox-amazon.zip # Disable/neutralize Remote Settings (as best we can) - echo "applying libre-0001-always-sync-remote-settings-with-local-dump.patch" - patch -Np1 --no-backup-if-mismatch -i ../libre-0001-always-sync-remote-settings-with-local-dump.patch + echo "applying 9001-always-sync-remote-settings-with-local-dump.patch" + patch -Np1 --no-backup-if-mismatch -i ../9001-always-sync-remote-settings-with-local-dump.patch - # Check Remote Settings patched completely by - # libre-0001-always-sync-remote-settings-with-local-dump.patch + # Verify Remote Settings patching local settings_server='firefox.settings.services.mozilla.com' ! grep -qr $settings_server || { echo 'Remote Settings patching needs rework'; return 1; } @@ -366,11 +367,11 @@ END #sed -i '/pocket/d' browser/extensions/moz.build #sed -i '/activity-stream/d' browser/extensions/moz.build - python ../libre-process-json-files.py "$srcdir/firefox-$pkgver" "${brandingsrcdir}" + python ../process-json-files.py "${srcdir}"/firefox-${pkgver} "${brandingsrcdir}" # Remove remaining non-free bits - echo "applying libre.patch" - patch -Np1 --no-backup-if-mismatch -i "${srcdir}"/libre.patch + echo "applying 9002-misc-libre.patch" + patch -Np1 --no-backup-if-mismatch -i "${srcdir}"/9002-misc-libre.patch } build() { diff --git a/libre/iceweasel/libre-0001-always-sync-remote-settings-with-local-dump.patch b/libre/iceweasel/libre-0001-always-sync-remote-settings-with-local-dump.patch deleted file mode 100644 index 4e3732845..000000000 --- a/libre/iceweasel/libre-0001-always-sync-remote-settings-with-local-dump.patch +++ /dev/null @@ -1,987 +0,0 @@ -From c115ebc66ae779c18128e0b815fcf29da268a4f8 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 17:20:39 +0200 -Subject: [PATCH 01/13] Point to local omni.ja files, not remote server - -Basically replace every occurrence of Remote Settings server domain name -with URIs that point to built-in local files within omni.ja. - -Some links to json files may point to non-existing files, but that's OK -because it's better than leave them point to Remote Settings server. -If necessary, missing files can be added later. ---- - .../components/ASRouterAdmin/ASRouterAdmin.jsx | 2 +- - .../newtab/data/content/activity-stream.bundle.js | 2 +- - modules/libpref/init/all.js | 2 +- - services/settings/Utils.jsm | 4 ++-- - .../periodic-updates/scripts/periodic_file_updates.sh | 2 +- - toolkit/components/search/SearchUtils.jsm | 8 ++++---- - toolkit/components/search/docs/DefaultSearchEngines.rst | 2 +- - .../components/search/docs/SearchEngineConfiguration.rst | 2 +- - toolkit/mozapps/defaultagent/RemoteSettings.cpp | 2 +- - 9 files changed, 13 insertions(+), 13 deletions(-) - -diff --git a/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx b/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx -index 8c5e540bd2..329e4e66f9 100644 ---- a/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx -+++ b/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx -@@ -1260,7 +1260,7 @@ export class ASRouterAdminInner extends React.PureComponent { - - nimbus-desktop-experiments -diff --git a/browser/components/newtab/data/content/activity-stream.bundle.js b/browser/components/newtab/data/content/activity-stream.bundle.js -index fb6d64d432..d8213e7e20 100644 ---- a/browser/components/newtab/data/content/activity-stream.bundle.js -+++ b/browser/components/newtab/data/content/activity-stream.bundle.js -@@ -1835,7 +1835,7 @@ class ASRouterAdminInner extends react__WEBPACK_IMPORTED_MODULE_4___default.a.Pu - label = react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("span", null, "remote settings (", react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("a", { - className: "providerUrl", - target: "_blank", -- href: "https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/nimbus-desktop-experiments/records", -+ href: "resource://app/defaults/settings/main/nimbus-desktop-experiments.json", - rel: "noopener noreferrer" - }, "nimbus-desktop-experiments"), ")"); - } -diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js -index 2406affed4..907e8ebcef 100644 ---- a/modules/libpref/init/all.js -+++ b/modules/libpref/init/all.js -@@ -2250,7 +2250,7 @@ pref("security.cert_pinning.hpkp.enabled", false); - // Remote settings preferences - // Note: if you change this, make sure to also review security.onecrl.maximum_staleness_in_seconds - pref("services.settings.poll_interval", 86400); // 24H --pref("services.settings.server", "https://firefox.settings.services.mozilla.com/v1"); -+pref("services.settings.server", "resource://app/defaults/settings"); - pref("services.settings.default_bucket", "main"); - - // The percentage of clients who will report uptake telemetry as -diff --git a/services/settings/Utils.jsm b/services/settings/Utils.jsm -index 66df850904..0df0fdc677 100644 ---- a/services/settings/Utils.jsm -+++ b/services/settings/Utils.jsm -@@ -60,11 +60,11 @@ var Utils = { - ); - const isXpcshell = env.exists("XPCSHELL_TEST_PROFILE_DIR"); - return AppConstants.RELEASE_OR_BETA && !Cu.isInAutomation && !isXpcshell -- ? "https://firefox.settings.services.mozilla.com/v1" -+ ? "resource://app/defaults/settings" - : gServerURL; - }, - -- CHANGES_PATH: "/buckets/monitor/collections/changes/records", -+ CHANGES_PATH: "/monitor/changes.json", - - /** - * Logger instance. -diff --git a/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh b/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh -index c2492615e0..2b10ad01f6 100755 ---- a/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh -+++ b/taskcluster/docker/periodic-updates/scripts/periodic_file_updates.sh -@@ -279,7 +279,7 @@ function compare_suffix_lists { - } - - function compare_remote_settings_files { -- REMOTE_SETTINGS_SERVER="https://firefox.settings.services.mozilla.com/v1" -+ REMOTE_SETTINGS_SERVER="resource://app/defaults/settings" - - # 1. List remote settings collections from server. - echo "INFO: fetch remote settings list from server" -diff --git a/toolkit/components/search/SearchUtils.jsm b/toolkit/components/search/SearchUtils.jsm -index 278f9f9c08..7bac023c11 100644 ---- a/toolkit/components/search/SearchUtils.jsm -+++ b/toolkit/components/search/SearchUtils.jsm -@@ -139,13 +139,13 @@ var SearchUtils = { - - ENGINES_URLS: { - "prod-main": -- "https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-config/records", -+ "resource://app/defaults/settings/main/search-config.json", - "prod-preview": -- "https://firefox.settings.services.mozilla.com/v1/buckets/main-preview/collections/search-config/records", -+ "resource://app/defaults/settings/main/search-config.json", - "stage-main": -- "https://settings.stage.mozaws.net/v1/buckets/main/collections/search-config/records", -+ "resource://app/defaults/settings/main/search-config.json", - "stage-preview": -- "https://settings.stage.mozaws.net/v1/buckets/main-preview/collections/search-config/records", -+ "resource://app/defaults/settings/main/search-config.json", - }, - - // The following constants are left undocumented in nsISearchService.idl -diff --git a/toolkit/components/search/docs/DefaultSearchEngines.rst b/toolkit/components/search/docs/DefaultSearchEngines.rst -index 5668646648..deb7d20185 100644 ---- a/toolkit/components/search/docs/DefaultSearchEngines.rst -+++ b/toolkit/components/search/docs/DefaultSearchEngines.rst -@@ -63,4 +63,4 @@ is updated. - - .. _configuration schema: SearchConfigurationSchema.html - .. _remote settings: /services/common/services/RemoteSettings.html --.. _search-default-override-allowlist bucket: https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-default-override-allowlist/records -+.. _search-default-override-allowlist bucket: resource://app/defaults/settings/main/search-default-override-allowlist.json -diff --git a/toolkit/components/search/docs/SearchEngineConfiguration.rst b/toolkit/components/search/docs/SearchEngineConfiguration.rst -index e9041affb8..7a9466d294 100644 ---- a/toolkit/components/search/docs/SearchEngineConfiguration.rst -+++ b/toolkit/components/search/docs/SearchEngineConfiguration.rst -@@ -68,5 +68,5 @@ related. As a result several situations may occur: - .. _JSON schema: https://json-schema.org/ - .. _stored in mozilla-central: https://searchfox.org/mozilla-central/source/toolkit/components/search/schema/ - .. _Search Configuration Schema: SearchConfigurationSchema.html --.. _viewed live: https://firefox.settings.services.mozilla.com/v1/buckets/main/collections/search-config/records -+.. _viewed live: resource://app/defaults/settings/main/search-config.json - .. _Normandy: /toolkit/components/normandy/normandy/services.html -diff --git a/toolkit/mozapps/defaultagent/RemoteSettings.cpp b/toolkit/mozapps/defaultagent/RemoteSettings.cpp -index 667d9fc628..b2bf628f29 100644 ---- a/toolkit/mozapps/defaultagent/RemoteSettings.cpp -+++ b/toolkit/mozapps/defaultagent/RemoteSettings.cpp -@@ -23,7 +23,7 @@ extern "C" { - HRESULT IsAgentRemoteDisabledRust(const char* szUrl, DWORD* lpdwDisabled); - } - --#define PROD_ENDPOINT "https://firefox.settings.services.mozilla.com/v1" -+#define PROD_ENDPOINT "resource://app/defaults/settings" - #define PROD_BID "main" - #define PROD_CID "windows-default-browser-agent" - #define PROD_ID "state" --- -2.30.0 - - -From f76e1c055def541e358886d0e73ba4710d3e5084 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 17:34:08 +0200 -Subject: [PATCH 02/13] Remove polling triggered by push broadcasts - -When initialized, remote-settings.js adds a listener to push broadcasts, -that let Remote Settings server send push messages to trigger polling -for changes from the client side. This is not needed for local-only -setup. Remove the record from broadcast-listeners.json file stored in -the user profile, so that it doesn't get picked up by push broadcast -service. ---- - dom/push/PushBroadcastService.jsm | 13 +++++++++++++ - services/settings/remote-settings.js | 7 ++----- - 2 files changed, 15 insertions(+), 5 deletions(-) - -diff --git a/dom/push/PushBroadcastService.jsm b/dom/push/PushBroadcastService.jsm -index 27ed31ee9c..71f1316994 100644 ---- a/dom/push/PushBroadcastService.jsm -+++ b/dom/push/PushBroadcastService.jsm -@@ -179,6 +179,19 @@ var BroadcastService = class { - } - } - -+ async deleteListener(broadcastId) { -+ await this.initializePromise; -+ -+ if (this.jsonFile.data.listeners.hasOwnProperty(broadcastId)) { -+ console.info( -+ "deleteListener: deleting listener", -+ broadcastId -+ ); -+ delete this.jsonFile.data.listeners[broadcastId]; -+ this.jsonFile.saveSoon(); -+ } -+ } -+ - /** - * Call the listeners of the specified broadcasts. - * -diff --git a/services/settings/remote-settings.js b/services/settings/remote-settings.js -index 6d0185faf9..aae93fa440 100644 ---- a/services/settings/remote-settings.js -+++ b/services/settings/remote-settings.js -@@ -441,7 +441,7 @@ function remoteSettingsFunction() { - moduleURI: __URI__, - symbolName: "remoteSettingsBroadcastHandler", - }; -- pushBroadcastService.addListener(BROADCAST_ID, currentVersion, moduleInfo); -+ pushBroadcastService.deleteListener(BROADCAST_ID); - }; - - return remoteSettings; -@@ -461,9 +461,6 @@ var remoteSettingsBroadcastHandler = { - `Push notification received (version=${version} phase=${phase})` - ); - -- return RemoteSettings.pollChanges({ -- expectedTimestamp: version, -- trigger: isStartup ? "startup" : "broadcast", -- }); -+ return; - }, - }; --- -2.30.0 - - -From fcf60ef5835e673e03807d898f90e48907f44e63 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 17:41:54 +0200 -Subject: [PATCH 03/13] Remove timer that triggers polling for changes - -That is not needed for local-only setup. ---- - services/settings/components.conf | 9 +-------- - services/settings/servicesSettings.manifest | 4 ---- - 2 files changed, 1 insertion(+), 12 deletions(-) - -diff --git a/services/settings/components.conf b/services/settings/components.conf -index 9a737802ee..25109415a7 100644 ---- a/services/settings/components.conf -+++ b/services/settings/components.conf -@@ -4,11 +4,4 @@ - # License, v. 2.0. If a copy of the MPL was not distributed with this - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - --Classes = [ -- { -- 'cid': '{5e756573-234a-49ea-bbe4-59ec7a70657d}', -- 'contract_ids': ['@mozilla.org/services/settings;1'], -- 'jsm': 'resource://services-settings/RemoteSettingsComponents.jsm', -- 'constructor': 'RemoteSettingsTimer', -- }, --] -+Classes = [] -diff --git a/services/settings/servicesSettings.manifest b/services/settings/servicesSettings.manifest -index 3bfed26ea4..807eb220ec 100644 ---- a/services/settings/servicesSettings.manifest -+++ b/services/settings/servicesSettings.manifest -@@ -1,7 +1,3 @@ - # Register resource aliases - resource services-settings resource://gre/modules/services-settings/ - --# Schedule polling of remote settings changes --# (default 24H, max 72H) --# see syntax https://searchfox.org/mozilla-central/rev/cc280c4be94ff8cf64a27cc9b3d6831ffa49fa45/toolkit/components/timermanager/UpdateTimerManager.jsm#155 --category update-timer RemoteSettingsComponents @mozilla.org/services/settings;1,getService,services-settings-poll-changes,services.settings.poll_interval,86400,259200 --- -2.30.0 - - -From 8600d50c402f523973f67dfb03c1ea8614fcf48c Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 17:47:41 +0200 -Subject: [PATCH 04/13] Utils: fetch timestamps of each collection locally - -Utils.CHANGES_PATH points to -services/settings/dumps/monitor/changes.json -which will be generated later by JSON processing script. Fetch the -timestamps from that file and mock response headers to not confuse any -code that expects them. ---- - browser/installer/package-manifest.in | 1 + - services/settings/Utils.jsm | 14 ++++++++++++-- - services/settings/dumps/monitor/moz.build | 8 ++++++++ - services/settings/dumps/moz.build | 1 + - 4 files changed, 22 insertions(+), 2 deletions(-) - create mode 100644 services/settings/dumps/monitor/moz.build - -diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in -index 75c79a7168..ac01689596 100644 ---- a/browser/installer/package-manifest.in -+++ b/browser/installer/package-manifest.in -@@ -295,6 +295,7 @@ - @RESPATH@/browser/defaults/settings/blocklists - @RESPATH@/browser/defaults/settings/pinning - @RESPATH@/browser/defaults/settings/main -+@RESPATH@/browser/defaults/settings/monitor - @RESPATH@/browser/defaults/settings/security-state - - ; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325) -diff --git a/services/settings/Utils.jsm b/services/settings/Utils.jsm -index 0df0fdc677..0e631ddc0d 100644 ---- a/services/settings/Utils.jsm -+++ b/services/settings/Utils.jsm -@@ -145,7 +145,7 @@ var Utils = { - // "collection":"certificates" - // }]} - -- let url = serverUrl + Utils.CHANGES_PATH; -+ let url = Utils.SERVER_URL + Utils.CHANGES_PATH; - - // Use ETag to obtain a `304 Not modified` when no change occurred, - // and `?_since` parameter to only keep entries that weren't processed yet. -@@ -166,6 +166,9 @@ var Utils = { - .join("&"); - } - const response = await fetch(url, { headers }); -+ const responseDate = new Date().toUTCString() -+ response.headers.set("Date", responseDate); -+ response.headers.set("Last-Modified", responseDate); - - let changes = []; - // If no changes since last time, go on with empty list of changes. -@@ -203,7 +206,14 @@ var Utils = { - ); - } - } else { -- changes = payload.data; -+ const { bucket, collection } = filters; -+ if (!bucket || !collection) { -+ throw new Error('Unable to fetch latest change without bucket or collection'); -+ } -+ const change = payload.data.find( -+ change => change.bucket === bucket && change.collection === collection -+ ) ?? { last_modified: 0, bucket, collection }; -+ changes = [change]; - } - } - // The server should always return ETag. But we've had situations where the CDN -diff --git a/services/settings/dumps/monitor/moz.build b/services/settings/dumps/monitor/moz.build -new file mode 100644 -index 0000000000..d3d017fda5 ---- /dev/null -+++ b/services/settings/dumps/monitor/moz.build -@@ -0,0 +1,8 @@ -+# This Source Code Form is subject to the terms of the Mozilla Public -+# License, v. 2.0. If a copy of the MPL was not distributed with this -+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ -+FINAL_TARGET_FILES.defaults.settings.monitor += ["changes.json"] -+ -+if CONFIG["MOZ_BUILD_APP"] == "browser": -+ DIST_SUBDIR = "browser" -diff --git a/services/settings/dumps/moz.build b/services/settings/dumps/moz.build -index 3cc9436f61..3742da5667 100644 ---- a/services/settings/dumps/moz.build -+++ b/services/settings/dumps/moz.build -@@ -5,6 +5,7 @@ - DIRS += [ - "blocklists", - "main", -+ "monitor", - "pinning", - "security-state", - ] --- -2.30.0 - - -From 99af961e47d810c965c0145f19a92eedec1abafc Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 17:52:10 +0200 -Subject: [PATCH 05/13] Utils: disable offline checking - -Since only local data is read now, it should always return false for the -current any any future code that relies on it. ---- - services/settings/Utils.jsm | 9 --------- - 1 file changed, 9 deletions(-) - -diff --git a/services/settings/Utils.jsm b/services/settings/Utils.jsm -index 0e631ddc0d..d034d8ea78 100644 ---- a/services/settings/Utils.jsm -+++ b/services/settings/Utils.jsm -@@ -80,15 +80,6 @@ var Utils = { - * @return {bool} Whether network is down or not. - */ - get isOffline() { -- try { -- return ( -- Services.io.offline || -- CaptivePortalService.state == CaptivePortalService.LOCKED_PORTAL || -- !gNetworkLinkService.isLinkUp -- ); -- } catch (ex) { -- log.warn("Could not determine network status.", ex); -- } - return false; - }, - --- -2.30.0 - - -From 55830695a1e2457aecca1392d46c98c3e210d58a Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 17:56:02 +0200 -Subject: [PATCH 06/13] Refactor hashing logic to a separate function - -It is used instead of internal signature validation mechanism, for -integrity checking of the locally cached data. ---- - services/settings/RemoteSettingsWorker.jsm | 4 ++++ - services/settings/SharedUtils.jsm | 9 +++++++-- - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/services/settings/RemoteSettingsWorker.jsm b/services/settings/RemoteSettingsWorker.jsm -index 147ebb6b13..c86e218fd3 100644 ---- a/services/settings/RemoteSettingsWorker.jsm -+++ b/services/settings/RemoteSettingsWorker.jsm -@@ -189,6 +189,10 @@ class Worker { - // task on the current thread instead of the worker thread. - return SharedUtils.checkContentHash(buffer, size, hash); - } -+ -+ async getContentHash(bytes) { -+ return SharedUtils.getContentHash(bytes); -+ } - } - - // Now, first add a shutdown blocker. If that fails, we must have -diff --git a/services/settings/SharedUtils.jsm b/services/settings/SharedUtils.jsm -index db5017a742..1a8e83c2e8 100644 ---- a/services/settings/SharedUtils.jsm -+++ b/services/settings/SharedUtils.jsm -@@ -28,11 +28,16 @@ var SharedUtils = { - return false; - } - // Has expected content? -+ const hashStr = await this.getContentHash(bytes); -+ return hashStr == hash; -+ }, -+ -+ async getContentHash(bytes) { - const hashBuffer = await crypto.subtle.digest("SHA-256", bytes); - const hashBytes = new Uint8Array(hashBuffer); - const toHex = b => b.toString(16).padStart(2, "0"); -- const hashStr = Array.from(hashBytes, toHex).join(""); -- return hashStr == hash; -+ -+ return Array.from(hashBytes, toHex).join(""); - }, - - /** --- -2.30.0 - - -From 9dc19397aebfb6b9f74afa0fb4d653a29e14e964 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 18:05:02 +0200 -Subject: [PATCH 07/13] Client: Fetch and hash records from local dump - -Read the records from local dumps. See [1] for details on how to prepare -custom dumps). Records are cached in the local IndexedDB, and the client -updates cached records each time there's a change. Also it verifies -integrity of the data. Then the list of current / created / updated / -deleted records is generated and emitted to every registered listener. - -Change upstream signature validation mechanism to a simpler one. -Otherwise, it'd be necessary to sign local records, which is redundant, -because the application package should be signed already by the distro. - -Instead of signature property from metadata records, json_dump_metadata -has been introduced. It contains the checksum of the records and size in -bytes. Also added app_build_id property for version checking and updates -of cached data. - -Although it's possible to disable integrity checking via preference, it -seems to be not a good idea, because the logic that detects invalid -local data relies on it. In the context of local-only setup, data that -has been received from real Remote Settings server will not contain the -custom metadata, and thus will be considered invalid and then discarded, -while the client gets a chance to gracefully inform registered listeners -about these changes so that they can discard the data received before -the upgrade to local-only setup. - -[1] https://firefox-source-docs.mozilla.org/services/common/services/RemoteSettings.html#initial-data ---- - services/settings/RemoteSettingsClient.jsm | 62 ++++++++++------------ - 1 file changed, 27 insertions(+), 35 deletions(-) - -diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm -index 80dd563e11..1025ab33a2 100644 ---- a/services/settings/RemoteSettingsClient.jsm -+++ b/services/settings/RemoteSettingsClient.jsm -@@ -556,11 +556,9 @@ class RemoteSettingsClient extends EventEmitter { - - // If the data is up-to-date but don't have metadata (records loaded from dump), - // we fetch them and validate the signature immediately. -- if (this.verifySignature && ObjectUtils.isEmpty(localMetadata)) { -+ if (this.verifySignature && ObjectUtils.isEmpty(localMetadata?.json_dump_metadata)) { - console.debug(`${this.identifier} pull collection metadata`); -- const metadata = await this.httpClient().getData({ -- query: { _expected: expectedTimestamp }, -- }); -+ const { metadata } = await this._fetchChangeset(expectedTimestamp); - await this.db.importChanges(metadata); - // We don't bother validating the signature if the dump was just loaded. We do - // if the dump was loaded at some other point (eg. from .get()). -@@ -813,32 +811,23 @@ class RemoteSettingsClient extends EventEmitter { - async _validateCollectionSignature(records, timestamp, metadata) { - const start = Cu.now() * 1000; - -- if (!metadata?.signature) { -+ if (!metadata?.json_dump_metadata) { - throw new MissingSignatureError(this.identifier); - } - -- if (!this._verifier) { -- this._verifier = Cc[ -- "@mozilla.org/security/contentsignatureverifier;1" -- ].createInstance(Ci.nsIContentSignatureVerifier); -- } -- -- // This is a content-signature field from an autograph response. - const { -- signature: { x5u, signature }, -+ json_dump_metadata: { hash, size }, - } = metadata; -- const certChain = await (await fetch(x5u)).text(); - // Merge remote records with local ones and serialize as canonical JSON. - const serialized = await RemoteSettingsWorker.canonicalStringify( - records, - timestamp - ); - if ( -- !(await this._verifier.asyncVerifyContentSignature( -- serialized, -- "p384ecdsa=" + signature, -- certChain, -- this.signerName -+ !(await RemoteSettingsWorker.checkContentHash( -+ new TextEncoder().encode(serialized), -+ size, -+ hash - )) - ) { - throw new InvalidSignatureError(this.identifier); -@@ -1030,24 +1019,27 @@ class RemoteSettingsClient extends EventEmitter { - * @param since timestamp of last sync (optional) - */ - async _fetchChangeset(expectedTimestamp, since) { -- const client = this.httpClient(); -- const { -- metadata, -- timestamp: remoteTimestamp, -- changes: remoteRecords, -- } = await client.execute( -- { -- path: `/buckets/${this.bucketName}/collections/${this.collectionName}/changeset`, -- }, -- { -- query: { -- _expected: expectedTimestamp, -- _since: since, -- }, -- } -+ const { data } = await SharedUtils.loadJSONDump( -+ this.bucketName, -+ this.collectionName - ); -+ const remoteRecords = data ?? []; -+ -+ const serialized = await RemoteSettingsWorker.canonicalStringify( -+ remoteRecords, -+ expectedTimestamp -+ ); -+ const bytes = new TextEncoder().encode(serialized); -+ const metadata = { -+ app_build_id: Services.appinfo.appBuildID, -+ json_dump_metadata: { -+ hash: await RemoteSettingsWorker.getContentHash(bytes), -+ size: bytes.length, -+ }, -+ } -+ - return { -- remoteTimestamp, -+ remoteTimestamp: expectedTimestamp, - metadata, - remoteRecords, - }; --- -2.30.0 - - -From 4dfbb2ccacd011b05839c19127942b497141f2a1 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 18:42:56 +0200 -Subject: [PATCH 08/13] Client: start deferred sync on get() or on() - -The users of the RemoteSettingsClient.jsm can receive records from it in -two ways: by calling get(), and by subscribing to events by calling -on(). - -So hook a deferred sync whenever something calls these methods. Because -multiple of those calls can be made quite early and in very short time, -set up a deferred task that will be armed only when needed and only once -in a second. When the task is running it first checks if the local data -came from the dump of the current app build, and no-ops if true. If -false, it triggers a sync. Then adds a flag if the client has been -correctly synchronized with the dump, so that no metadata checking -occurs during the session. ---- - services/settings/RemoteSettingsClient.jsm | 32 ++++++++++++++++++++-- - 1 file changed, 30 insertions(+), 2 deletions(-) - -diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm -index 1025ab33a2..253251823a 100644 ---- a/services/settings/RemoteSettingsClient.jsm -+++ b/services/settings/RemoteSettingsClient.jsm -@@ -16,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { - ClientEnvironmentBase: - "resource://gre/modules/components-utils/ClientEnvironment.jsm", - Database: "resource://services-settings/Database.jsm", -+ DeferredTask: "resource://gre/modules/DeferredTask.jsm", - Downloader: "resource://services-settings/Attachments.jsm", - IDBHelpers: "resource://services-settings/IDBHelpers.jsm", - KintoHttpClient: "resource://services-common/kinto-http-client.js", -@@ -30,6 +31,7 @@ XPCOMUtils.defineLazyModuleGetters(this, { - XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]); - - const TELEMETRY_COMPONENT = "remotesettings"; -+const DEFERRED_SYNC_DELAY_MILLISECONDS = 1000 - - XPCOMUtils.defineLazyGetter(this, "console", () => Utils.log); - -@@ -259,6 +261,14 @@ class RemoteSettingsClient extends EventEmitter { - this._lastCheckTimePref = lastCheckTimePref; - this._verifier = null; - this._syncRunning = false; -+ this._deferredSync = new DeferredTask( -+ async () => { -+ if (!this._syncRunning && !(await this._isSynced())) { -+ await this.sync(); -+ } -+ }, -+ DEFERRED_SYNC_DELAY_MILLISECONDS -+ ); - - // This attribute allows signature verification to be disabled, when running tests - // or when pulling data from a dev server. -@@ -290,6 +300,11 @@ class RemoteSettingsClient extends EventEmitter { - ); - } - -+ on(event, callback) { -+ super.on(event, callback); -+ this._deferredSync.arm(); -+ } -+ - get identifier() { - return `${this.bucketName}/${this.collectionName}`; - } -@@ -353,7 +368,11 @@ class RemoteSettingsClient extends EventEmitter { - try { - let hasLocalData = await Utils.hasLocalData(this); - -- if (syncIfEmpty && !hasLocalData) { -+ if (!(await this._isSynced())) { -+ throw new MissingSignatureError(this.identifier); -+ } -+ -+ if ((syncIfEmpty && !hasLocalData)) { - // .get() was called before we had the chance to synchronize the local database. - // We'll try to avoid returning an empty list. - if (!this._importingPromise) { -@@ -414,7 +433,10 @@ class RemoteSettingsClient extends EventEmitter { - // No need to verify signature on JSON dumps. - // If local DB cannot be read, then we don't even try to do anything, - // we return results early. -- return this._filterEntries(data); -+ const filtered = this._filterEntries(data); -+ this._deferredSync.arm(); -+ -+ return filtered; - } - - console.debug( -@@ -452,6 +474,12 @@ class RemoteSettingsClient extends EventEmitter { - return final; - } - -+ async _isSynced() { -+ this._synced ||= -+ Services.appinfo.appBuildID === (await this.db.getMetadata())?.app_build_id; -+ return this._synced; -+ } -+ - /** - * Synchronize the local database with the remote server. - * --- -2.30.0 - - -From 89dc912d08b7d4eed113439efa17dce57eda106e Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 18:53:51 +0200 -Subject: [PATCH 09/13] Client: deep compare records if timestamps match - -When the list of current / updated / deleted records is generated, their -modification timestamps are compared to detect the updates. - -Although in practice this is unlikely to happen, in theory the -timestamp of some older record received from Remote Settings can match -with the modified record in the dump. Although JSON processing script -makes sure to add unique timestamps to each of the modified records, -it's still possible to update dumps manually and simply forget to update -timestamps. So serialize the records and compare them as strings to be -on the safe side. This should happen only once after upgrading to each -new version of the application, so is not likely to introduce any -noticeable performance issues. ---- - services/settings/RemoteSettingsClient.jsm | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm -index 253251823a..b45a55919c 100644 ---- a/services/settings/RemoteSettingsClient.jsm -+++ b/services/settings/RemoteSettingsClient.jsm -@@ -13,6 +13,7 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); - - XPCOMUtils.defineLazyModuleGetters(this, { - AppConstants: "resource://gre/modules/AppConstants.jsm", -+ CanonicalJSON: "resource://gre/modules/CanonicalJSON.jsm", - ClientEnvironmentBase: - "resource://gre/modules/components-utils/ClientEnvironment.jsm", - Database: "resource://services-settings/Database.jsm", -@@ -1022,7 +1023,10 @@ class RemoteSettingsClient extends EventEmitter { - const old = oldById.get(r.id); - if (old) { - oldById.delete(r.id); -- if (r.last_modified != old.last_modified) { -+ if ( -+ r.last_modified != old.last_modified || -+ CanonicalJSON.stringify(r) != CanonicalJSON.stringify(old) -+ ) { - syncResult.updated.push({ old, new: r }); - } - } else { --- -2.30.0 - - -From 5f4207fd155c2dae802522070627c34ced6a192e Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 19:01:39 +0200 -Subject: [PATCH 10/13] Client: delete more data on cleanup - -When the client detects the local data is invalid (i.e. it came from -real Remote Settings and can have unwanted records), delete not only -the records, but also the attachments that came with them, because they -too can be problematic. And last check time preference, because it's not -useful anyway when remote-settings.js doesn't do any polling for changes. - -Note that attachments should be deleted before the records, because the -logic gets the data about the attachments from those records. ---- - services/settings/RemoteSettingsClient.jsm | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm -index b45a55919c..3dbd972f87 100644 ---- a/services/settings/RemoteSettingsClient.jsm -+++ b/services/settings/RemoteSettingsClient.jsm -@@ -221,7 +221,10 @@ class AttachmentDownloader extends Downloader { - async deleteAll() { - let allRecords = await this._client.db.list(); - return Promise.all( -- allRecords.filter(r => !!r.attachment).map(r => this.delete(r)) -+ allRecords.filter(r => !!r.attachment).map(r => { -+ this.delete(r); -+ this.deleteCached(r.id); -+ }) - ); - } - } -@@ -982,7 +985,7 @@ class RemoteSettingsClient extends EventEmitter { - // Signature failed, clear local DB because it contains - // bad data (local + remote changes). - console.debug(`${this.identifier} clear local data`); -- await this.db.clear(); -+ await this._clearAll(); - // Local data was tampered, throw and it will retry from empty DB. - console.error(`${this.identifier} local data was corrupted`); - throw new CorruptedDataError(this.identifier); -@@ -1004,7 +1007,7 @@ class RemoteSettingsClient extends EventEmitter { - // _importJSONDump() only clears DB if dump is available, - // therefore do it here! - if (imported < 0) { -- await this.db.clear(); -+ await this._clearAll(); - } - } - } -@@ -1044,6 +1047,12 @@ class RemoteSettingsClient extends EventEmitter { - return syncResult; - } - -+ async _clearAll() { -+ await this.attachments.deleteAll(); -+ await this.db.clear(); -+ Services.prefs.clearUserPref(this.lastCheckTimePref); -+ } -+ - /** - * Fetch information from changeset endpoint. - * --- -2.30.0 - - -From b3c304e2fe95d0a75c524a5aa96a68a34ce2ae34 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 19:07:56 +0200 -Subject: [PATCH 11/13] Client: remove comparison of collection timestamps - -In case if the cached data that came from real Remote Settings server -(before the upgrade to local-only setup) has collection timestamp, that -is newer than the packaged local dump, then this comparison logic can -lead to early return of old data, skipping the integrity checking and -necessary cleanup. So remove the checks. ---- - services/settings/RemoteSettingsClient.jsm | 5 ----- - 1 file changed, 5 deletions(-) - -diff --git a/services/settings/RemoteSettingsClient.jsm b/services/settings/RemoteSettingsClient.jsm -index 3dbd972f87..d319a77c27 100644 ---- a/services/settings/RemoteSettingsClient.jsm -+++ b/services/settings/RemoteSettingsClient.jsm -@@ -917,14 +917,9 @@ class RemoteSettingsClient extends EventEmitter { - updated: [], - deleted: [], - }; -- // If data wasn't changed, return empty sync result. -- // This can happen when we update the signature but not the data. - console.debug( - `${this.identifier} local timestamp: ${localTimestamp}, remote: ${remoteTimestamp}` - ); -- if (localTimestamp && remoteTimestamp < localTimestamp) { -- return syncResult; -- } - - const start = Cu.now() * 1000; - await this.db.importChanges(metadata, remoteTimestamp, remoteRecords, { --- -2.30.0 - - -From 804007d2861f829315e575660d47b9a4c430d151 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 19:15:44 +0200 -Subject: [PATCH 12/13] Attachments: load only from dump and drop cached - ---- - services/settings/Attachments.jsm | 35 +++++++------------------------ - 1 file changed, 8 insertions(+), 27 deletions(-) - -diff --git a/services/settings/Attachments.jsm b/services/settings/Attachments.jsm -index 0eeb632799..eaa7db8c81 100644 ---- a/services/settings/Attachments.jsm -+++ b/services/settings/Attachments.jsm -@@ -143,10 +143,11 @@ class Downloader { - checkHash, - attachmentId = record?.id, - useCache = false, -- fallbackToCache = false, - fallbackToDump = false, - } = options || {}; - -+ const fallbackToCache = false; -+ - if (!useCache) { - // For backwards compatibility. - // WARNING: Its return type is different from what's documented. -@@ -206,6 +207,7 @@ class Downloader { - const newBuffer = await this.downloadAsBytes(record, { - retries, - checkHash, -+ dumpInfo, - }); - const blob = new Blob([newBuffer]); - if (useCache) { -@@ -241,7 +243,7 @@ class Downloader { - } - - try { -- return { ...(await cacheInfo.getResult()), _source: "cache_fallback" }; -+ await this.cacheImpl.delete(attachmentId); - } catch (e) { - // Failed to read from cache, e.g. IndexedDB unusable. - Cu.reportError(e); -@@ -278,7 +280,7 @@ class Downloader { - * @returns {String} the absolute file path to the downloaded attachment. - */ - async downloadToDisk(record, options = {}) { -- const { retries = 3 } = options; -+ const retries = 0; - const { - attachment: { filename, size, hash }, - } = record; -@@ -335,31 +337,10 @@ class Downloader { - */ - async downloadAsBytes(record, options = {}) { - const { -- attachment: { location, hash, size }, -- } = record; -- -- const remoteFileUrl = (await this._baseAttachmentsURL()) + location; -+ dumpInfo = new LazyRecordAndBuffer(() => this._readAttachmentDump(attachmentId)) -+ } = options; - -- const { retries = 3, checkHash = true } = options; -- let retried = 0; -- while (true) { -- try { -- const buffer = await this._fetchAttachment(remoteFileUrl); -- if (!checkHash) { -- return buffer; -- } -- if (await RemoteSettingsWorker.checkContentHash(buffer, size, hash)) { -- return buffer; -- } -- // Content is corrupted. -- throw new Downloader.BadContentError(location); -- } catch (e) { -- if (retried >= retries) { -- throw e; -- } -- } -- retried++; -- } -+ return (await dumpInfo.getResult()).buffer; - } - - /** --- -2.30.0 - - -From 4ee3b715e10a5f9a5ef7830b047ae7f64e55e5f4 Mon Sep 17 00:00:00 2001 -From: grizzlyuser -Date: Wed, 30 Dec 2020 19:22:20 +0200 -Subject: [PATCH 13/13] Disable CRLite entirely for now - -It's designed to fetch the data from Remote Settings. One of the main -selling points is that new revocations can be pushed to the clients -within minutes. That won't work with local-only setup. Although (some?) -of the JSON dumps for it are in place, obviously the updates won't -happen that fast. - -Right now CRLite doesn't enforce anything, and works just for telemetry -collection (which is hopefully disabled anyway). So disable the -preference right in the source code, so that the patch fails to apply -when the upstream decides to set it to enforcing mode by default. - -The solution with CRLite is up for discussion. If necessary, it's -possible to make clients for blessed collections to communicate to real -Remote Settings server. For example, for collections related to -certificate revocations. ---- - modules/libpref/init/all.js | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js -index 907e8ebcef..65db6bd04c 100644 ---- a/modules/libpref/init/all.js -+++ b/modules/libpref/init/all.js -@@ -186,7 +186,7 @@ pref("security.pki.distrust_ca_policy", 2); - #if defined(NIGHTLY_BUILD) - pref("security.pki.crlite_mode", 2); - #else --pref("security.pki.crlite_mode", 1); -+pref("security.pki.crlite_mode", 0); - #endif - - // Represents the expected certificate transparency log merge delay (including --- -2.30.0 - diff --git a/libre/iceweasel/libre-process-json-files.py b/libre/iceweasel/libre-process-json-files.py deleted file mode 100644 index 2fdde62d4..000000000 --- a/libre/iceweasel/libre-process-json-files.py +++ /dev/null @@ -1,174 +0,0 @@ -#! /usr/bin/python3 - -# Copyright (C) 2020 grizzlyuser -# Based on: https://gitlab.trisquel.org/trisquel/wrapage-helpers/-/blob/81881d89b2bf7d502dd14fcccdb471fec6f6b206/helpers/DATA/firefox/reprocess-search-config.py -# Below is the notice from the original author: -# -# Copyright (C) 2020 Ruben Rodriguez -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -import json -import sys -import time -import copy -import argparse -import pathlib -from collections import namedtuple -from jsonschema import validate - -parser = argparse.ArgumentParser() -parser.add_argument( - 'MAIN_PATH', - type=pathlib.Path, - help='path to main application source code directory') -parser.add_argument( - 'BRANDING_PATH', - type=pathlib.Path, - help='path to branding source code directory') -parser.add_argument( - '-i', - '--indent', - type=int, - help='indent for pretty printing of output files') -arguments = parser.parse_args() - -File = namedtuple('File', ['path', 'content']) - - -class RemoteSettings: - DUMPS_PATH = arguments.MAIN_PATH / 'services/settings/dumps' - JSON_PATHS = tuple(DUMPS_PATH.glob('*/*.json')) - WRAPPER_NAME = 'data' - - @classmethod - def wrap(cls, processed): - return File(processed.path, {cls.WRAPPER_NAME: processed.content}) - - @classmethod - def unwrap(cls, parsed_jsons): - return [File(json.path, json.content[cls.WRAPPER_NAME]) - for json in parsed_jsons] - - @classmethod - def process_raw(cls, unwrapped_jsons): - changes = [] - output_path = cls.DUMPS_PATH / 'monitor/changes.json' - - for collection in unwrapped_jsons: - if collection.path == cls.DUMPS_PATH / 'main/example.json': - continue - latest_change = {} - latest_change['last_modified'] = max( - (record['last_modified'] for record in collection.content), default=0) - latest_change['bucket'] = collection.path.parent.name - latest_change['collection'] = collection.path.stem - changes.append(latest_change) - - output_path.parent.mkdir(exist_ok=True) - - return File(output_path, changes) - - @classmethod - def process(cls, parsed_jsons): - return cls.wrap(cls.process_raw(cls.unwrap(parsed_jsons))) - - -class SearchConfig(RemoteSettings): - JSON_PATHS = (RemoteSettings.DUMPS_PATH / 'main/search-config.json',) - - def _get_schema(): - PATH = arguments.MAIN_PATH / \ - 'toolkit/components/search/schema/search-engine-config-schema.json' - with PATH.open() as file: - return json.load(file) - - @classmethod - def process_raw(cls, unwrapped_jsons): - _WHITELIST = ('ddg@search.mozilla.org', 'wikipedia@search.mozilla.org') - SCHEMA = cls._get_schema() - - search_engines, timestamps = [], [] - search_config = unwrapped_jsons[0] - - for search_engine in search_config.content: - if search_engine['webExtension']['id'] in _WHITELIST: - clone = copy.deepcopy(search_engine) - - if 'telemetryId' in search_engine: - del search_engine['telemetryId'] - if 'extraParams' in search_engine: - del search_engine['extraParams'] - - general_specifier = {} - for specifier in search_engine['appliesTo'].copy(): - if 'application' in specifier: - if 'distributions' in specifier['application']: - search_engine['appliesTo'].remove(specifier) - continue - if 'extraParams' in specifier['application']: - del specifier['application']['extraParams'] - - if 'included' in specifier and 'everywhere' in specifier[ - 'included'] and specifier['included']['everywhere']: - general_specifier = specifier - - if not general_specifier: - general_specifier = {'included': {'everywhere': True}} - search_engine['appliesTo'].insert(0, general_specifier) - if search_engine['webExtension']['id'] == _WHITELIST[0]: - general_specifier['default'] = 'yes' - - if clone != search_engine: - timestamp = int(round(time.time_ns() / 10 ** 6)) - while timestamp in timestamps: - timestamp += 1 - timestamps.append(timestamp) - search_engine['last_modified'] = timestamp - - validate(search_engine, schema=SCHEMA) - - search_engines.append(search_engine) - - return File(search_config.path, search_engines) - - -class TopSites: - JSON_PATHS = ( - arguments.MAIN_PATH / - 'browser/components/newtab/data/content/tippytop/top_sites.json', - arguments.BRANDING_PATH / - 'tippytop/top_sites.json') - - @classmethod - def process(cls, parsed_jsons): - main_top_sites = parsed_jsons[0] - branding_top_sites = parsed_jsons[1] - result = branding_top_sites.content + \ - [site for site in main_top_sites.content if site['title'] == 'wikipedia'] - return File(main_top_sites.path, result) - - -processors = (SearchConfig, TopSites, RemoteSettings) - -for processor in processors: - parsed_jsons = [] - for json_path in processor.JSON_PATHS: - with json_path.open() as file: - parsed_jsons.append(File(json_path, json.load(file))) - - processed = processor.process(parsed_jsons) - with processed.path.open('w') as file: - json.dump(processed.content, file, indent=arguments.indent) diff --git a/libre/iceweasel/libre.patch b/libre/iceweasel/libre.patch deleted file mode 100644 index 124ff00f2..000000000 --- a/libre/iceweasel/libre.patch +++ /dev/null @@ -1,387 +0,0 @@ -diff --git a/browser/app/permissions b/browser/app/permissions -index 991284081d..888cc811ce 100644 ---- a/browser/app/permissions -+++ b/browser/app/permissions -@@ -15,11 +15,5 @@ origin uitour 1 https://support.mozilla.org - origin uitour 1 about:home - origin uitour 1 about:newtab - --# XPInstall --origin install 1 https://addons.mozilla.org -- - # Remote troubleshooting - origin remote-troubleshooting 1 https://support.mozilla.org -- --# addon install --origin install 1 https://fpn.firefox.com -diff --git a/browser/components/preferences/sync.inc.xhtml b/browser/components/preferences/sync.inc.xhtml -index 7d37d26..4ebbc06 100644 ---- a/browser/components/preferences/sync.inc.xhtml -+++ b/browser/components/preferences/sync.inc.xhtml -@@ -35,22 +35,6 @@ - - - -- - - - -diff --git a/browser/locales/en-US/browser/policies/policies-descriptions.ftl b/browser/locales/en-US/browser/policies/policies-descriptions.ftl -index dabfadc..3ce732e 100644 ---- a/browser/locales/en-US/browser/policies/policies-descriptions.ftl -+++ b/browser/locales/en-US/browser/policies/policies-descriptions.ftl -@@ -96,7 +96,7 @@ policy-ExtensionSettings = Manage all aspects of extension installation. - - policy-ExtensionUpdate = Enable or disable automatic extension updates. - --policy-FirefoxHome = Configure Firefox Home. -+policy-FirefoxHome = Configure Iceweasel Home. - - policy-FlashPlugin = Allow or deny usage of the Flash plugin. - -diff --git a/browser/locales/en-US/browser/preferences/preferences.ftl b/browser/locales/en-US/browser/preferences/preferences.ftl -index 1b29e8d..6f7566c 100644 ---- a/browser/locales/en-US/browser/preferences/preferences.ftl -+++ b/browser/locales/en-US/browser/preferences/preferences.ftl -@@ -550,7 +550,7 @@ home-restore-defaults = - # "Firefox" should be treated as a brand and kept in English, - # while "Home" and "(Default)" can be localized. - home-mode-choice-default = -- .label = Firefox Home (Default) -+ .label = Iceweasel Home (Default) - - home-mode-choice-custom = - .label = Custom URLs… -@@ -577,10 +577,10 @@ choose-bookmark = - .label = Use Bookmark… - .accesskey = B - --## Home Section - Firefox Home Content Customization -+## Home Section - Iceweasel Home Content Customization - --home-prefs-content-header = Firefox Home Content --home-prefs-content-description = Choose what content you want on your Firefox Home screen. -+home-prefs-content-header = Iceweasel Home Content -+home-prefs-content-description = Choose what content you want on your Iceweasel Home screen. - - home-prefs-search-header = - .label = Web Search -@@ -714,16 +714,6 @@ sync-signedout-account-signin2 = - .label = Sign in to { -sync-brand-short-name }… - .accesskey = i - --# This message contains two links and two icon images. --# `` - Android logo icon --# `` - Link to Android Download --# `` - iOS logo icon --# `` - Link to iOS Download --# --# They can be moved within the sentence as needed to adapt --# to your language, but should not be changed or translated. --sync-mobile-promo = Download Firefox for Android or iOS to sync with your mobile device. -- - ## Firefox Account - Signed in - - sync-profile-picture = -diff --git a/browser/locales/generic/profile/bookmarks.html.in b/browser/locales/generic/profile/bookmarks.html.in -index 2d3c7b4..00221d3 100644 ---- a/browser/locales/generic/profile/bookmarks.html.in -+++ b/browser/locales/generic/profile/bookmarks.html.in -@@ -1,15 +1,15 @@ - #filter substitution - #include @BOOKMARKS_INCLUDE_PATH@ - --#define mozilla_icon data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E %3Cpath d='M0 0h16v16H0z'/%3E %3Cpath d='M13.994 10.356H15V12h-3.171V7.741c0-1.308-.435-1.81-1.29-1.81-1.04 0-1.46.737-1.46 1.8v2.63h1.006V12H6.918V7.741c0-1.308-.435-1.81-1.291-1.81-1.039 0-1.459.737-1.459 1.8v2.63h1.441V12H1v-1.644h1.006V6.079H1V4.435h3.168v1.139a2.507 2.507 0 0 1 2.3-1.29A2.452 2.452 0 0 1 8.931 5.91 2.535 2.535 0 0 1 11.4 4.284 2.448 2.448 0 0 1 14 6.9v3.458z' fill='%23fff'/%3E %3C/svg%3E -+#define parabola_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABL0lEQVQ4jWNgoCcoq16VU1GzygnEBtEVDWuV8GooKFuhWVG3uiM3d5UokG4qr1szAaa5vGbVt4ralacwNDU0rGIrr10VBVG0+lxhwyqVsqqVtRW1q6eD5IvL19oB2V+B+D9QzQu4xtDQVZylVavygRKHqurWOlbUrknKK12qWlCwWLK8elUFA8N/xvLy5VYVtas+gzWDDVi9E2QjT1XdcufymjWpQJt1cXmnvHwVP1DzR7hmIC6vW+kOtpnYQKysW30arrlm9RVi9cFBRfXKJTADympWJZNsQFnN6rUQA1adAQU2SZqBXmUGBtozUDiU1qxQJtl2oCY3kO2l1avCSdYMAsBAWwyM2plkaS4p6eYGOv1YQ0MDB1kGlFWuDChuWKZBlmYQqK5eJU22ZkIAAEIlnQZQkzITAAAAAElFTkSuQmCC - --#define firefox_icon data:image/png;base64,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 -+#define fsf_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAADG0lEQVQoFQEQA+/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQECAAAAAAAAAAAAAAAAAAAA2qOp7tTXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAP///wAAAAAAAOCyt7pUXQcSEgcQDwAAAP///wAAAAAAAAD//x9NSDqNhQEBAQQAAAAAAAAAAAAAAAAQJiQGDQ0aPToZPjoAAQEAAAAAAAAAAAABAQEpZV4AAAAAAAAAAAAA////////////////pSIv05KZ////////////////////////////////AAAAAQAAAP///6krNwAAAAAAAPHc3ggSEQcSEQAAAAAAAAAAABY3NEGelQAAAAAAAAEBAQEAAAD///+YARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDg1g690CBgYAAAABAQEEAAAAAAAAS7etAAAAAAAAwGVtHklFIlJOAAAAAAAAAAAAAAAA+/X2BwYGAAAAAAAABAAAAAAAAB1IQwAAAAAAAAYNDBAmJB1IQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAgL//v4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAQEB//7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAECAv/+/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////////////cqK3qzM////////////////////////////////8AAAABAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGuLjDf9F8oBAAAAAElFTkSuQmCC - --#define bugzilla_icon data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnYCL7J0pY9wwETY9kYEM9AAAAAEBAYAhVVVUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1bjTOS1Vb/wAA2/8JEqT/Q0g8kQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJnMqoiJtJ/0haST/NEkp/yQnW/8AAPD8AAHY/RsgP/JZUI+GKitih4ObUEAAAAAAAAAAAAAAAAAAAAAAKnouwip5Lv9ooW//a6Jz/y9GIv8JBXb/AADO/gEBvf8AAK7/FRJp/z9BfP8iLGj1AAAAAAAAAAAAAAAAL4YzwiB0I/+UwJ3/bK+C/02eZ/9CTjz/DBa1/wABxf8BAOj/AACp/w8Oc/sJCv//EhCN9AAAAAAAAAAANJA6iC2MMv93tYL/TZ5U/3mzjP9NoWr/NEss/wYIU/8CBOn/ARCX/wwNqP0TD6X/Cgyex5qacDAAAAAAAAAAADKUN/ZirWj/d76R/0SgXf9Ln1P/eLSM/1mda/8rOkb/CQiD/wMQvf8UEnT/MTAt4P//MwUhZyN8AAAAAAAAAAAznDf5UqlZ/228jP9NqnD/Qp9c/0yiVP+Dv5b/VaVw/0VxXf9PZXD/S3pQ/y54Nf8jcCf/I2wn/wAAAAA0ozjIM6E4/zOeOP+Uz6z/XLR+/06scv9BoV3/TqZX/4XBmP9XqHP/hr6Z/yp+Lf8leSr1JXUqbQAAAAA3rTz7Nqo7/zWmOqM3oz7rUK1W/43Mpf9etYD/T61z/0KjXf9Rqln/msup/46/lf8pgy7/JFg6sAAAAAAAAAAAOK8+8jqvOiMAAAAAAAAAADSlOv85pT//kM6o/2K5hP9Ysnv/YLJ2/ziXPv8piS3/V6Ri/yZQQ9wAAAAAAAAAAAAAAAAAAAAAAAAAADetP0E2qzz/OKg98UWsS/+e1K3/pNe4/4XDjv8ojy3/T7df/5fIqv8sjTH/K4kw/yqFLv8AAAAAAAAAAAAAAAA4sT3xN7A8+QAAAAA4qz3yNag6/zSlOf80oTn/csJ+/6/jwv9fjHj/MmRMdQAAAAAAAAAAAAAAAAAAAAAAAAAAOrdA/zm0QHQAAAAAAAAAADasO/k2qTvuRX5lpjqGT/gznDr/O3FXigAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADq9QiMAAAAAAAAAAAAAAAA4sj7/Nq09s0uOaSI1qTplM6U68wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrc//zu0P0EAAAAAOK4+UjWsPPgAAAAAAAAAAAAAAAAAAAAA/48AAP8HAAD4AQAA8AAAAOAAAADAAQAAwAMAAMAAAACAAwAAAAMAAHADAADwAAAA5AcAAO4HAAD+bwAA/u8AAA== -+#define gnu_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAGFBMVEVFRUV+fn6mpqa/v7/Ozs7Y2Njg4OD8/Pwuhn+TAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEQAACxEBf2RfkQAAAAd0SU1FB9MBDhQ6Gd8s57cAAAEVSURBVBgZBcGxVtpgGADQL9gHSBzqSognzMixmcWWzB6pmRHhnyvku6/fewMAIPD3TwHmQxHs6vr+A16bphNum/vV0x429201hcPjAGBTDZGnR/Kw1U181+u4HXvOdSxjUcztz8jjg1xGVBG9XPYxt4PviKiaWLg168iXtbrq+mPT1utjNcR1U73deRnL43M2sRgj3+oYs8uL3rLphPd2QWmHbMu/VS/cnk6UdtSW657g9yBlcZ0UAkUWzPvyRaAYmfd+HT4IZtvC59ibEJxXiqJjQpBpNEufBYE0McoOAunGhRMEFIPc7h4goJigQEBxk8u7AgEpL3IEAUZfcgAByGFXQACm5+4MAuB19QMEgI8CAgDgP4rivVgoKP6ZAAAAAElFTkSuQmCC - --#define mdn_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAABgElEQVR4AWPouPiRpmjUAjgatSBj+aG0OVuyVhymsgWl2y475zXySikwwIC4lpFDVk3avG0BrXP9mmeV7bhCvgXuxW3M7JwMeAGfpByZFpjHFzAQB2KmrSfZAtuMKgaiAZ+MUuLc7SRY4FbYwkA60HAJiJm8uubQAwIWeJV1MlAAOAREHDJrcFqQMG+ngIK6oKyykLwqAyMjeXZwiUjgtKD+yGMIwyGzmoGBTAs4hcXrgObgi4OiVkpCiUtYov7YU5wW1B194t0ww69ldvjktYouwWRYIGdkQ1Q+iJ28hp2Xn7B5zKzIPAlNw6S52wlbkL3mJJecOq+CBqeIJC6TjUJTMlcdz9lwLmriSuPgJBVbj/D+5SSXRequQVhNN4nIoEJhV77jKgs7B6bprJw85XtuU8GCpNlbSS3gSA4ii4QiTAvElDWpWeH41kxg5eZDSypUrtFKd1zTcA1EpHRDS5rUyQEts+VN7JjYOGR0TWhY6RdsOhc/Y9NoswUJjVoAAE+h555Rgcg2AAAAAElFTkSuQmCC -+#define libreplanet_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACfElEQVQ4jZXTS0hUcRTH8f+9M3fGd0gRRq1a2bZdBAotWtS6TQtB6IHgKzRy0UKqjRaRCAq+R21MDMsUR83JR5fJxhmaK2lzsWAWw+ToEHJxgnFm7reFIgza66z/58P/dzhHcESZpsluIsFPwyCVSmGa5lHPEEIIkdGYTqPPvqUlP4fK8nJ2DINYNEq71YJ3fv4QlAGkUynaj+VRdfUK7580M52rEN/ZYWNjg2GrjEMSPFXsmOn0YcA0TZ4V5tNZUkJTTTWfJiZIJhJ8U1VczwcZs0o4JUHzufM0ZGcf/OQASCaTxGIxDMNA00P8iEbpuXyJ8Tw77+wWJhWZQYuVbiHoFIKwpmUC4XCYzc1NDMMgHo9z8+IFvl6/xsf7D9ArbjOpyAxLEt1C0CUErfvJDwBd14lEImxvb/N9fR1fgY3egmyWsq0sO/poUyw4pb3mLiFolyRM09wDEokEfr+fUChEJBJh4HgBS7kKn92zLIy9ZriqklFZwiEEHfsRRp1O0un0HpDa3cU9M8PKygp3Tp5AzbKgZlmYt1uYtkn02q0MyYKmnBxWNI27Nhtut5tkMrkHmKZJbWkpqqryQpFxKTJTisyEVeaVRWJIlqgpLuZRWRkejwe/34/P58ucwZvWVhYXF5l2uejIzeHGqbM4ZYmB/dy1hUV8mJpibm4On8/H1tbW4T1YXV3F6/WysLDA5Pg4nfsDe5yfz8OiIjweD5qmEQwGf7/KwWCQtbU1NE2jRZbpEoI2SWKqr49lVUXX9T/fAkAgEKC/e5SW6mo6hKD+zGn6e0bw+/x/PyaA9S/rvOwfobGukfpbddyraMDR7iCwHPg34H9KCCF+Abts3KCj/p6aAAAAAElFTkSuQmCC - --#define addon_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAABOFBMVEUAAAAAzdwAydcAyNgA//8AzOYAydcAyNgAyNgA2NgAytoAzNkAytgAydgA29sA0egAyNgAyNgA//8AyNgAydgA//8Ay9cAydcAytkAz90Ay9gA1eoAydgAytsAyNgAytgAydkAydgAydgAyNgAydgAyNcAy9oAydgA//8AytsAy9kAytkAyNgAydgAydkAy9kAzP8AydgAydgAydgAz98AzN0AyNcAyNsAydcAydgAydgAydcAytgAytcAydcAydcAytcAydcAyNcAydcAy9gAztgAydcAydgAzOAAydcAyNgAyNgAytwAyNcAyNgAy9wAyNcAyNcAyNgAydgAyNcAydcAydgA0uEAydkAyNgAyeQA4+MAyNgAydkAzN0AyNsA1f8AyNgAydgAydcA1eMAydgAydcAyNdj6PGJAAAAZ3RSTlMAJFpBAQqm8qwNPiiPygcLv8QEw5cDQMA1JU4MwiuDbl/+6+m4+0XLAj9KePz9cjYFvervEA/IDsfFr+xcgeaOYIDo+ica1OMZ9bXlHe73LM3M35itxs8Rf5ATCbFeHjgGttC5ErzO3WvwaAAAAWxJREFUOMt9kudCwkAQhFcITQWCoaggiBqxoaixYUVsYMMGCmLXff838LIXCJAL84fvmCHsTg4AYMDhlIDkcnu8Po4w6BjiIA0joj+gY1BmGKLEiMIwHNFR9xGjuh8jpMQoYZjRGBGOA8QTHDEUB4hynABwcEqCT8GW2DNSnCYBnJzSoSk0NT2jcphlM/rRXpk5NkRgfmFxSWBml6MrOWNlWBUEEmDKtyYIrGttP66gSP4Nww8mUKzNLd5/zHaJbb1Tl9xnzR2WcGM/5QE8BLvJvf0Dc4HDo8IxUVECL5Vywv7s9Mzwz/WLcFHSsWy8w0sa9+qa/JtbOlUY3mnGLbjnCz9Q4JEfnhCrNb5nXi3w754p8MIPKVWpt6psGJ+vFJBbBUO3GlozzYdsSmCV1NlntiTnegNvPQ29Wx7h7fKrEUvg47PD/6oLpgh8m7//AZEav4b/J/bbb75SAzvR3crY+6y8fLGsQV9ZSvwHF4LQIhDjT+8AAAAASUVORK5CYII= -+#define hnode_icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABgElEQVQ4jaXRz2uSARzHcb0vlRGEzTVWISU1BVkFYTIyjNK1pKcxHA+yhWMWIamHYikFgpoLIi9jwegi3QbL9SzdLmMbM9J+DkJBgm5RDvEPeHeQHOyQz0OH9+V7ePGBr0pqpPmfVPsP8a0AR4MnMEwf48x9K0s/E8oAY9iEMOvD+8yP2qVjrhhRBnSN61n5sIpULqC+pGHh8wNlgEY8jPQXcGh4VXukDND5evYAl46odIuXtYdKAANSudAChO52/XeMZMohecCbcoGdH99Y+7LO72adT9+/4nh8nYOjBl7/SsoB8gBkpHk8T0S2K++pN3fRin3cfnFDHvCuWkI9rEMvHGEo5gbAHnXhnLF1BpZLeRaLOVT2A8Q3A5wMngXgWtKLxX9KPqC+rCWQvYkpeK4NWKcGOgO50ts2MJJ0cPreeQDciTHMchZYIhcwh2wcuqjn+ccwGm9v6wsTxxn0dVgQXZ7Ek3Agpq6QrcaQGmmebtxFSDkRU1fJVmL/BpT2ByV/3eDMhinRAAAAAElFTkSuQmCC - -@@ -21,29 +21,21 @@ -

-

@bookmarks_toolbarfolder@

-
@bookmarks_toolbarfolder_description@ --#ifndef NIGHTLY_BUILD -
--

@getting_started@
-+

Parabola GNU/Linux-libre
-
--

@firefox_heading@

-+

Parabola GNU/Linux-libre

-

--

@firefox_help@ --
@firefox_customize@ --
@firefox_community@ --
@firefox_about@ -+
Parabola GNU/Linux-libre -+
Parabola GNU/Linux-libre Packages -+
Parabola GNU/Linux-libre Wiki -+
Parabola GNU/Linux-libre Labs -
--#else --
--

@firefox_community@ --
--

@nightly_heading@

-+

Free Software Foundation

-

--

@nightly_blog@ --
@bugzilla@ --
@mdn@ --
@nightly_tester_tools@ --
@crashes@ --
@planet@ -+
Free Software Foundation -+
The GNU Operating System and the Free Software Movement -+
LibrePlanet -+
h-node -
--#endif -
-diff --git a/devtools/startup/aboutdevtools/aboutdevtools.xhtml b/devtools/startup/aboutdevtools/aboutdevtools.xhtml -index 5b0709e..38ea275 100644 ---- a/devtools/startup/aboutdevtools/aboutdevtools.xhtml -+++ b/devtools/startup/aboutdevtools/aboutdevtools.xhtml -@@ -89,19 +89,6 @@ -
    -
- -- --
-- -- --
- - - -diff --git a/devtools/startup/locales/en-US/aboutDevTools.ftl b/devtools/startup/locales/en-US/aboutDevTools.ftl -index db2146d..e02ab58 100644 ---- a/devtools/startup/locales/en-US/aboutDevTools.ftl -+++ b/devtools/startup/locales/en-US/aboutDevTools.ftl -@@ -3,18 +3,18 @@ - # file, You can obtain one at http://mozilla.org/MPL/2.0/. - - head-title = About Developer Tools --enable-title = Enable Firefox Developer Tools --enable-inspect-element-title = Enable Firefox Developer Tools to use Inspect Element -+enable-title = Enable Iceweasel Developer Tools -+enable-inspect-element-title = Enable Iceweasel Developer Tools to use Inspect Element - enable-inspect-element-message = Examine and edit HTML and CSS with the Developer Tools’ Inspector. --enable-about-debugging-message = Develop and debug WebExtensions, web workers, service workers and more with Firefox Developer Tools. -+enable-about-debugging-message = Develop and debug WebExtensions, web workers, service workers and more with Iceweasel Developer Tools. - enable-key-shortcut-message = You activated a Developer Tools shortcut. If that was a mistake, you can close this Tab. - enable-menu-message = Perfect your website’s HTML, CSS, and JavaScript with tools like Inspector and Debugger. --enable-common-message = Firefox Developer Tools are disabled by default to give you more control over your browser. -+enable-common-message = Iceweasel Developer Tools are disabled by default to give you more control over your browser. - enable-learn-more-link = Learn more about Developer Tools - enable-enable-button = Enable Developer Tools - enable-close-button = Close this Tab - --welcome-title = Welcome to Firefox Developer Tools! -+welcome-title = Welcome to Iceweasel Developer Tools! - newsletter-title = Mozilla Developer Newsletter - newsletter-message = Get developer news, tricks and resources sent straight to your inbox. - newsletter-email-placeholder = -@@ -24,8 +24,6 @@ newsletter-subscribe-button = Subscribe - newsletter-thanks-title = Thanks! - newsletter-thanks-message = If you haven’t previously confirmed a subscription to a Mozilla-related newsletter you may have to do so. Please check your inbox or your spam filter for an email from us. - --footer-title = Firefox Developer Edition --footer-message = Looking for more than just Developer Tools? Check out the Firefox browser that is built specifically for developers and modern workflows. - footer-learn-more-link = Learn more - - features-learn-more = Learn more -diff --git a/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl b/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl -index edd871b..77870fe 100644 ---- a/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl -+++ b/toolkit/locales/en-US/toolkit/about/aboutAddons.ftl -@@ -7,7 +7,7 @@ addons-window = - addons-page-title = Add-ons Manager - - search-header = -- .placeholder = Search addons.mozilla.org -+ .placeholder = Search www.parabola.nu/packages - .searchbuttonlabel = Search - - search-header-shortcut = -@@ -482,7 +482,7 @@ theme-heading-search-label = Find more themes - - default-heading-search-label = Find more add-ons - addons-heading-search-input = -- .placeholder = Search addons.mozilla.org -+ .placeholder = Search www.parabola.nu/packages - - addon-page-options-button = - .title = Tools for all add-ons -diff --git a/browser/components/newtab/lib/OnboardingMessageProvider.jsm b/browser/components/newtab/lib/OnboardingMessageProvider.jsm -index 02eb150..abb3af9 100644 ---- a/browser/components/newtab/lib/OnboardingMessageProvider.jsm -+++ b/browser/components/newtab/lib/OnboardingMessageProvider.jsm -@@ -270,7 +270,7 @@ const ONBOARDING_MESSAGES = () => [ - action: { type: "OPEN_PRIVATE_BROWSER_WINDOW" }, - }, - }, -- targeting: "'dynamic' in trailheadTriplet", -+ targeting: "trailheadTriplet in ['supercharge', 'static'] || 'dynamic' in trailheadTriplet", - trigger: { id: "showOnboarding" }, - }, - { -@@ -314,7 +314,7 @@ const ONBOARDING_MESSAGES = () => [ - }, - }, - targeting: -- "trailheadTriplet in ['supercharge', 'static'] || ('dynamic' in trailheadTriplet && sync.mobileDevices < 1)", -+ "false", - trigger: { id: "showOnboarding" }, - }, - { -diff --git a/browser/locales/en-US/chrome/browser-region/region.properties b/browser/locales/en-US/chrome/browser-region/region.properties -index 4c4ea76..e0f2880 100644 ---- a/browser/locales/en-US/chrome/browser-region/region.properties -+++ b/browser/locales/en-US/chrome/browser-region/region.properties -@@ -9,16 +9,3 @@ - # don't make any spelling errors here. - gecko.handlerService.defaultHandlersVersion=4 - --# The default set of protocol handlers for mailto: --gecko.handlerService.schemes.mailto.0.name=Yahoo! Mail --gecko.handlerService.schemes.mailto.0.uriTemplate=https://compose.mail.yahoo.com/?To=%s --gecko.handlerService.schemes.mailto.1.name=Gmail --gecko.handlerService.schemes.mailto.1.uriTemplate=https://mail.google.com/mail/?extsrc=mailto&url=%s -- --# The default set of protocol handlers for irc: --gecko.handlerService.schemes.irc.0.name=Mibbit --gecko.handlerService.schemes.irc.0.uriTemplate=https://www.mibbit.com/?url=%s -- --# The default set of protocol handlers for ircs: --gecko.handlerService.schemes.ircs.0.name=Mibbit --gecko.handlerService.schemes.ircs.0.uriTemplate=https://www.mibbit.com/?url=%s -diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js -index 2588a53cf2..e818b254d2 100644 ---- a/browser/app/profile/firefox.js -+++ b/browser/app/profile/firefox.js -@@ -1726,15 +1726,15 @@ pref("browser.contentblocking.report.monitor.enabled", true); - pref("browser.contentblocking.report.proxy.enabled", false); - - // Disable the mobile promotion by default. --pref("browser.contentblocking.report.show_mobile_app", true); -+pref("browser.contentblocking.report.show_mobile_app", false); - - // Enable the vpn card by default. --pref("browser.contentblocking.report.vpn.enabled", true); -+pref("browser.contentblocking.report.vpn.enabled", false); - // Only show vpn card to certain regions. Comma separated string of two letter ISO 3166-1 country codes. - pref("browser.contentblocking.report.vpn_regions", "us,ca,nz,sg,my,gb"); - // Comma separated string of mozilla vpn supported platforms. - pref("browser.contentblocking.report.vpn_platforms", "win"); --pref("browser.contentblocking.report.hide_vpn_banner", false); -+pref("browser.contentblocking.report.hide_vpn_banner", true); - pref("browser.contentblocking.report.vpn_sub_id", "sub_HrfCZF7VPHzZkA"); - - pref("browser.contentblocking.report.monitor.url", "https://monitor.firefox.com/?entrypoint=protection_report_monitor&utm_source=about-protections"); -@@ -1745,12 +1745,12 @@ pref("browser.contentblocking.report.monitor.home_page_url", "https://monitor.fi - pref("browser.contentblocking.report.manage_devices.url", "https://accounts.firefox.com/settings/clients"); - pref("browser.contentblocking.report.endpoint_url", "https://monitor.firefox.com/user/breach-stats?includeResolved=true"); - pref("browser.contentblocking.report.proxy_extension.url", "https://fpn.firefox.com/browser?utm_source=firefox-desktop&utm_medium=referral&utm_campaign=about-protections&utm_content=about-protections"); --pref("browser.contentblocking.report.mobile-ios.url", "https://apps.apple.com/app/firefox-private-safe-browser/id989804926"); --pref("browser.contentblocking.report.mobile-android.url", "https://play.google.com/store/apps/details?id=org.mozilla.firefox&referrer=utm_source%3Dprotection_report%26utm_content%3Dmobile_promotion"); --pref("browser.contentblocking.report.vpn.url", "https://vpn.mozilla.org/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=about-protections-card"); --pref("browser.contentblocking.report.vpn-promo.url", "https://vpn.mozilla.org/?utm_source=firefox-browser&utm_medium=firefox-browser&utm_campaign=about-protections-top-promo"); --pref("browser.contentblocking.report.vpn-android.url", "https://play.google.com/store/apps/details?id=org.mozilla.firefox.vpn&referrer=utm_source%3Dfirefox-browser%26utm_medium%3Dfirefox-browser%26utm_campaign%3Dabout-protections-mobile-vpn%26anid%3D--"); --pref("browser.contentblocking.report.vpn-ios.url", "https://apps.apple.com/us/app/firefox-private-network-vpn/id1489407738"); -+pref("browser.contentblocking.report.mobile-ios.url", ""); -+pref("browser.contentblocking.report.mobile-android.url", ""); -+pref("browser.contentblocking.report.vpn.url", ""); -+pref("browser.contentblocking.report.vpn-promo.url", ""); -+pref("browser.contentblocking.report.vpn-android.url", ""); -+pref("browser.contentblocking.report.vpn-ios.url", ""); - - // Protection Report's SUMO urls - pref("browser.contentblocking.report.lockwise.how_it_works.url", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/password-manager-report"); -diff --git a/browser/components/protections/content/protections.ftl b/browser/components/protections/content/protections.ftl -index 5ac8a7b08c..fec81698e3 100644 ---- a/browser/components/protections/content/protections.ftl -+++ b/browser/components/protections/content/protections.ftl -@@ -18,7 +18,7 @@ get-vpn-link = Get { -mozilla-vpn-brand-name } - - vpn-title-subscribed = VPN: Subscribed - # Note This text is not being translated, and the
will need to be removed if or when it does get translated --vpn-header-content-subscribed = Using the { -mozilla-vpn-brand-name } encrypts all your traffic and hides your location — on up to 5 devices. Get the most from your subscription — add it from
the Google Play Store or Apple App Store. -+vpn-header-content-subscribed = Using the { -mozilla-vpn-brand-name } encrypts all your traffic and hides your location — on up to 5 devices. - - vpn-banner-header = Protection that extends beyond the browser - # Note This text is not being translated, and the
will need to be removed if or when it does get translated -diff --git a/browser/components/protections/content/protections.html b/browser/components/protections/content/protections.html -index e33c814f62..5698f2b3e9 100644 ---- a/browser/components/protections/content/protections.html -+++ b/browser/components/protections/content/protections.html -@@ -303,8 +303,6 @@ - -

-

-- -- -

- - -diff --git a/browser/components/protections/content/vpn-card.js b/browser/components/protections/content/vpn-card.js -index 2417f1a641..698c48ccc3 100644 ---- a/browser/components/protections/content/vpn-card.js -+++ b/browser/components/protections/content/vpn-card.js -@@ -23,22 +23,6 @@ export default class VPNCard { - vpnLink.addEventListener("click", () => { - this.doc.sendTelemetryEvent("click", "vpn_card_link"); - }); -- let androidVPNAppLink = document.getElementById( -- "vpn-google-playstore-link" -- ); -- androidVPNAppLink.href = RPMGetStringPref( -- "browser.contentblocking.report.vpn-android.url" -- ); -- androidVPNAppLink.addEventListener("click", () => { -- document.sendTelemetryEvent("click", "vpn_app_link_android"); -- }); -- let iosVPNAppLink = document.getElementById("vpn-app-store-link"); -- iosVPNAppLink.href = RPMGetStringPref( -- "browser.contentblocking.report.vpn-ios.url" -- ); -- iosVPNAppLink.addEventListener("click", () => { -- document.sendTelemetryEvent("click", "vpn_app_link_ios"); -- }); - - const vpnBanner = this.doc.querySelector(".vpn-banner"); - const exitIcon = vpnBanner.querySelector(".exit-icon"); diff --git a/libre/iceweasel/process-json-files.py b/libre/iceweasel/process-json-files.py new file mode 100644 index 000000000..2fdde62d4 --- /dev/null +++ b/libre/iceweasel/process-json-files.py @@ -0,0 +1,174 @@ +#! /usr/bin/python3 + +# Copyright (C) 2020 grizzlyuser +# Based on: https://gitlab.trisquel.org/trisquel/wrapage-helpers/-/blob/81881d89b2bf7d502dd14fcccdb471fec6f6b206/helpers/DATA/firefox/reprocess-search-config.py +# Below is the notice from the original author: +# +# Copyright (C) 2020 Ruben Rodriguez +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import json +import sys +import time +import copy +import argparse +import pathlib +from collections import namedtuple +from jsonschema import validate + +parser = argparse.ArgumentParser() +parser.add_argument( + 'MAIN_PATH', + type=pathlib.Path, + help='path to main application source code directory') +parser.add_argument( + 'BRANDING_PATH', + type=pathlib.Path, + help='path to branding source code directory') +parser.add_argument( + '-i', + '--indent', + type=int, + help='indent for pretty printing of output files') +arguments = parser.parse_args() + +File = namedtuple('File', ['path', 'content']) + + +class RemoteSettings: + DUMPS_PATH = arguments.MAIN_PATH / 'services/settings/dumps' + JSON_PATHS = tuple(DUMPS_PATH.glob('*/*.json')) + WRAPPER_NAME = 'data' + + @classmethod + def wrap(cls, processed): + return File(processed.path, {cls.WRAPPER_NAME: processed.content}) + + @classmethod + def unwrap(cls, parsed_jsons): + return [File(json.path, json.content[cls.WRAPPER_NAME]) + for json in parsed_jsons] + + @classmethod + def process_raw(cls, unwrapped_jsons): + changes = [] + output_path = cls.DUMPS_PATH / 'monitor/changes.json' + + for collection in unwrapped_jsons: + if collection.path == cls.DUMPS_PATH / 'main/example.json': + continue + latest_change = {} + latest_change['last_modified'] = max( + (record['last_modified'] for record in collection.content), default=0) + latest_change['bucket'] = collection.path.parent.name + latest_change['collection'] = collection.path.stem + changes.append(latest_change) + + output_path.parent.mkdir(exist_ok=True) + + return File(output_path, changes) + + @classmethod + def process(cls, parsed_jsons): + return cls.wrap(cls.process_raw(cls.unwrap(parsed_jsons))) + + +class SearchConfig(RemoteSettings): + JSON_PATHS = (RemoteSettings.DUMPS_PATH / 'main/search-config.json',) + + def _get_schema(): + PATH = arguments.MAIN_PATH / \ + 'toolkit/components/search/schema/search-engine-config-schema.json' + with PATH.open() as file: + return json.load(file) + + @classmethod + def process_raw(cls, unwrapped_jsons): + _WHITELIST = ('ddg@search.mozilla.org', 'wikipedia@search.mozilla.org') + SCHEMA = cls._get_schema() + + search_engines, timestamps = [], [] + search_config = unwrapped_jsons[0] + + for search_engine in search_config.content: + if search_engine['webExtension']['id'] in _WHITELIST: + clone = copy.deepcopy(search_engine) + + if 'telemetryId' in search_engine: + del search_engine['telemetryId'] + if 'extraParams' in search_engine: + del search_engine['extraParams'] + + general_specifier = {} + for specifier in search_engine['appliesTo'].copy(): + if 'application' in specifier: + if 'distributions' in specifier['application']: + search_engine['appliesTo'].remove(specifier) + continue + if 'extraParams' in specifier['application']: + del specifier['application']['extraParams'] + + if 'included' in specifier and 'everywhere' in specifier[ + 'included'] and specifier['included']['everywhere']: + general_specifier = specifier + + if not general_specifier: + general_specifier = {'included': {'everywhere': True}} + search_engine['appliesTo'].insert(0, general_specifier) + if search_engine['webExtension']['id'] == _WHITELIST[0]: + general_specifier['default'] = 'yes' + + if clone != search_engine: + timestamp = int(round(time.time_ns() / 10 ** 6)) + while timestamp in timestamps: + timestamp += 1 + timestamps.append(timestamp) + search_engine['last_modified'] = timestamp + + validate(search_engine, schema=SCHEMA) + + search_engines.append(search_engine) + + return File(search_config.path, search_engines) + + +class TopSites: + JSON_PATHS = ( + arguments.MAIN_PATH / + 'browser/components/newtab/data/content/tippytop/top_sites.json', + arguments.BRANDING_PATH / + 'tippytop/top_sites.json') + + @classmethod + def process(cls, parsed_jsons): + main_top_sites = parsed_jsons[0] + branding_top_sites = parsed_jsons[1] + result = branding_top_sites.content + \ + [site for site in main_top_sites.content if site['title'] == 'wikipedia'] + return File(main_top_sites.path, result) + + +processors = (SearchConfig, TopSites, RemoteSettings) + +for processor in processors: + parsed_jsons = [] + for json_path in processor.JSON_PATHS: + with json_path.open() as file: + parsed_jsons.append(File(json_path, json.load(file))) + + processed = processor.process(parsed_jsons) + with processed.path.open('w') as file: + json.dump(processed.content, file, indent=arguments.indent) -- cgit v1.2.2