You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Merge branch 'develop' into kegan/indexeddb
This commit is contained in:
@@ -52,21 +52,21 @@ export default function TestClient(userId, deviceId, accessToken) {
|
||||
/**
|
||||
* start the client, and wait for it to initialise.
|
||||
*
|
||||
* @param {object?} existingDevices the list of our existing devices to return from
|
||||
* the /query request. Defaults to empty device list
|
||||
* @return {Promise}
|
||||
*/
|
||||
TestClient.prototype.start = function(existingDevices) {
|
||||
TestClient.prototype.start = function() {
|
||||
this.httpBackend.when("GET", "/pushrules").respond(200, {});
|
||||
this.httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });
|
||||
this.expectKeyUpload(existingDevices);
|
||||
this.expectKeyUpload();
|
||||
|
||||
this.client.startClient({
|
||||
// set this so that we can get hold of failed events
|
||||
pendingEventOrdering: 'detached',
|
||||
});
|
||||
|
||||
return this.httpBackend.flush();
|
||||
return this.httpBackend.flush().then(() => {
|
||||
console.log('TestClient[' + this.userId + ']: started');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -78,22 +78,9 @@ TestClient.prototype.stop = function() {
|
||||
|
||||
/**
|
||||
* Set up expectations that the client will upload device and one-time keys.
|
||||
*
|
||||
* @param {object?} existingDevices the list of our existing devices to return from
|
||||
* the /query request. Defaults to empty device list
|
||||
*/
|
||||
TestClient.prototype.expectKeyUpload = function(existingDevices) {
|
||||
TestClient.prototype.expectKeyUpload = function() {
|
||||
const self = this;
|
||||
this.httpBackend.when('POST', '/keys/query').respond(200, function(path, content) {
|
||||
expect(Object.keys(content.device_keys)).toEqual([self.userId]);
|
||||
expect(content.device_keys[self.userId]).toEqual({});
|
||||
let res = existingDevices;
|
||||
if (!res) {
|
||||
res = { device_keys: {} };
|
||||
res.device_keys[self.userId] = {};
|
||||
}
|
||||
return res;
|
||||
});
|
||||
this.httpBackend.when("POST", "/keys/upload").respond(200, function(path, content) {
|
||||
expect(content.one_time_keys).toBe(undefined);
|
||||
expect(content.device_keys).toBeTruthy();
|
||||
@@ -111,6 +98,24 @@ TestClient.prototype.expectKeyUpload = function(existingDevices) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Set up expectations that the client will query device keys.
|
||||
*
|
||||
* We check that the query contains each of the users in `response`.
|
||||
*
|
||||
* @param {Object} response response to the query.
|
||||
*/
|
||||
TestClient.prototype.expectKeyQuery = function(response) {
|
||||
this.httpBackend.when('POST', '/keys/query').respond(
|
||||
200, (path, content) => {
|
||||
Object.keys(response.device_keys).forEach((userId) => {
|
||||
expect(content.device_keys[userId]).toEqual({});
|
||||
});
|
||||
return response;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* get the uploaded curve25519 device key
|
||||
*
|
||||
|
@@ -393,7 +393,9 @@ describe("MatrixClient crypto", function() {
|
||||
|
||||
afterEach(function() {
|
||||
aliTestClient.stop();
|
||||
aliTestClient.httpBackend.verifyNoOutstandingExpectation();
|
||||
bobTestClient.stop();
|
||||
bobTestClient.httpBackend.verifyNoOutstandingExpectation();
|
||||
});
|
||||
|
||||
it('Ali knows the difference between a new user and one with no devices',
|
||||
@@ -620,16 +622,13 @@ describe("MatrixClient crypto", function() {
|
||||
.then(function() {
|
||||
aliTestClient.client.setDeviceBlocked(bobUserId, bobDeviceId, true);
|
||||
const p1 = sendMessage(aliTestClient.client);
|
||||
const p2 = expectAliQueryKeys()
|
||||
.then(expectAliClaimKeys)
|
||||
.then(function() {
|
||||
return expectSendMessageRequest(aliTestClient.httpBackend);
|
||||
}).then(function(sentContent) {
|
||||
// no unblocked devices, so the ciphertext should be empty
|
||||
expect(sentContent.ciphertext).toEqual({});
|
||||
});
|
||||
const p2 = expectSendMessageRequest(aliTestClient.httpBackend)
|
||||
.then(function(sentContent) {
|
||||
// no unblocked devices, so the ciphertext should be empty
|
||||
expect(sentContent.ciphertext).toEqual({});
|
||||
});
|
||||
return q.all([p1, p2]);
|
||||
}).catch(testUtils.failTest).nodeify(done);
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it("Bob receives two pre-key messages", function(done) {
|
||||
@@ -685,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);
|
||||
});
|
||||
});
|
||||
|
@@ -351,7 +351,6 @@ describe("MatrixClient", function() {
|
||||
|
||||
httpBackend.when("POST", "/keys/query").check(function(req) {
|
||||
expect(req.data).toEqual({device_keys: {
|
||||
'@alice:localhost': {},
|
||||
'boris': {},
|
||||
'chaz': {},
|
||||
}});
|
||||
|
@@ -349,6 +349,69 @@ describe("megolm", function() {
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it("Alice receives a megolm message before the session keys", function(done) {
|
||||
// https://github.com/vector-im/riot-web/issues/2273
|
||||
let roomKeyEncrypted;
|
||||
|
||||
return aliceTestClient.start().then(function() {
|
||||
const p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||
|
||||
const groupSession = new Olm.OutboundGroupSession();
|
||||
groupSession.create();
|
||||
|
||||
// make the room_key event, but don't send it yet
|
||||
roomKeyEncrypted = encryptGroupSessionKey({
|
||||
senderKey: testSenderKey,
|
||||
recipient: aliceTestClient,
|
||||
p2pSession: p2pSession,
|
||||
groupSession: groupSession,
|
||||
room_id: ROOM_ID,
|
||||
});
|
||||
|
||||
// encrypt a message with the group session
|
||||
const messageEncrypted = encryptMegolmEvent({
|
||||
senderKey: testSenderKey,
|
||||
groupSession: groupSession,
|
||||
room_id: ROOM_ID,
|
||||
});
|
||||
|
||||
// Alice just gets the message event to start with
|
||||
const syncResponse = {
|
||||
next_batch: 1,
|
||||
rooms: {
|
||||
join: {},
|
||||
},
|
||||
};
|
||||
syncResponse.rooms.join[ROOM_ID] = {
|
||||
timeline: {
|
||||
events: [messageEncrypted],
|
||||
},
|
||||
};
|
||||
|
||||
aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse);
|
||||
return aliceTestClient.httpBackend.flush("/sync", 1);
|
||||
}).then(function() {
|
||||
const room = aliceTestClient.client.getRoom(ROOM_ID);
|
||||
const event = room.getLiveTimeline().getEvents()[0];
|
||||
expect(event.getContent().msgtype).toEqual('m.bad.encrypted');
|
||||
|
||||
// now she gets the room_key event
|
||||
const syncResponse = {
|
||||
next_batch: 2,
|
||||
to_device: {
|
||||
events: [roomKeyEncrypted],
|
||||
},
|
||||
};
|
||||
|
||||
aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse);
|
||||
return aliceTestClient.httpBackend.flush("/sync", 1);
|
||||
}).then(function() {
|
||||
const room = aliceTestClient.client.getRoom(ROOM_ID);
|
||||
const event = room.getLiveTimeline().getEvents()[0];
|
||||
expect(event.getContent().body).toEqual('42');
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it("Alice gets a second room_key message", function(done) {
|
||||
return aliceTestClient.start().then(function() {
|
||||
const p2pSession = createOlmSession(testOlmAccount, aliceTestClient);
|
||||
@@ -672,9 +735,7 @@ describe("megolm", function() {
|
||||
let inboundGroupSession;
|
||||
let decrypted;
|
||||
|
||||
return aliceTestClient.start(
|
||||
getTestKeysQueryResponse(aliceTestClient.userId),
|
||||
).then(function() {
|
||||
return aliceTestClient.start().then(function() {
|
||||
// an encrypted room with just alice
|
||||
const syncResponse = {
|
||||
next_batch: 1,
|
||||
@@ -701,6 +762,13 @@ describe("megolm", function() {
|
||||
};
|
||||
aliceTestClient.httpBackend.when('GET', '/sync').respond(200, syncResponse);
|
||||
|
||||
// the completion of the first initialsync hould make Alice
|
||||
// invalidate the device cache for all members in e2e rooms (ie,
|
||||
// herself), and do a key query.
|
||||
aliceTestClient.expectKeyQuery(
|
||||
getTestKeysQueryResponse(aliceTestClient.userId),
|
||||
);
|
||||
|
||||
return aliceTestClient.httpBackend.flush();
|
||||
}).then(function() {
|
||||
aliceTestClient.client.setDeviceKnown(aliceTestClient.userId, 'DEVICE_ID');
|
||||
|
@@ -49,17 +49,17 @@ HttpBackend.prototype = {
|
||||
const tryFlush = function() {
|
||||
// if there's more real requests and more expected requests, flush 'em.
|
||||
console.log(
|
||||
" trying to flush queue => reqs=%s expected=%s [%s]",
|
||||
self.requests.length, self.expectedRequests.length, path,
|
||||
" trying to flush queue => reqs=[%s] expected=[%s]",
|
||||
self.requests, self.expectedRequests.map((er) => er.path),
|
||||
);
|
||||
if (self._takeFromQueue(path)) {
|
||||
// try again on the next tick.
|
||||
console.log(" flushed. Trying for more. [%s]", path);
|
||||
flushed += 1;
|
||||
if (numToFlush && flushed === numToFlush) {
|
||||
console.log(" [%s] Flushed assigned amount: %s", path, numToFlush);
|
||||
console.log(" Flushed assigned amount: %s", numToFlush);
|
||||
defer.resolve();
|
||||
} else {
|
||||
console.log(" flushed. Trying for more.");
|
||||
setTimeout(tryFlush, 0);
|
||||
}
|
||||
} else if (flushed === 0 && !triedWaiting) {
|
||||
@@ -68,7 +68,7 @@ HttpBackend.prototype = {
|
||||
setTimeout(tryFlush, 5);
|
||||
triedWaiting = true;
|
||||
} else {
|
||||
console.log(" no more flushes. [%s]", path);
|
||||
console.log(" no more flushes.");
|
||||
defer.resolve();
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user