diff --git a/spec/integ/matrix-client-crypto.spec.js b/spec/integ/matrix-client-crypto.spec.js index 7c1c40af5..966385394 100644 --- a/spec/integ/matrix-client-crypto.spec.js +++ b/spec/integ/matrix-client-crypto.spec.js @@ -684,4 +684,44 @@ describe("MatrixClient crypto", function() { }).then(expectAliQueryKeys) .nodeify(done); }); + + it("Ali does a key query when encryption is enabled", function(done) { + // enabling encryption in the room should make alice download devices + // for both members. + q() + .then(() => startClient(aliTestClient)) + .then(() => { + const syncData = { + next_batch: '2', + rooms: { + join: {}, + }, + }; + syncData.rooms.join[roomId] = { + state: { + events: [ + testUtils.mkEvent({ + type: 'm.room.encryption', + skey: '', + content: { + algorithm: 'm.olm.v1.curve25519-aes-sha2', + }, + }), + ], + }, + }; + + aliTestClient.httpBackend.when('GET', '/sync').respond( + 200, syncData); + return aliTestClient.httpBackend.flush('/sync', 1); + }).then(() => { + aliTestClient.expectKeyQuery({ + device_keys: { + [aliUserId]: {}, + [bobUserId]: {}, + }, + }); + return aliTestClient.httpBackend.flush('/keys/query', 1); + }).nodeify(done); + }); }); diff --git a/src/crypto/index.js b/src/crypto/index.js index d87e172fc..4f43eafb2 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -542,6 +542,23 @@ Crypto.prototype.setRoomEncryption = function(roomId, config) { config: config, }); this._roomEncryptors[roomId] = alg; + + // if encryption was not previously enabled in this room, we will have been + // ignoring new device events for these users so far. We may well have + // up-to-date lists for some users, for instance if we were sharing other + // e2e rooms with them, so there is room for optimisation here, but for now + // we just invalidate everyone in the room. + if (!existingConfig) { + console.log("Enabling encryption in " + roomId + " for the first time; " + + "invalidating device lists for all users therein"); + const room = this._clientStore.getRoom(roomId); + const members = room.getJoinedMembers(); + members.forEach((m) => { + this._deviceList.invalidateUserDeviceList(m.userId); + }); + // the actual refresh happens once we've finished processing the sync, + // in _onSyncCompleted. + } };