diff --git a/packages/lib/package-lock.json b/packages/lib/package-lock.json index 99272e757d1..0b51049e48c 100644 --- a/packages/lib/package-lock.json +++ b/packages/lib/package-lock.json @@ -20,6 +20,7 @@ "css": "^3.0.0", "diff-match-patch": "^1.0.4", "es6-promise-pool": "^2.5.0", + "fast-deep-equal": "^3.1.3", "file-uri-to-path": "^1.0.0", "follow-redirects": "^1.2.4", "form-data": "^2.1.4", diff --git a/packages/lib/package.json b/packages/lib/package.json index 7ec5ebd288b..27d9e9a936a 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -44,6 +44,7 @@ "css": "^3.0.0", "diff-match-patch": "^1.0.4", "es6-promise-pool": "^2.5.0", + "fast-deep-equal": "^3.1.3", "file-uri-to-path": "^1.0.0", "follow-redirects": "^1.2.4", "form-data": "^2.1.4", diff --git a/packages/lib/services/synchronizer/syncInfoUtils.test.ts b/packages/lib/services/synchronizer/syncInfoUtils.test.ts index 2a0db899efc..bbdb299e0ab 100644 --- a/packages/lib/services/synchronizer/syncInfoUtils.test.ts +++ b/packages/lib/services/synchronizer/syncInfoUtils.test.ts @@ -1,6 +1,6 @@ import { afterAllCleanUp, setupDatabaseAndSynchronizer, switchClient, encryptionService } from '../../testing/test-utils'; import MasterKey from '../../models/MasterKey'; -import { masterKeyEnabled, setMasterKeyEnabled } from './syncInfoUtils'; +import { masterKeyEnabled, setMasterKeyEnabled, SyncInfo, syncInfoEquals } from './syncInfoUtils'; describe('syncInfoUtils', function() { @@ -34,4 +34,62 @@ describe('syncInfoUtils', function() { expect(masterKeyEnabled(await MasterKey.load(mk2.id))).toBe(false); }); + it('should tell if two sync info are equal', async () => { + { + const syncInfo1 = new SyncInfo(); + const syncInfo2 = new SyncInfo(); + expect(syncInfoEquals(syncInfo1, syncInfo2)).toBe(true); + } + + { + const syncInfo1 = new SyncInfo(); + syncInfo1.masterKeys = [{ + id: 'id', + content: 'content', + }]; + + const syncInfo2 = new SyncInfo(); + syncInfo2.masterKeys = [{ + id: 'id', + content: 'different', + }]; + + expect(syncInfoEquals(syncInfo1, syncInfo2)).toBe(false); + } + + { + const syncInfo1 = new SyncInfo(); + syncInfo1.masterKeys = [{ + id: 'id', + content: 'content', + }]; + + const syncInfo2 = new SyncInfo(); + syncInfo2.masterKeys = [{ + id: 'id', + content: 'content', + }]; + + expect(syncInfoEquals(syncInfo1, syncInfo2)).toBe(true); + } + + { + // Should disregard object key order + + const syncInfo1 = new SyncInfo(); + syncInfo1.masterKeys = [{ + content: 'content', + id: 'id', + }]; + + const syncInfo2 = new SyncInfo(); + syncInfo2.masterKeys = [{ + id: 'id', + content: 'content', + }]; + + expect(syncInfoEquals(syncInfo1, syncInfo2)).toBe(true); + } + }); + }); diff --git a/packages/lib/services/synchronizer/syncInfoUtils.ts b/packages/lib/services/synchronizer/syncInfoUtils.ts index fc66aad19ba..38a9ccc450d 100644 --- a/packages/lib/services/synchronizer/syncInfoUtils.ts +++ b/packages/lib/services/synchronizer/syncInfoUtils.ts @@ -4,6 +4,7 @@ import Setting from '../../models/Setting'; import { State } from '../../reducer'; import { PublicPrivateKeyPair } from '../e2ee/ppk'; import { MasterKeyEntity } from '../e2ee/types'; +const fastDeepEqual = require('fast-deep-equal'); export interface SyncInfoValueBoolean { value: boolean; @@ -113,7 +114,7 @@ export function mergeSyncInfos(s1: SyncInfo, s2: SyncInfo): SyncInfo { } export function syncInfoEquals(s1: SyncInfo, s2: SyncInfo): boolean { - return s1.serialize() === s2.serialize(); + return fastDeepEqual(s1.toObject(), s2.toObject()); } export class SyncInfo {