Loading browser/components/BrowserGlue.sys.mjs +5 −0 Original line number Diff line number Diff line Loading @@ -1350,6 +1350,11 @@ BrowserGlue.prototype = { this._addBreachesSyncHandler(); }.bind(this), function RemoteSettingsPollChanges() { // Support clients that use the "sync" event or "remote-settings:changes-poll-end". lazy.RemoteSettings.pollChanges({ trigger: "timer" }); }, function searchBackgroundChecks() { Services.search.runBackgroundChecks(); }, Loading mobile/shared/chrome/geckoview/geckoview.js +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ ChromeUtils.defineESModuleGetters(this, { InitializationTracker: "resource://gre/modules/GeckoViewTelemetry.sys.mjs", RemoteSecuritySettings: "resource://gre/modules/psm/RemoteSecuritySettings.sys.mjs", RemoteSettings: "resource://services-settings/remote-settings.sys.mjs", SafeBrowsing: "resource://gre/modules/SafeBrowsing.sys.mjs", CaptchaDetectionPingUtils: "resource://gre/modules/CaptchaDetectionPingUtils.sys.mjs", Loading Loading @@ -930,6 +931,10 @@ function startup() { CaptchaDetectionPingUtils.init(); }); InitLater(() => { RemoteSettings.pollChanges({ trigger: "timer" }); }); // This should always go last, since the idle tasks (except for the ones with // timeouts) should execute in order. Note that this observer notification is // not guaranteed to fire, since the window could close before we get here. Loading services/settings/Attachments.sys.mjs +6 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,10 @@ export class Downloader { fallbackToDump = false; } avoidDownload = true; fallbackToCache = true; fallbackToDump = true; const dumpInfo = new LazyRecordAndBuffer(() => this._readAttachmentDump(attachmentId) ); Loading Loading @@ -521,6 +525,8 @@ export class Downloader { attachment: { location, hash, size }, } = record; return (await this.#fetchAttachment(record)).buffer; // eslint-disable-next-line no-unreachable let baseURL; try { baseURL = await lazy.Utils.baseAttachmentsURL(); Loading services/settings/RemoteSettingsClient.sys.mjs +29 −38 Original line number Diff line number Diff line Loading @@ -445,11 +445,19 @@ export class RemoteSettingsClient extends EventEmitter { order = "", // not sorted by default. dumpFallback = true, emptyListFallback = true, forceSync = false, loadDumpIfNewer = true, syncIfEmpty = true, } = options; let { verifySignature = false } = options; const hasLocalDump = await lazy.Utils.hasLocalDump( this.bucketName, this.collectionName ); if (!hasLocalDump) { return []; } const forceSync = false; const syncIfEmpty = true; let verifySignature = false; const hasParallelCall = !!this._importingPromise; let data; Loading Loading @@ -648,6 +656,10 @@ export class RemoteSettingsClient extends EventEmitter { * @param {object} options See #maybeSync() options. */ async sync(options) { if (AppConstants.BASE_BROWSER_VERSION) { return; } if (lazy.Utils.shouldSkipRemoteActivityDueToTests) { lazy.console.debug(`${this.identifier} Skip sync() due to tests.`); return; Loading Loading @@ -731,7 +743,7 @@ export class RemoteSettingsClient extends EventEmitter { let thrownError = null; try { // If network is offline, we can't synchronize. if (lazy.Utils.isOffline) { if (!AppConstants.BASE_BROWSER_VERSION && lazy.Utils.isOffline) { throw new RemoteSettingsClient.NetworkOfflineError(); } Loading Loading @@ -1152,8 +1164,6 @@ export class RemoteSettingsClient extends EventEmitter { ) { const hasLocalData = localTimestamp !== null; const { retry = false } = options; // On retry, we fully re-fetch the collection (no `?_since`). const since = retry || !hasLocalData ? undefined : `"${localTimestamp}"`; // Define an executor that will verify the signature of the local data. const verifySignatureLocalData = (resolve, reject) => { Loading Loading @@ -1181,23 +1191,11 @@ export class RemoteSettingsClient extends EventEmitter { }); }; // Fetch collection metadata and list of changes from server. lazy.console.debug( `${this.identifier} Fetch changes from server (expected=${expectedTimestamp}, since=${since})` ); const { metadata, remoteTimestamp, remoteRecords } = await this._fetchChangeset(expectedTimestamp, since); lazy.console.debug( `${this.identifier} local timestamp: ${localTimestamp}, remote: ${remoteTimestamp} (expected: ${expectedTimestamp})` ); let metadata, remoteTimestamp; if (remoteTimestamp < localTimestamp) { // This should never happen. Unless the CDN serves stale data. // If the local data is valid, then we can safely ignore this stage remote changeset. const localTrustworthy = await new Promise(verifySignatureLocalData); if (localTrustworthy) { lazy.console.info(`${this.identifier} CDN served staled data, ignore.`); try { await this._importJSONDump(); } catch (e) { return { current: localRecords, created: [], Loading @@ -1205,21 +1203,14 @@ export class RemoteSettingsClient extends EventEmitter { deleted: [], }; } // Otherwise, continue with importing, since we prefer stale data over corrupt/tempered. lazy.console.warn( `${this.identifier} CDN served staled data, but local data is corrupted, import anyway.` ); } await this.db.importChanges(metadata, remoteTimestamp, remoteRecords, { clear: retry, }); // Read the new local data, after updating. const newLocal = await this.db.list(); const newRecords = newLocal.map(r => this._cleanLocalFields(r)); // And verify the signature on what is now stored. if (this.verifySignature) { if (metadata === undefined) { // When working only with dumps, we do not have signatures. } else if (this.verifySignature) { try { await this.validateCollectionSignature( newRecords, Loading services/settings/dumps/gen_last_modified.py +2 −0 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ def main(output): dumps_locations = [] if buildconfig.substs["MOZ_BUILD_APP"] == "browser": dumps_locations += ["services/settings/dumps/"] dumps_locations += ["services/settings/static-dumps/"] elif buildconfig.substs["MOZ_BUILD_APP"] == "mobile/android": dumps_locations += ["services/settings/dumps/"] dumps_locations += ["services/settings/static-dumps/"] elif buildconfig.substs["MOZ_BUILD_APP"] == "mobile/ios": dumps_locations += ["services/settings/dumps/"] elif buildconfig.substs["MOZ_BUILD_APP"] == "comm/mail": Loading Loading
browser/components/BrowserGlue.sys.mjs +5 −0 Original line number Diff line number Diff line Loading @@ -1350,6 +1350,11 @@ BrowserGlue.prototype = { this._addBreachesSyncHandler(); }.bind(this), function RemoteSettingsPollChanges() { // Support clients that use the "sync" event or "remote-settings:changes-poll-end". lazy.RemoteSettings.pollChanges({ trigger: "timer" }); }, function searchBackgroundChecks() { Services.search.runBackgroundChecks(); }, Loading
mobile/shared/chrome/geckoview/geckoview.js +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ ChromeUtils.defineESModuleGetters(this, { InitializationTracker: "resource://gre/modules/GeckoViewTelemetry.sys.mjs", RemoteSecuritySettings: "resource://gre/modules/psm/RemoteSecuritySettings.sys.mjs", RemoteSettings: "resource://services-settings/remote-settings.sys.mjs", SafeBrowsing: "resource://gre/modules/SafeBrowsing.sys.mjs", CaptchaDetectionPingUtils: "resource://gre/modules/CaptchaDetectionPingUtils.sys.mjs", Loading Loading @@ -930,6 +931,10 @@ function startup() { CaptchaDetectionPingUtils.init(); }); InitLater(() => { RemoteSettings.pollChanges({ trigger: "timer" }); }); // This should always go last, since the idle tasks (except for the ones with // timeouts) should execute in order. Note that this observer notification is // not guaranteed to fire, since the window could close before we get here. Loading
services/settings/Attachments.sys.mjs +6 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,10 @@ export class Downloader { fallbackToDump = false; } avoidDownload = true; fallbackToCache = true; fallbackToDump = true; const dumpInfo = new LazyRecordAndBuffer(() => this._readAttachmentDump(attachmentId) ); Loading Loading @@ -521,6 +525,8 @@ export class Downloader { attachment: { location, hash, size }, } = record; return (await this.#fetchAttachment(record)).buffer; // eslint-disable-next-line no-unreachable let baseURL; try { baseURL = await lazy.Utils.baseAttachmentsURL(); Loading
services/settings/RemoteSettingsClient.sys.mjs +29 −38 Original line number Diff line number Diff line Loading @@ -445,11 +445,19 @@ export class RemoteSettingsClient extends EventEmitter { order = "", // not sorted by default. dumpFallback = true, emptyListFallback = true, forceSync = false, loadDumpIfNewer = true, syncIfEmpty = true, } = options; let { verifySignature = false } = options; const hasLocalDump = await lazy.Utils.hasLocalDump( this.bucketName, this.collectionName ); if (!hasLocalDump) { return []; } const forceSync = false; const syncIfEmpty = true; let verifySignature = false; const hasParallelCall = !!this._importingPromise; let data; Loading Loading @@ -648,6 +656,10 @@ export class RemoteSettingsClient extends EventEmitter { * @param {object} options See #maybeSync() options. */ async sync(options) { if (AppConstants.BASE_BROWSER_VERSION) { return; } if (lazy.Utils.shouldSkipRemoteActivityDueToTests) { lazy.console.debug(`${this.identifier} Skip sync() due to tests.`); return; Loading Loading @@ -731,7 +743,7 @@ export class RemoteSettingsClient extends EventEmitter { let thrownError = null; try { // If network is offline, we can't synchronize. if (lazy.Utils.isOffline) { if (!AppConstants.BASE_BROWSER_VERSION && lazy.Utils.isOffline) { throw new RemoteSettingsClient.NetworkOfflineError(); } Loading Loading @@ -1152,8 +1164,6 @@ export class RemoteSettingsClient extends EventEmitter { ) { const hasLocalData = localTimestamp !== null; const { retry = false } = options; // On retry, we fully re-fetch the collection (no `?_since`). const since = retry || !hasLocalData ? undefined : `"${localTimestamp}"`; // Define an executor that will verify the signature of the local data. const verifySignatureLocalData = (resolve, reject) => { Loading Loading @@ -1181,23 +1191,11 @@ export class RemoteSettingsClient extends EventEmitter { }); }; // Fetch collection metadata and list of changes from server. lazy.console.debug( `${this.identifier} Fetch changes from server (expected=${expectedTimestamp}, since=${since})` ); const { metadata, remoteTimestamp, remoteRecords } = await this._fetchChangeset(expectedTimestamp, since); lazy.console.debug( `${this.identifier} local timestamp: ${localTimestamp}, remote: ${remoteTimestamp} (expected: ${expectedTimestamp})` ); let metadata, remoteTimestamp; if (remoteTimestamp < localTimestamp) { // This should never happen. Unless the CDN serves stale data. // If the local data is valid, then we can safely ignore this stage remote changeset. const localTrustworthy = await new Promise(verifySignatureLocalData); if (localTrustworthy) { lazy.console.info(`${this.identifier} CDN served staled data, ignore.`); try { await this._importJSONDump(); } catch (e) { return { current: localRecords, created: [], Loading @@ -1205,21 +1203,14 @@ export class RemoteSettingsClient extends EventEmitter { deleted: [], }; } // Otherwise, continue with importing, since we prefer stale data over corrupt/tempered. lazy.console.warn( `${this.identifier} CDN served staled data, but local data is corrupted, import anyway.` ); } await this.db.importChanges(metadata, remoteTimestamp, remoteRecords, { clear: retry, }); // Read the new local data, after updating. const newLocal = await this.db.list(); const newRecords = newLocal.map(r => this._cleanLocalFields(r)); // And verify the signature on what is now stored. if (this.verifySignature) { if (metadata === undefined) { // When working only with dumps, we do not have signatures. } else if (this.verifySignature) { try { await this.validateCollectionSignature( newRecords, Loading
services/settings/dumps/gen_last_modified.py +2 −0 Original line number Diff line number Diff line Loading @@ -63,8 +63,10 @@ def main(output): dumps_locations = [] if buildconfig.substs["MOZ_BUILD_APP"] == "browser": dumps_locations += ["services/settings/dumps/"] dumps_locations += ["services/settings/static-dumps/"] elif buildconfig.substs["MOZ_BUILD_APP"] == "mobile/android": dumps_locations += ["services/settings/dumps/"] dumps_locations += ["services/settings/static-dumps/"] elif buildconfig.substs["MOZ_BUILD_APP"] == "mobile/ios": dumps_locations += ["services/settings/dumps/"] elif buildconfig.substs["MOZ_BUILD_APP"] == "comm/mail": Loading