1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-28 05:03:59 +03:00

Fix device tracking with initial /sync

* Check whether we share an e2e room with user IDs in the 'left'
   field of /keys/changes: there's no guarantee we no longer share
   any e2e rooms with these users
 * Reset everyone's tracking status on an initial sync - just
   re-fetching device lists for all users we're currently tracking
   isn't good enough since room memberships may have changed.
 * Fix typo in test
This commit is contained in:
David Baker
2018-01-17 16:03:46 +00:00
parent 585ea14a23
commit 5bab8647b6
4 changed files with 58 additions and 23 deletions

View File

@@ -366,9 +366,9 @@ describe("DeviceList management:", function() {
anotherTestClient.httpBackend.when('GET', '/sync').respond( anotherTestClient.httpBackend.when('GET', '/sync').respond(
200, getSyncResponse([])); 200, getSyncResponse([]));
await anotherTestClient.flushSync(); await anotherTestClient.flushSync();
await aliceTestClient.client._crypto._deviceList.saveIfDirty(); await anotherTestClient.client._crypto._deviceList.saveIfDirty();
aliceTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => { anotherTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => {
const bobStat = data.trackingStatus['@bob:xyz']; const bobStat = data.trackingStatus['@bob:xyz'];
expect(bobStat).toEqual( expect(bobStat).toEqual(

View File

@@ -417,6 +417,19 @@ export default class DeviceList {
this._dirty = true; this._dirty = true;
} }
/**
* Set all users we're currently tracking to untracked
*
* This will flag each user whose devices we are tracking as in need of an
* update.
*/
stopTrackingAllDeviceLists() {
for (const userId of Object.keys(this._deviceTrackingStatus)) {
this._deviceTrackingStatus[userId] = TRACKING_STATUS_NOT_TRACKED;
}
console.log("stopped tracking all: "+JSON.stringify(this._deviceTrackingStatus));
this._dirty = true;
}
/** /**
* Mark the cached device list for the given user outdated. * Mark the cached device list for the given user outdated.
@@ -440,18 +453,6 @@ export default class DeviceList {
this._dirty = true; this._dirty = true;
} }
/**
* Mark all tracked device lists as outdated.
*
* This will flag each user whose devices we are tracking as in need of an
* update.
*/
invalidateAllDeviceLists() {
for (const userId of Object.keys(this._deviceTrackingStatus)) {
this.invalidateUserDeviceList(userId);
}
}
/** /**
* If we have users who have outdated device lists, start key downloads for them * If we have users who have outdated device lists, start key downloads for them
* *

View File

@@ -894,6 +894,22 @@ Crypto.prototype.onCryptoEvent = async function(event) {
} }
}; };
/**
* Called before the result of a sync is procesed
*
* @param {Object} syncData the data from the 'MatrixClient.sync' event
*/
Crypto.prototype.onSyncWillProcess = async function(syncData) {
if (!syncData.oldSyncToken) {
// If there is no old sync token, we start all our tracking from
// scratch, so mark everything as untracked. onCryptoEvent will
// be called for all e2e rooms during the processing of the sync,
// at which point we'll start tracking all the users of that room.
console.log("Initial sync performed - resetting device tracking state");
this._deviceList.stopTrackingAllDeviceLists();
}
};
/** /**
* handle the completion of a /sync * handle the completion of a /sync
* *
@@ -905,14 +921,6 @@ Crypto.prototype.onCryptoEvent = async function(event) {
Crypto.prototype.onSyncCompleted = async function(syncData) { Crypto.prototype.onSyncCompleted = async function(syncData) {
const nextSyncToken = syncData.nextSyncToken; const nextSyncToken = syncData.nextSyncToken;
if (!syncData.oldSyncToken) {
// If we have a stored device sync token, we could request the complete
// list of device changes from the server here to get our device list up
// to date. This case should be relatively rare though (only when you hit
// 'clear cache and reload' in practice) so we just invalidate everything.
console.log("invalidating all device list caches after inital sync");
this._deviceList.invalidateAllDeviceLists();
}
this._deviceList.setSyncToken(syncData.nextSyncToken); this._deviceList.setSyncToken(syncData.nextSyncToken);
this._deviceList.saveIfDirty(); this._deviceList.saveIfDirty();
@@ -945,12 +953,32 @@ Crypto.prototype._evalDeviceListChanges = async function(deviceLists) {
} }
if (deviceLists.left && Array.isArray(deviceLists.left)) { if (deviceLists.left && Array.isArray(deviceLists.left)) {
const e2eUserIds = new Set(this._getE2eUsers());
deviceLists.left.forEach((u) => { deviceLists.left.forEach((u) => {
this._deviceList.stopTrackingDeviceList(u); if (!e2eUserIds.has(u)) {
this._deviceList.stopTrackingDeviceList(u);
}
}); });
} }
}; };
/**
* Get a list of all the IDs of users we share an e2e room with
*
* @returns {string[]} List of user IDs
*/
Crypto.prototype._getE2eUsers = function() {
const e2eUserIds = [];
for (const room of this._getE2eRooms()) {
const members = room.getJoinedMembers();
for (const member of members) {
e2eUserIds.push(member.userId);
}
}
return e2eUserIds;
};
/** /**
* Get a list of the e2e-enabled rooms we are members of * Get a list of the e2e-enabled rooms we are members of
* *

View File

@@ -627,6 +627,12 @@ SyncApi.prototype._sync = async function(syncOptions) {
catchingUp: this._catchingUp, catchingUp: this._catchingUp,
}; };
if (this.opts.crypto && !isCachedResponse) {
// tell the crypto module we're about to process a sync
// response
await this.opts.crypto.onSyncWillProcess(syncEventData);
}
try { try {
await this._processSyncResponse(syncEventData, data, isCachedResponse); await this._processSyncResponse(syncEventData, data, isCachedResponse);
} catch(e) { } catch(e) {