From 21e0c79f7d8f447b79cf3e334ae54b4c7bf17d71 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 24 Aug 2018 10:55:59 +0200 Subject: [PATCH 01/10] Revert "Revert "Lazy loading: don't block on setting up room crypto"" This reverts commit 5cf2ebea4fc2728e5492c108b04120daa81bc610. --- spec/unit/room.spec.js | 3 + src/crypto/RoomList.js | 3 + src/crypto/index.js | 134 ++++++++++++++++++++++++++--------------- src/models/room.js | 5 ++ src/sync.js | 9 +-- 5 files changed, 100 insertions(+), 54 deletions(-) diff --git a/spec/unit/room.spec.js b/spec/unit/room.spec.js index eb5ba5a5145..b98559ecf5a 100644 --- a/spec/unit/room.spec.js +++ b/spec/unit/room.spec.js @@ -1318,6 +1318,9 @@ describe("Room", function() { // events should already be MatrixEvents return function(event) {return event;}; }, + isRoomEncrypted: function() { + return false; + }, _http: { serverResponse, authedRequest: function() { diff --git a/src/crypto/RoomList.js b/src/crypto/RoomList.js index 5bb437fb774..eb5b469c687 100644 --- a/src/crypto/RoomList.js +++ b/src/crypto/RoomList.js @@ -71,6 +71,9 @@ export default class RoomList { } async setRoomEncryption(roomId, roomInfo) { + // important that this happens before calling into the store + // as it prevents the Crypto::setRoomEncryption for calling + // this twice for consecutive m.room.encryption events this._roomEncryption[roomId] = roomInfo; await this._cryptoStore.doTxn( 'readwrite', [IndexedDBCryptoStore.STORE_ROOMS], (txn) => { diff --git a/src/crypto/index.js b/src/crypto/index.js index 77268cf2cf5..756fdb3e9c3 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -106,6 +106,10 @@ function Crypto(baseApis, sessionStore, userId, deviceId, this._receivedRoomKeyRequestCancellations = []; // true if we are currently processing received room key requests this._processingRoomKeyRequests = false; + // track if an initial tracking of all the room members + // has happened for a given room. This is delayed + // to avoid loading room members as long as possible. + this._roomDeviceTrackingState = {}; } utils.inherits(Crypto, EventEmitter); @@ -612,9 +616,6 @@ Crypto.prototype.getEventSenderDeviceInfo = function(event) { * @param {string} roomId The room ID to enable encryption in. * * @param {object} config The encryption config for the room. - * - * @param {boolean=} inhibitDeviceQuery true to suppress device list query for - * users in the room (for now) */ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDeviceQuery) { // if state is being replayed from storage, we might already have a configuration @@ -670,25 +671,42 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic if (storeConfigPromise) { await storeConfigPromise; } + console.log("Enabling encryption in " + roomId); +}; - // make sure we are tracking the device lists for all users in this room. - console.log("Enabling encryption in " + roomId + "; " + - "starting to track device lists for all users therein"); - const room = this._clientStore.getRoom(roomId); - if (!room) { - throw new Error(`Unable to enable encryption in unknown room ${roomId}`); - } - const members = await room.getEncryptionTargetMembers(); - members.forEach((m) => { - this._deviceList.startTrackingDeviceList(m.userId); - }); - if (!inhibitDeviceQuery) { - this._deviceList.refreshOutdatedDeviceLists(); +/** + * Make sure we are tracking the device lists for all users in this room. + * + * @param {string} roomId The room ID to start tracking devices in. + * @returns {Promise} when all devices for the room have been fetched and marked to track + */ +Crypto.prototype.trackRoomDevices = function(roomId) { + const trackAndRefresh = async () => { + // not an encrypted room + if (!this._roomEncryptors[roomId]) { + return; + } + const room = this._clientStore.getRoom(roomId); + if (!room) { + throw new Error(`Unable to start tracking devices in unknown room ${roomId}`); + } + console.log(`Starting to track devices for room ${roomId} ...`); + const members = await room.getEncryptionTargetMembers(); + members.forEach((m) => { + this._deviceList.startTrackingDeviceList(m.userId); + }); + return this._deviceList.refreshOutdatedDeviceLists(); + }; + + let promise = this._roomDeviceTrackingState[roomId]; + if (!promise) { + promise = trackAndRefresh(); + this._roomDeviceTrackingState[roomId] = promise; } + return promise; }; - /** * @typedef {Object} module:crypto~OlmSessionResult * @property {module:crypto/deviceinfo} device device info @@ -779,7 +797,7 @@ Crypto.prototype.importRoomKeys = function(keys) { }, ); }; - +/* eslint-disable valid-jsdoc */ //https://github.com/eslint/eslint/issues/7307 /** * Encrypt an event according to the configuration of the room. * @@ -790,7 +808,8 @@ Crypto.prototype.importRoomKeys = function(keys) { * @return {module:client.Promise?} Promise which resolves when the event has been * encrypted, or null if nothing was needed */ -Crypto.prototype.encryptEvent = function(event, room) { +/* eslint-enable valid-jsdoc */ +Crypto.prototype.encryptEvent = async function(event, room) { if (!room) { throw new Error("Cannot send encrypted messages in unknown rooms"); } @@ -808,6 +827,12 @@ Crypto.prototype.encryptEvent = function(event, room) { ); } + if (!this._roomDeviceTrackingState[roomId]) { + this.trackRoomDevices(roomId); + } + // wait for all the room devices to be loaded + await this._roomDeviceTrackingState[roomId]; + let content = event.getContent(); // If event has an m.relates_to then we need // to put this on the wrapping event instead @@ -818,20 +843,19 @@ Crypto.prototype.encryptEvent = function(event, room) { delete content['m.relates_to']; } - return alg.encryptMessage( - room, event.getType(), content, - ).then((encryptedContent) => { - if (mRelatesTo) { - encryptedContent['m.relates_to'] = mRelatesTo; - } + const encryptedContent = await alg.encryptMessage( + room, event.getType(), content); - event.makeEncrypted( - "m.room.encrypted", - encryptedContent, - this._olmDevice.deviceCurve25519Key, - this._olmDevice.deviceEd25519Key, - ); - }); + if (mRelatesTo) { + encryptedContent['m.relates_to'] = mRelatesTo; + } + + event.makeEncrypted( + "m.room.encrypted", + encryptedContent, + this._olmDevice.deviceCurve25519Key, + this._olmDevice.deviceEd25519Key, + ); }; /** @@ -924,9 +948,7 @@ Crypto.prototype.onCryptoEvent = async function(event) { const content = event.getContent(); try { - // inhibit the device list refresh for now - it will happen once we've - // finished processing the sync, in onSyncCompleted. - await this.setRoomEncryption(roomId, content, true); + await this.setRoomEncryption(roomId, content); } catch (e) { console.error("Error configuring encryption in room " + roomId + ":", e); @@ -946,6 +968,7 @@ Crypto.prototype.onSyncWillProcess = async function(syncData) { // 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(); + this._roomDeviceTrackingState = {}; } }; @@ -991,11 +1014,12 @@ Crypto.prototype._evalDeviceListChanges = async function(deviceLists) { }); } - if (deviceLists.left && Array.isArray(deviceLists.left)) { + if (deviceLists.left && Array.isArray(deviceLists.left) && + deviceLists.left.length) { // Check we really don't share any rooms with these users // any more: the server isn't required to give us the // exact correct set. - const e2eUserIds = new Set(await this._getE2eUsers()); + const e2eUserIds = new Set(await this._getTrackedE2eUsers()); deviceLists.left.forEach((u) => { if (!e2eUserIds.has(u)) { @@ -1007,12 +1031,13 @@ Crypto.prototype._evalDeviceListChanges = async function(deviceLists) { /** * Get a list of all the IDs of users we share an e2e room with + * for which we are tracking devices already * * @returns {string[]} List of user IDs */ -Crypto.prototype._getE2eUsers = async function() { +Crypto.prototype._getTrackedE2eUsers = async function() { const e2eUserIds = []; - for (const room of this._getE2eRooms()) { + for (const room of this._getTrackedE2eRooms()) { const members = await room.getEncryptionTargetMembers(); for (const member of members) { e2eUserIds.push(member.userId); @@ -1022,17 +1047,21 @@ Crypto.prototype._getE2eUsers = async function() { }; /** - * Get a list of the e2e-enabled rooms we are members of + * Get a list of the e2e-enabled rooms we are members of, + * and for which we are already tracking the devices * * @returns {module:models.Room[]} */ -Crypto.prototype._getE2eRooms = function() { +Crypto.prototype._getTrackedE2eRooms = function() { return this._clientStore.getRooms().filter((room) => { // check for rooms with encryption enabled const alg = this._roomEncryptors[room.roomId]; if (!alg) { return false; } + if (!this._roomDeviceTrackingState[room.roomId]) { + return false; + } // ignore any rooms which we have left const myMembership = room.getMyMembership(); @@ -1101,15 +1130,20 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) { // not encrypting in this room return; } - - if (member.membership == 'join') { - console.log('Join event for ' + member.userId + ' in ' + roomId); - // make sure we are tracking the deviceList for this user - this._deviceList.startTrackingDeviceList(member.userId); - } else if (member.membership == 'invite' && - this._clientStore.getRoom(roomId).shouldEncryptForInvitedMembers()) { - console.log('Invite event for ' + member.userId + ' in ' + roomId); - this._deviceList.startTrackingDeviceList(member.userId); + // only mark users in this room as tracked if we already started tracking in this room + // this way we don't start device queries after sync on behalf of this room which we won't use + // the result of anyway, as we'll need to do a query again once all the members are fetched + // by calling _trackRoomDevices + if (this._roomDeviceTrackingState[roomId]) { + if (member.membership == 'join') { + console.log('Join event for ' + member.userId + ' in ' + roomId); + // make sure we are tracking the deviceList for this user + this._deviceList.startTrackingDeviceList(member.userId); + } else if (member.membership == 'invite' && + this._clientStore.getRoom(roomId).shouldEncryptForInvitedMembers()) { + console.log('Invite event for ' + member.userId + ' in ' + roomId); + this._deviceList.startTrackingDeviceList(member.userId); + } } alg.onRoomMembership(event, member, oldMembership); diff --git a/src/models/room.js b/src/models/room.js index 94115ef45cf..dc1052ea456 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -368,6 +368,11 @@ Room.prototype.loadMembersIfNeeded = function() { }); this._membersPromise = promise; + // now the members are loaded, start to track the e2e devices if needed + if (this._client.isRoomEncrypted(this.roomId)) { + this._client._crypto.trackRoomDevices(this.roomId); + } + return this._membersPromise; }; diff --git a/src/sync.js b/src/sync.js index 4aa2d24822f..d8dffe6b30b 100644 --- a/src/sync.js +++ b/src/sync.js @@ -1085,15 +1085,16 @@ SyncApi.prototype._processSyncResponse = async function( self._processEventsForNotifs(room, timelineEvents); - async function processRoomEvent(e) { + function processRoomEvent(e) { client.emit("event", e); if (e.isState() && e.getType() == "m.room.encryption" && self.opts.crypto) { - await self.opts.crypto.onCryptoEvent(e); + self.opts.crypto.onCryptoEvent(e); } } - await Promise.mapSeries(stateEvents, processRoomEvent); - await Promise.mapSeries(timelineEvents, processRoomEvent); + stateEvents.forEach(processRoomEvent); + timelineEvents.forEach(processRoomEvent); + ephemeralEvents.forEach(function(e) { client.emit("event", e); }); From 7247762b60fba020003585a55a16e0e9029fc127 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 23 Aug 2018 18:44:06 +0200 Subject: [PATCH 02/10] Also support not lazy-loading members in Crypto --- src/client.js | 4 ++++ src/crypto/index.js | 35 +++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/client.js b/src/client.js index 54f9647f224..1f3a4813072 100644 --- a/src/client.js +++ b/src/client.js @@ -3098,6 +3098,10 @@ MatrixClient.prototype.startClient = async function(opts) { } } + if (opts.lazyLoadMembers && this._crypto) { + this._crypto.enableLazyLoading(); + } + opts.crypto = this._crypto; opts.canResetEntireTimeline = (roomId) => { if (!this._canResetTimelineCallback) { diff --git a/src/crypto/index.js b/src/crypto/index.js index 756fdb3e9c3..4f414314afb 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -106,6 +106,11 @@ function Crypto(baseApis, sessionStore, userId, deviceId, this._receivedRoomKeyRequestCancellations = []; // true if we are currently processing received room key requests this._processingRoomKeyRequests = false; + // controls whether device tracking is delayed + // until calling encryptEvent or trackRoomDevices, + // or done immediately upon enabling room encryption. + this._lazyLoadMembers = false; + // in case _lazyLoadMembers is true, // track if an initial tracking of all the room members // has happened for a given room. This is delayed // to avoid loading room members as long as possible. @@ -171,6 +176,15 @@ Crypto.prototype.init = async function() { } }; + + + +/** + */ +Crypto.prototype.enableLazyLoading = function() { + this._lazyLoadMembers = true; +}; + /** * Tell the crypto module to register for MatrixClient events which it needs to * listen for @@ -672,6 +686,13 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic await storeConfigPromise; } console.log("Enabling encryption in " + roomId); + + if (!this._lazyLoadMembers) { + const members = await room.getEncryptionTargetMembers(); + members.forEach((m) => { + this._deviceList.startTrackingDeviceList(m.userId); + }); + } }; @@ -827,11 +848,13 @@ Crypto.prototype.encryptEvent = async function(event, room) { ); } - if (!this._roomDeviceTrackingState[roomId]) { - this.trackRoomDevices(roomId); + if (this._lazyLoadMembers) { + if (!this._roomDeviceTrackingState[roomId]) { + this.trackRoomDevices(roomId); + } + // wait for all the room devices to be loaded + await this._roomDeviceTrackingState[roomId]; } - // wait for all the room devices to be loaded - await this._roomDeviceTrackingState[roomId]; let content = event.getContent(); // If event has an m.relates_to then we need @@ -1059,7 +1082,7 @@ Crypto.prototype._getTrackedE2eRooms = function() { if (!alg) { return false; } - if (!this._roomDeviceTrackingState[room.roomId]) { + if (this._lazyLoadMembers && !this._roomDeviceTrackingState[room.roomId]) { return false; } @@ -1134,7 +1157,7 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) { // this way we don't start device queries after sync on behalf of this room which we won't use // the result of anyway, as we'll need to do a query again once all the members are fetched // by calling _trackRoomDevices - if (this._roomDeviceTrackingState[roomId]) { + if (!this._lazyLoadMembers || this._roomDeviceTrackingState[roomId]) { if (member.membership == 'join') { console.log('Join event for ' + member.userId + ' in ' + roomId); // make sure we are tracking the deviceList for this user From 5e5994f1669e658b943b9a811aac43b5ef805b0b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 23 Aug 2018 19:49:23 +0200 Subject: [PATCH 03/10] try and fix tests --- spec/integ/devicelist-integ-spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/integ/devicelist-integ-spec.js b/spec/integ/devicelist-integ-spec.js index f3f889deb74..b6ed84267a8 100644 --- a/spec/integ/devicelist-integ-spec.js +++ b/spec/integ/devicelist-integ-spec.js @@ -331,8 +331,8 @@ describe("DeviceList management:", function() { aliceTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => { const bobStat = data.trackingStatus['@bob:xyz']; - expect(bobStat).toEqual( - 0, "Alice should have marked bob's device list as untracked", + expect(bobStat).toBeFalsy( //0 or undefined + "Alice should have marked bob's device list as untracked", ); }); }); @@ -367,8 +367,8 @@ describe("DeviceList management:", function() { aliceTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => { const bobStat = data.trackingStatus['@bob:xyz']; - expect(bobStat).toEqual( - 0, "Alice should have marked bob's device list as untracked", + expect(bobStat).toBeFalsy( //0 or undefined + "Alice should have marked bob's device list as untracked", ); }); }); @@ -388,8 +388,8 @@ describe("DeviceList management:", function() { anotherTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => { const bobStat = data.trackingStatus['@bob:xyz']; - expect(bobStat).toEqual( - 0, "Alice should have marked bob's device list as untracked", + expect(bobStat).toBeFalsy( //0 or undefined + "Alice should have marked bob's device list as untracked", ); }); } finally { From 7d00c0bd5a9de739eec80ae812464198b7deb3db Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 23 Aug 2018 23:38:53 +0200 Subject: [PATCH 04/10] make LL/non-LL flow in Crypto more alike by always going through _roomDeviceTrackingState --- src/crypto/index.js | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/crypto/index.js b/src/crypto/index.js index 4f414314afb..cbc9318d484 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -688,10 +688,7 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic console.log("Enabling encryption in " + roomId); if (!this._lazyLoadMembers) { - const members = await room.getEncryptionTargetMembers(); - members.forEach((m) => { - this._deviceList.startTrackingDeviceList(m.userId); - }); + await this.trackRoomDevices(roomId); } }; @@ -717,7 +714,6 @@ Crypto.prototype.trackRoomDevices = function(roomId) { members.forEach((m) => { this._deviceList.startTrackingDeviceList(m.userId); }); - return this._deviceList.refreshOutdatedDeviceLists(); }; let promise = this._roomDeviceTrackingState[roomId]; @@ -848,13 +844,11 @@ Crypto.prototype.encryptEvent = async function(event, room) { ); } - if (this._lazyLoadMembers) { - if (!this._roomDeviceTrackingState[roomId]) { - this.trackRoomDevices(roomId); - } - // wait for all the room devices to be loaded - await this._roomDeviceTrackingState[roomId]; + if (!this._roomDeviceTrackingState[roomId]) { + this.trackRoomDevices(roomId); } + // wait for all the room devices to be loaded + await this._roomDeviceTrackingState[roomId]; let content = event.getContent(); // If event has an m.relates_to then we need @@ -1082,7 +1076,7 @@ Crypto.prototype._getTrackedE2eRooms = function() { if (!alg) { return false; } - if (this._lazyLoadMembers && !this._roomDeviceTrackingState[room.roomId]) { + if (!this._roomDeviceTrackingState[room.roomId]) { return false; } @@ -1157,7 +1151,7 @@ Crypto.prototype._onRoomMembership = function(event, member, oldMembership) { // this way we don't start device queries after sync on behalf of this room which we won't use // the result of anyway, as we'll need to do a query again once all the members are fetched // by calling _trackRoomDevices - if (!this._lazyLoadMembers || this._roomDeviceTrackingState[roomId]) { + if (this._roomDeviceTrackingState[roomId]) { if (member.membership == 'join') { console.log('Join event for ' + member.userId + ' in ' + roomId); // make sure we are tracking the deviceList for this user From 362bf1895dde40776dc9f15e66ad5c8ded5dbd56 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 27 Aug 2018 11:12:00 +0200 Subject: [PATCH 05/10] restore inhibitDeviceQuery param to avoid breaking change --- src/crypto/index.js | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/crypto/index.js b/src/crypto/index.js index cbc9318d484..43e092c722e 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -176,9 +176,6 @@ Crypto.prototype.init = async function() { } }; - - - /** */ Crypto.prototype.enableLazyLoading = function() { @@ -630,6 +627,10 @@ Crypto.prototype.getEventSenderDeviceInfo = function(event) { * @param {string} roomId The room ID to enable encryption in. * * @param {object} config The encryption config for the room. + * + * @param {boolean=} inhibitDeviceQuery true to suppress device list query for + * users in the room (for now). In case lazy loading is enabled, + * the device query is always inhibited as the members are not tracked. */ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDeviceQuery) { // if state is being replayed from storage, we might already have a configuration @@ -685,10 +686,21 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic if (storeConfigPromise) { await storeConfigPromise; } - console.log("Enabling encryption in " + roomId); if (!this._lazyLoadMembers) { + console.log("Enabling encryption in " + roomId + "; " + + "starting to track device lists for all users therein"); + await this.trackRoomDevices(roomId); + // TODO: this flag is only not used from MatrixClient::setRoomEncryption + // which is never used (inside riot at least) + // but didn't want to remove it as it technically would + // be a breaking change. + if(!this.inhibitDeviceQuery) { + this._deviceList.refreshOutdatedDeviceLists(); + } + } else { + console.log("Enabling encryption in " + roomId); } }; @@ -700,7 +712,7 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic * @returns {Promise} when all devices for the room have been fetched and marked to track */ Crypto.prototype.trackRoomDevices = function(roomId) { - const trackAndRefresh = async () => { + const trackMembers = async () => { // not an encrypted room if (!this._roomEncryptors[roomId]) { return; @@ -718,7 +730,7 @@ Crypto.prototype.trackRoomDevices = function(roomId) { let promise = this._roomDeviceTrackingState[roomId]; if (!promise) { - promise = trackAndRefresh(); + promise = trackMembers(); this._roomDeviceTrackingState[roomId] = promise; } return promise; @@ -965,7 +977,7 @@ Crypto.prototype.onCryptoEvent = async function(event) { const content = event.getContent(); try { - await this.setRoomEncryption(roomId, content); + await this.setRoomEncryption(roomId, content, true); } catch (e) { console.error("Error configuring encryption in room " + roomId + ":", e); From ad71bb30acc380ea03a38b972da5a3e4ae1aca8a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 27 Aug 2018 11:51:29 +0200 Subject: [PATCH 06/10] add comment back as we kept flag in the end --- src/crypto/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/crypto/index.js b/src/crypto/index.js index 43e092c722e..4f6dbd24e3c 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -977,6 +977,8 @@ Crypto.prototype.onCryptoEvent = async function(event) { const content = event.getContent(); try { + // inhibit the device list refresh for now - it will happen once we've + // finished processing the sync, in onSyncCompleted. await this.setRoomEncryption(roomId, content, true); } catch (e) { console.error("Error configuring encryption in room " + roomId + From 4e25867548886582e8dd45dbc69c13919ae21963 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 27 Aug 2018 11:56:46 +0200 Subject: [PATCH 07/10] revert to async event processing without LL, we could refresh the device list before all members have been tracked. as promises, even resolved ones (in case of no LL), always continue async --- src/sync.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sync.js b/src/sync.js index d8dffe6b30b..ac6c6272b86 100644 --- a/src/sync.js +++ b/src/sync.js @@ -1085,15 +1085,15 @@ SyncApi.prototype._processSyncResponse = async function( self._processEventsForNotifs(room, timelineEvents); - function processRoomEvent(e) { + async function processRoomEvent(e) { client.emit("event", e); if (e.isState() && e.getType() == "m.room.encryption" && self.opts.crypto) { - self.opts.crypto.onCryptoEvent(e); + await self.opts.crypto.onCryptoEvent(e); } } - stateEvents.forEach(processRoomEvent); - timelineEvents.forEach(processRoomEvent); + await Promise.mapSeries(stateEvents, processRoomEvent); + await Promise.mapSeries(timelineEvents, processRoomEvent); ephemeralEvents.forEach(function(e) { client.emit("event", e); From c47445ca987feb340f78b1d91185b731d4c6549a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 27 Aug 2018 12:01:22 +0200 Subject: [PATCH 08/10] no need to just add a space now --- src/sync.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sync.js b/src/sync.js index ac6c6272b86..4aa2d24822f 100644 --- a/src/sync.js +++ b/src/sync.js @@ -1094,7 +1094,6 @@ SyncApi.prototype._processSyncResponse = async function( await Promise.mapSeries(stateEvents, processRoomEvent); await Promise.mapSeries(timelineEvents, processRoomEvent); - ephemeralEvents.forEach(function(e) { client.emit("event", e); }); From 85f1da1f10359ac641374f49ad66b2f53857c8fa Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 27 Aug 2018 12:09:10 +0200 Subject: [PATCH 09/10] revert unnecesary changes --- spec/integ/devicelist-integ-spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/integ/devicelist-integ-spec.js b/spec/integ/devicelist-integ-spec.js index b6ed84267a8..f3f889deb74 100644 --- a/spec/integ/devicelist-integ-spec.js +++ b/spec/integ/devicelist-integ-spec.js @@ -331,8 +331,8 @@ describe("DeviceList management:", function() { aliceTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => { const bobStat = data.trackingStatus['@bob:xyz']; - expect(bobStat).toBeFalsy( //0 or undefined - "Alice should have marked bob's device list as untracked", + expect(bobStat).toEqual( + 0, "Alice should have marked bob's device list as untracked", ); }); }); @@ -367,8 +367,8 @@ describe("DeviceList management:", function() { aliceTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => { const bobStat = data.trackingStatus['@bob:xyz']; - expect(bobStat).toBeFalsy( //0 or undefined - "Alice should have marked bob's device list as untracked", + expect(bobStat).toEqual( + 0, "Alice should have marked bob's device list as untracked", ); }); }); @@ -388,8 +388,8 @@ describe("DeviceList management:", function() { anotherTestClient.cryptoStore.getEndToEndDeviceData(null, (data) => { const bobStat = data.trackingStatus['@bob:xyz']; - expect(bobStat).toBeFalsy( //0 or undefined - "Alice should have marked bob's device list as untracked", + expect(bobStat).toEqual( + 0, "Alice should have marked bob's device list as untracked", ); }); } finally { From a6ebfe4215633bc2dcff56755a14d7ba3ea1c358 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 28 Aug 2018 15:31:20 +0200 Subject: [PATCH 10/10] typo --- src/crypto/RoomList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/RoomList.js b/src/crypto/RoomList.js index eb5b469c687..1f0234548f8 100644 --- a/src/crypto/RoomList.js +++ b/src/crypto/RoomList.js @@ -72,7 +72,7 @@ export default class RoomList { async setRoomEncryption(roomId, roomInfo) { // important that this happens before calling into the store - // as it prevents the Crypto::setRoomEncryption for calling + // as it prevents the Crypto::setRoomEncryption from calling // this twice for consecutive m.room.encryption events this._roomEncryption[roomId] = roomInfo; await this._cryptoStore.doTxn(