Skip to content

Commit

Permalink
E2E: Download our own devicelist on startup
Browse files Browse the repository at this point in the history
Make sure we get a list of our own devices when starting a new client.

Fixes element-hq/element-web#2676.
  • Loading branch information
richvdh committed Dec 6, 2016
1 parent a4e2812 commit 89ced19
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 22 deletions.
48 changes: 27 additions & 21 deletions lib/crypto/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
this._deviceId = deviceId;

this._initialSyncCompleted = false;
// userId -> deviceId -> true
this._pendingNewDevices = {};
// userId -> true
this._pendingUsersWithNewDevices = {};

this._olmDevice = new OlmDevice(sessionStore);

Expand All @@ -77,20 +77,31 @@ function Crypto(baseApis, eventEmitter, sessionStore, userId, deviceId) {
this._deviceKeys["curve25519:" + this._deviceId] =
this._olmDevice.deviceCurve25519Key;

// add our own deviceinfo to the sessionstore
var deviceInfo = {
keys: this._deviceKeys,
algorithms: this._supportedAlgorithms,
verified: DeviceVerification.VERIFIED,
};
var myDevices = this._sessionStore.getEndToEndDevicesForUser(
this._userId
) || {};
myDevices[this._deviceId] = deviceInfo;
this._sessionStore.storeEndToEndDevicesForUser(
this._userId, myDevices
);

if (!myDevices) {
// we don't yet have a list of our own devices; make sure we
// get one when we flush the pendingUsersWithNewDevices.
this._pendingUsersWithNewDevices[this._userId] = true;
myDevices = {};
}

if (!myDevices[this._deviceId]) {
// add our own deviceinfo to the sessionstore
var deviceInfo = {
keys: this._deviceKeys,
algorithms: this._supportedAlgorithms,
verified: DeviceVerification.VERIFIED,
};

myDevices[this._deviceId] = deviceInfo;
this._sessionStore.storeEndToEndDevicesForUser(
this._userId, myDevices
);
}

_registerEventHandlers(this, eventEmitter);

// map from userId -> deviceId -> roomId -> timestamp
Expand Down Expand Up @@ -1134,8 +1145,7 @@ Crypto.prototype._onNewDeviceEvent = function(event) {
return;
}

this._pendingNewDevices[userId] = this._pendingNewDevices[userId] || {};
this._pendingNewDevices[userId][deviceId] = true;
this._pendingUsersWithNewDevices[userId] = true;

// we delay handling these until the intialsync has completed, so that we
// can do all of them together.
Expand All @@ -1150,10 +1160,7 @@ Crypto.prototype._onNewDeviceEvent = function(event) {
Crypto.prototype._flushNewDeviceRequests = function() {
var self = this;

var pending = this._pendingNewDevices;
var users = utils.keys(pending).filter(function(u) {
return utils.keys(pending[u]).length > 0;
});
var users = utils.keys(this._pendingUsersWithNewDevices);

if (users.length === 0) {
return;
Expand All @@ -1163,7 +1170,7 @@ Crypto.prototype._flushNewDeviceRequests = function() {

// we've kicked off requests to these users: remove their
// pending flag for now.
this._pendingNewDevices = {};
this._pendingUsersWithNewDevices = {};

users.map(function(u) {
r[u] = r[u].catch(function(e) {
Expand All @@ -1175,8 +1182,7 @@ Crypto.prototype._flushNewDeviceRequests = function() {
// mean that we will do another download in the future, but won't
// tight-loop.
//
self._pendingNewDevices[u] = self._pendingNewDevices[u] || {};
utils.update(self._pendingNewDevices[u], pending[u]);
self._pendingUsersWithNewDevices[u] = true;
});
});

Expand Down
18 changes: 18 additions & 0 deletions spec/integ/matrix-client-crypto.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,15 @@ function recvMessage(httpBackend, client, sender, message) {

function aliStartClient() {
expectAliKeyUpload().catch(test_utils.failTest);

// ali will try to query her own keys on start
aliHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
expect(content.device_keys[aliUserId]).toEqual({});
var result = {};
result[aliUserId] = {};
return {device_keys: result};
});

startClient(aliHttpBackend, aliClient);
return aliHttpBackend.flush().then(function() {
console.log("Ali client started");
Expand All @@ -391,6 +400,15 @@ function aliStartClient() {

function bobStartClient() {
expectBobKeyUpload().catch(test_utils.failTest);

// bob will try to query his own keys on start
bobHttpBackend.when("POST", "/keys/query").respond(200, function(path, content) {
expect(content.device_keys[bobUserId]).toEqual({});
var result = {};
result[bobUserId] = {};
return {device_keys: result};
});

startClient(bobHttpBackend, bobClient);
return bobHttpBackend.flush().then(function() {
console.log("Bob client started");
Expand Down
15 changes: 14 additions & 1 deletion spec/integ/megolm.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,25 @@ function TestClient(userId, deviceId, accessToken) {
/**
* start the client, and wait for it to initialise.
*
* @param {object?} deviceQueryResponse the list of our existing devices to return from
* the /query request. Defaults to empty device list
* @return {Promise}
*/
TestClient.prototype.start = function() {
TestClient.prototype.start = function(existingDevices) {
var self = this;

this.httpBackend.when("GET", "/pushrules").respond(200, {});
this.httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });

this.httpBackend.when('POST', '/keys/query').respond(200, function(path, content) {
expect(content.device_keys[self.userId]).toEqual({});
var 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).not.toBeDefined();
expect(content.device_keys).toBeDefined();
Expand Down

0 comments on commit 89ced19

Please sign in to comment.