From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:33 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- services/sync/modules/UIState.sys.mjs | 2 +- services/sync/modules/bridged_engine.sys.mjs | 4 +-- services/sync/modules/collection_validator.sys.mjs | 4 +-- services/sync/modules/constants.sys.mjs | 2 +- services/sync/modules/engines.sys.mjs | 30 +++++++++---------- services/sync/modules/engines/bookmarks.sys.mjs | 8 ++--- services/sync/modules/engines/clients.sys.mjs | 2 +- .../sync/modules/engines/extension-storage.sys.mjs | 4 +-- services/sync/modules/engines/forms.sys.mjs | 2 +- services/sync/modules/engines/prefs.sys.mjs | 6 ++-- services/sync/modules/engines/tabs.sys.mjs | 4 +-- services/sync/modules/record.sys.mjs | 6 ++-- services/sync/modules/sync_auth.sys.mjs | 35 ++++++++++++---------- services/sync/modules/telemetry.sys.mjs | 4 +++ 14 files changed, 61 insertions(+), 52 deletions(-) (limited to 'services/sync/modules') diff --git a/services/sync/modules/UIState.sys.mjs b/services/sync/modules/UIState.sys.mjs index 8981d81f7d..6a45130cb1 100644 --- a/services/sync/modules/UIState.sys.mjs +++ b/services/sync/modules/UIState.sys.mjs @@ -87,7 +87,7 @@ const UIStateInternal = { this._initialized = false; }, - observe(subject, topic, data) { + observe(subject, topic) { switch (topic) { case "weave:service:sync:start": this.toggleSyncActivity(true); diff --git a/services/sync/modules/bridged_engine.sys.mjs b/services/sync/modules/bridged_engine.sys.mjs index 45e5f685cd..3e40a80505 100644 --- a/services/sync/modules/bridged_engine.sys.mjs +++ b/services/sync/modules/bridged_engine.sys.mjs @@ -43,7 +43,7 @@ class BridgedStore { this._batchChunkSize = 500; } - async applyIncomingBatch(records, countTelemetry) { + async applyIncomingBatch(records) { for (let chunk of lazy.PlacesUtils.chunkArray( records, this._batchChunkSize @@ -145,7 +145,7 @@ class InterruptedError extends Error { /** * Adapts a `Log.sys.mjs` logger to a `mozIServicesLogSink`. This class is copied - * from `SyncedBookmarksMirror.jsm`. + * from `SyncedBookmarksMirror.sys.mjs`. */ export class LogAdapter { constructor(log) { diff --git a/services/sync/modules/collection_validator.sys.mjs b/services/sync/modules/collection_validator.sys.mjs index a64ede10e9..1f40110ca9 100644 --- a/services/sync/modules/collection_validator.sys.mjs +++ b/services/sync/modules/collection_validator.sys.mjs @@ -114,13 +114,13 @@ export class CollectionValidator { // Return whether or not a server item should be present on the client. Expected // to be overridden. - clientUnderstands(item) { + clientUnderstands() { return true; } // Return whether or not a client item should be present on the server. Expected // to be overridden - async syncedByClient(item) { + async syncedByClient() { return true; } diff --git a/services/sync/modules/constants.sys.mjs b/services/sync/modules/constants.sys.mjs index 35c0ac2f0b..958e3345e6 100644 --- a/services/sync/modules/constants.sys.mjs +++ b/services/sync/modules/constants.sys.mjs @@ -4,7 +4,7 @@ // Don't manually modify this line, as it is automatically replaced on merge day // by the gecko_migration.py script. -export const WEAVE_VERSION = "1.126.0"; +export const WEAVE_VERSION = "1.127.0"; // Sync Server API version that the client supports. export const SYNC_API_VERSION = "1.5"; diff --git a/services/sync/modules/engines.sys.mjs b/services/sync/modules/engines.sys.mjs index 0d490ac4b3..63b4c02cc5 100644 --- a/services/sync/modules/engines.sys.mjs +++ b/services/sync/modules/engines.sys.mjs @@ -113,12 +113,12 @@ Tracker.prototype = { }, // Also unsupported. - async addChangedID(id, when) { + async addChangedID() { throw new TypeError("Can't add changed ID to this tracker"); }, // Ditto. - async removeChangedID(...ids) { + async removeChangedID() { throw new TypeError("Can't remove changed IDs from this tracker"); }, @@ -155,7 +155,7 @@ Tracker.prototype = { // Override these in your subclasses. onStart() {}, onStop() {}, - async observe(subject, topic, data) {}, + async observe() {}, engineIsEnabled() { if (!this.engine) { @@ -437,7 +437,7 @@ Store.prototype = { * @param record * The store record to create an item from */ - async create(record) { + async create() { throw new Error("override create in a subclass"); }, @@ -450,7 +450,7 @@ Store.prototype = { * @param record * The store record to delete an item from */ - async remove(record) { + async remove() { throw new Error("override remove in a subclass"); }, @@ -463,7 +463,7 @@ Store.prototype = { * @param record * The record to use to update an item from */ - async update(record) { + async update() { throw new Error("override update in a subclass"); }, @@ -477,7 +477,7 @@ Store.prototype = { * string record ID * @return boolean indicating whether record exists locally */ - async itemExists(id) { + async itemExists() { throw new Error("override itemExists in a subclass"); }, @@ -495,7 +495,7 @@ Store.prototype = { * constructor for the newly-created record. * @return record type for this engine */ - async createRecord(id, collection) { + async createRecord() { throw new Error("override createRecord in a subclass"); }, @@ -507,7 +507,7 @@ Store.prototype = { * @param newID * string new record ID */ - async changeItemID(oldID, newID) { + async changeItemID() { throw new Error("override changeItemID in a subclass"); }, @@ -1040,7 +1040,7 @@ SyncEngine.prototype = { * Note: Overriding engines must take resyncs into account -- score will not * be cleared. */ - shouldSkipSync(syncReason) { + shouldSkipSync() { return false; }, @@ -1550,7 +1550,7 @@ SyncEngine.prototype = { // Indicates whether an incoming item should be deleted from the server at // the end of the sync. Engines can override this method to clean up records // that shouldn't be on the server. - _shouldDeleteRemotely(remoteItem) { + _shouldDeleteRemotely() { return false; }, @@ -1560,7 +1560,7 @@ SyncEngine.prototype = { * * @return GUID of the similar item; falsy otherwise */ - async _findDupe(item) { + async _findDupe() { // By default, assume there's no dupe items for the engine }, @@ -1568,7 +1568,7 @@ SyncEngine.prototype = { * Called before a remote record is discarded due to failed reconciliation. * Used by bookmark sync to merge folder child orders. */ - beforeRecordDiscard(localRecord, remoteRecord, remoteIsNewer) {}, + beforeRecordDiscard() {}, // Called when the server has a record marked as deleted, but locally we've // changed it more recently than the deletion. If we return false, the @@ -1576,7 +1576,7 @@ SyncEngine.prototype = { // record to the server -- any extra work that's needed as part of this // process should be done at this point (such as mark the record's parent // for reuploading in the case of bookmarks). - async _shouldReviveRemotelyDeletedRecord(remoteItem) { + async _shouldReviveRemotelyDeletedRecord() { return true; }, @@ -1948,7 +1948,7 @@ SyncEngine.prototype = { } }, - async _onRecordsWritten(succeeded, failed, serverModifiedTime) { + async _onRecordsWritten() { // Implement this method to take specific actions against successfully // uploaded records and failed records. }, diff --git a/services/sync/modules/engines/bookmarks.sys.mjs b/services/sync/modules/engines/bookmarks.sys.mjs index 3c1396f67d..4995da6899 100644 --- a/services/sync/modules/engines/bookmarks.sys.mjs +++ b/services/sync/modules/engines/bookmarks.sys.mjs @@ -513,7 +513,7 @@ BookmarksEngine.prototype = { await this._apply(); }, - async _reconcile(item) { + async _reconcile() { return true; }, @@ -752,7 +752,7 @@ BookmarksStore.prototype = { }); }, - async applyIncomingBatch(records, countTelemetry) { + async applyIncomingBatch(records) { let buf = await this.ensureOpenMirror(); for (let chunk of lazy.PlacesUtils.chunkArray( records, @@ -921,11 +921,11 @@ Object.setPrototypeOf(BookmarksTracker.prototype, Tracker.prototype); class BookmarksChangeset extends Changeset { // Only `_reconcile` calls `getModifiedTimestamp` and `has`, and the engine // does its own reconciliation. - getModifiedTimestamp(id) { + getModifiedTimestamp() { throw new Error("Don't use timestamps to resolve bookmark conflicts"); } - has(id) { + has() { throw new Error("Don't use the changeset to resolve bookmark conflicts"); } diff --git a/services/sync/modules/engines/clients.sys.mjs b/services/sync/modules/engines/clients.sys.mjs index eda92bd75b..cb391982e0 100644 --- a/services/sync/modules/engines/clients.sys.mjs +++ b/services/sync/modules/engines/clients.sys.mjs @@ -1107,7 +1107,7 @@ ClientsTracker.prototype = { Svc.Obs.remove("fxaccounts:new_device_id", this.asyncObserver); }, - async observe(subject, topic, data) { + async observe(subject, topic) { switch (topic) { case "nsPref:changed": this._log.debug("client.name preference changed"); diff --git a/services/sync/modules/engines/extension-storage.sys.mjs b/services/sync/modules/engines/extension-storage.sys.mjs index d2671978c8..693d94f647 100644 --- a/services/sync/modules/engines/extension-storage.sys.mjs +++ b/services/sync/modules/engines/extension-storage.sys.mjs @@ -124,7 +124,7 @@ ExtensionStorageEngineBridge.prototype = { }, _takeMigrationInfo() { - return new Promise((resolve, reject) => { + return new Promise(resolve => { this.component .QueryInterface(Ci.mozIExtensionStorageArea) .takeMigrationInfo({ @@ -291,7 +291,7 @@ ExtensionStorageTracker.prototype = { lazy.Svc.Obs.remove("ext.storage.sync-changed", this.asyncObserver); }, - async observe(subject, topic, data) { + async observe(subject, topic) { if (this.ignoreAll) { return; } diff --git a/services/sync/modules/engines/forms.sys.mjs b/services/sync/modules/engines/forms.sys.mjs index 3516327659..0d63eb96d1 100644 --- a/services/sync/modules/engines/forms.sys.mjs +++ b/services/sync/modules/engines/forms.sys.mjs @@ -189,7 +189,7 @@ FormStore.prototype = { await this._processChange(change); }, - async update(record) { + async update() { this._log.trace("Ignoring form record update request!"); }, diff --git a/services/sync/modules/engines/prefs.sys.mjs b/services/sync/modules/engines/prefs.sys.mjs index f29a9e7b59..cb494ec70e 100644 --- a/services/sync/modules/engines/prefs.sys.mjs +++ b/services/sync/modules/engines/prefs.sys.mjs @@ -386,7 +386,7 @@ PrefStore.prototype = { return allprefs; }, - async changeItemID(oldID, newID) { + async changeItemID() { this._log.trace("PrefStore GUID is constant!"); }, @@ -406,11 +406,11 @@ PrefStore.prototype = { return record; }, - async create(record) { + async create() { this._log.trace("Ignoring create request"); }, - async remove(record) { + async remove() { this._log.trace("Ignoring remove request"); }, diff --git a/services/sync/modules/engines/tabs.sys.mjs b/services/sync/modules/engines/tabs.sys.mjs index 861e051d1a..93747665f2 100644 --- a/services/sync/modules/engines/tabs.sys.mjs +++ b/services/sync/modules/engines/tabs.sys.mjs @@ -430,7 +430,7 @@ export const TabProvider = { .then(iconData => { thisTab.icon = iconData.uri.spec; }) - .catch(ex => { + .catch(() => { log.trace( `Failed to fetch favicon for ${url}`, thisTab.urlHistory[0] @@ -503,7 +503,7 @@ TabTracker.prototype = { } }, - async observe(subject, topic, data) { + async observe(subject, topic) { switch (topic) { case "domwindowopened": let onLoad = () => { diff --git a/services/sync/modules/record.sys.mjs b/services/sync/modules/record.sys.mjs index 7d5918a8ca..f8580cfbd4 100644 --- a/services/sync/modules/record.sys.mjs +++ b/services/sync/modules/record.sys.mjs @@ -182,7 +182,7 @@ RawCryptoWrapper.prototype = { * @param {Cleartext} outgoingCleartext The cleartext to upload. * @returns {String} The serialized cleartext. */ - transformBeforeEncrypt(outgoingCleartext) { + transformBeforeEncrypt() { throw new TypeError("Override to stringify outgoing records"); }, @@ -194,7 +194,7 @@ RawCryptoWrapper.prototype = { * @param {String} incomingCleartext The decrypted cleartext string. * @returns {Cleartext} The parsed cleartext. */ - transformAfterDecrypt(incomingCleartext) { + transformAfterDecrypt() { throw new TypeError("Override to parse incoming records"); }, @@ -527,7 +527,7 @@ CollectionKeyManager.prototype = { /** * Create a WBO for the current keys. */ - asWBO(collection, id) { + asWBO() { return this._makeWBO(this._collections, this._default); }, diff --git a/services/sync/modules/sync_auth.sys.mjs b/services/sync/modules/sync_auth.sys.mjs index 6b8da4061c..cfa76827d5 100644 --- a/services/sync/modules/sync_auth.sys.mjs +++ b/services/sync/modules/sync_auth.sys.mjs @@ -164,7 +164,7 @@ SyncAuthManager.prototype = { this._token = null; }, - async observe(subject, topic, data) { + async observe(subject, topic) { this._log.debug("observed " + topic); if (!this.username) { this._log.info("Sync is not configured, so ignoring the notification"); @@ -276,7 +276,7 @@ SyncAuthManager.prototype = { * allows us to avoid a network request for when we actually need the * migration info. */ - prefetchMigrationSentinel(service) { + prefetchMigrationSentinel() { // nothing to do here until we decide to migrate away from FxA. }, @@ -387,22 +387,28 @@ SyncAuthManager.prototype = { // Do the token dance, with a retry in case of transient auth failure. // We need to prove that we know the sync key in order to get a token // from the tokenserver. - let getToken = async key => { + let getToken = async (key, accessToken) => { this._log.info("Getting a sync token from", this._tokenServerUrl); - let token = await this._fetchTokenUsingOAuth(key); + let token = await this._fetchTokenUsingOAuth(key, accessToken); this._log.trace("Successfully got a token"); return token; }; + const ttl = fxAccountsCommon.OAUTH_TOKEN_FOR_SYNC_LIFETIME_SECONDS; try { let token, key; try { this._log.info("Getting sync key"); - key = await fxa.keys.getKeyForScope(SCOPE_OLD_SYNC); + const tokenAndKey = await fxa.getOAuthTokenAndKey({ + scope: SCOPE_OLD_SYNC, + ttl, + }); + + key = tokenAndKey.key; if (!key) { throw new Error("browser does not have the sync key, cannot sync"); } - token = await getToken(key); + token = await getToken(key, tokenAndKey.token); } catch (err) { // If we get a 401 fetching the token it may be that our auth tokens needed // to be regenerated; retry exactly once. @@ -412,8 +418,11 @@ SyncAuthManager.prototype = { this._log.warn( "Token server returned 401, retrying token fetch with fresh credentials" ); - key = await fxa.keys.getKeyForScope(SCOPE_OLD_SYNC); - token = await getToken(key); + const tokenAndKey = await fxa.getOAuthTokenAndKey({ + scope: SCOPE_OLD_SYNC, + ttl, + }); + token = await getToken(tokenAndKey.key, tokenAndKey.token); } // TODO: Make it be only 80% of the duration, so refresh the token // before it actually expires. This is to avoid sync storage errors @@ -437,7 +446,7 @@ SyncAuthManager.prototype = { // A hawkclient error. } else if (err.code && err.code === 401) { err = new AuthenticationError(err, "hawkclient"); - // An FxAccounts.jsm error. + // An FxAccounts.sys.mjs error. } else if (err.message == fxAccountsCommon.ERROR_AUTH_ERROR) { err = new AuthenticationError(err, "fxaccounts"); } @@ -460,17 +469,13 @@ SyncAuthManager.prototype = { }, /** - * Generates an OAuth access_token using the OLD_SYNC scope and exchanges it - * for a TokenServer token. - * + * Exchanges an OAuth access_token for a TokenServer token. * @returns {Promise} * @private */ - async _fetchTokenUsingOAuth(key) { + async _fetchTokenUsingOAuth(key, accessToken) { this._log.debug("Getting a token using OAuth"); const fxa = this._fxaService; - const ttl = fxAccountsCommon.OAUTH_TOKEN_FOR_SYNC_LIFETIME_SECONDS; - const accessToken = await fxa.getOAuthToken({ scope: SCOPE_OLD_SYNC, ttl }); const headers = { "X-KeyId": key.kid, }; diff --git a/services/sync/modules/telemetry.sys.mjs b/services/sync/modules/telemetry.sys.mjs index c08f405b0e..28888ef277 100644 --- a/services/sync/modules/telemetry.sys.mjs +++ b/services/sync/modules/telemetry.sys.mjs @@ -241,10 +241,14 @@ export class ErrorSanitizer { NotAllowedError: this.E_PERMISSION_DENIED, }; + // IOUtils error messages include the specific nsresult error code that caused them. + static NS_ERROR_RE = new RegExp(/ \(NS_ERROR_.*\)$/); + static #cleanOSErrorMessage(message, error = undefined) { if (DOMException.isInstance(error)) { const sub = this.DOMErrorSubstitutions[error.name]; message = message.replaceAll("\\", "/"); + message = message.replace(this.NS_ERROR_RE, ""); if (sub) { return `${sub} ${message}`; } -- cgit v1.2.3