From b0e99b50a140deb4258fb9a73604a779fa21be4b Mon Sep 17 00:00:00 2001 From: Edward Lee Date: Tue, 28 Jul 2009 10:06:02 -0700 Subject: [PATCH] Bug 506795 - Handle adding duplicate logins. r=thunder Refactor reconcile to call findLikeId that by default will look for recordLike in the outgoing queue as it does now. Override findLikeId for password engine to search local logins. --- services/sync/modules/engines.js | 32 ++++++++++++++++------ services/sync/modules/engines/passwords.js | 17 ++++++------ 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/services/sync/modules/engines.js b/services/sync/modules/engines.js index b9eb84645a8c..f420c50a679e 100644 --- a/services/sync/modules/engines.js +++ b/services/sync/modules/engines.js @@ -356,6 +356,18 @@ SyncEngine.prototype = { Cu.forceGC(); }, + /** + * Find a GUID that is like the incoming item + * + * @return GUID of the similar record; falsy otherwise + */ + _findLikeId: function SyncEngine__findLikeId(item) { + // By default, only look in the outgoing queue for similar records + for (let id in this._tracker.changedIDs) + if (this._recordLike(item, this._createRecord(id))) + return id; + }, + _isEqual: function SyncEngine__isEqual(item) { let local = this._createRecord(item.id); this._log.trace("Local record: \n" + local); @@ -406,15 +418,17 @@ SyncEngine.prototype = { // Step 3: Check for similar items this._log.trace("Reconcile step 3"); - for (let id in this._tracker.changedIDs) { - let out = this._createRecord(id); - if (this._recordLike(item, out)) { - this._store.changeItemID(id, item.id); - this._tracker.removeChangedID(id); - this._tracker.removeChangedID(item.id); - this._store.cache.clear(); // because parentid refs will be wrong - return false; - } + let likeId = this._findLikeId(item); + if (likeId) { + // Change the local item GUID to the incoming one + this._store.changeItemID(likeId, item.id); + + // Remove outgoing changes of the original id any any that were just made + this._tracker.removeChangedID(likeId); + this._tracker.removeChangedID(item.id); + + this._store.cache.clear(); // because parentid refs will be wrong + return false; } return true; diff --git a/services/sync/modules/engines/passwords.js b/services/sync/modules/engines/passwords.js index 07673626a8d0..5bb23cd53bc2 100644 --- a/services/sync/modules/engines/passwords.js +++ b/services/sync/modules/engines/passwords.js @@ -61,14 +61,15 @@ PasswordEngine.prototype = { _trackerObj: PasswordTracker, _recordObj: LoginRec, - _recordLike: function SyncEngine__recordLike(a, b) { - if (a.deleted || b.deleted) - return false; - if (["hostname", "httpRealm", "username"].some(function(k) a[k] != b[k])) - return false; - if (!a.formSubmitURL || !b.formSubmitURL) - return true; - return a.formSubmitURL == b.formSubmitURL; + _findLikeId: function PasswordEngine__findLikeId(item) { + let login = this._store._nsLoginInfoFromRecord(item); + let logins = Svc.Login.findLogins({}, login.hostname, login.formSubmitURL, + login.httpRealm); + + // Look for existing logins that match the hostname but ignore the password + for each (let local in logins) + if (login.matches(local, true) && local instanceof Ci.nsILoginMetaInfo) + return local.guid; } };