Skip to content

Commit

Permalink
Merge pull request #348 from matrix-org/rav/device_list_stream
Browse files Browse the repository at this point in the history
Use the device change notifications interface
  • Loading branch information
richvdh authored Feb 3, 2017
2 parents eaa95fb + 8d50274 commit c3a8aec
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 50 deletions.
51 changes: 44 additions & 7 deletions src/base-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -1018,20 +1018,35 @@ MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
*
* @param {string[]} userIds list of users to get keys for
*
* @param {module:client.callback=} callback
* @param {Object=} opts
*
* @param {string=} opts.token sync token to pass in the query request, to help
* the HS give the most recent results
*
* @return {module:client.Promise} Resolves: result object. Rejects: with
* an error response ({@link module:http-api.MatrixError}).
*/
MatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, callback) {
const downloadQuery = {};
MatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, opts) {
if (utils.isFunction(opts)) {
// opts used to be 'callback'.
throw new Error(
'downloadKeysForUsers no longer accepts a callback parameter',
);
}
opts = opts || {};

for (let i = 0; i < userIds.length; ++i) {
downloadQuery[userIds[i]] = {};
const content = {
device_keys: {},
};
if ('token' in opts) {
content.token = opts.token;
}
const content = {device_keys: downloadQuery};
userIds.forEach((u) => {
content.device_keys[u] = {};
});

return this._http.authedRequestWithPrefix(
callback, "POST", "/keys/query", undefined, content,
undefined, "POST", "/keys/query", undefined, content,
httpApi.PREFIX_UNSTABLE,
);
};
Expand Down Expand Up @@ -1067,6 +1082,28 @@ MatrixBaseApis.prototype.claimOneTimeKeys = function(devices, key_algorithm) {
);
};

/**
* Ask the server for a list of users who have changed their device lists
* between a pair of sync tokens
*
* @param {string} oldToken
* @param {string} newToken
*
* @return {module:client.Promise} Resolves: result object. Rejects: with
* an error response ({@link module:http-api.MatrixError}).
*/
MatrixBaseApis.prototype.getKeyChanges = function(oldToken, newToken) {
const qps = {
from: oldToken,
to: newToken,
};

return this._http.authedRequestWithPrefix(
undefined, "GET", "/keys/changes", qps, undefined,
httpApi.PREFIX_UNSTABLE,
);
};


// Identity Server Operations
// ==========================
Expand Down
24 changes: 22 additions & 2 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ function MatrixClient(opts) {
this, this,
opts.sessionStore,
userId, this.deviceId,
this.store,
);

this.olmVersion = Crypto.getOlmVersion();
Expand Down Expand Up @@ -2665,8 +2666,6 @@ MatrixClient.prototype.startClient = function(opts) {
};
}

this._clientOpts = opts;

if (this._crypto) {
this._crypto.uploadKeys(5).done();
const tenMinutes = 1000 * 60 * 10;
Expand All @@ -2684,6 +2683,13 @@ MatrixClient.prototype.startClient = function(opts) {
console.error("Still have sync object whilst not running: stopping old one");
this._syncApi.stop();
}

// shallow-copy the opts dict before modifying and storing it
opts = Object.assign({}, opts);

opts.crypto = this._crypto;
this._clientOpts = opts;

this._syncApi = new SyncApi(this, opts);
this._syncApi.sync();
};
Expand Down Expand Up @@ -3067,12 +3073,26 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED;
* </ul>
*
* @event module:client~MatrixClient#"sync"
*
* @param {string} state An enum representing the syncing state. One of "PREPARED",
* "SYNCING", "ERROR", "STOPPED".
*
* @param {?string} prevState An enum representing the previous syncing state.
* One of "PREPARED", "SYNCING", "ERROR", "STOPPED" <b>or null</b>.
*
* @param {?Object} data Data about this transition.
*
* @param {MatrixError} data.err The matrix error if <code>state=ERROR</code>.
*
* @param {String} data.oldSyncToken The 'since' token passed to /sync.
* <code>null</code> for the first successful sync since this client was
* started. Only present if <code>state=PREPARED</code> or
* <code>state=SYNCING</code>.
*
* @param {String} data.nextSyncToken The 'next_batch' result from /sync, which
* will become the 'since' token for the next call to /sync. Only present if
* <code>state=PREPARED</code> or <code>state=SYNCING</code>.
*
* @example
* matrixClient.on("sync", function(state, prevState, data) {
* switch (state) {
Expand Down
13 changes: 12 additions & 1 deletion src/crypto/DeviceList.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export default class DeviceList {

// userId -> promise
this._keyDownloadsInProgressByUser = {};

this.lastKnownSyncToken = null;
}

/**
Expand Down Expand Up @@ -288,8 +290,13 @@ export default class DeviceList {
_doKeyDownloadForUsers(downloadUsers) {
console.log('Starting key download for ' + downloadUsers);

const token = this.lastKnownSyncToken;
const opts = {};
if (token) {
opts.token = token;
}
return this._baseApis.downloadKeysForUsers(
downloadUsers,
downloadUsers, opts,
).then((res) => {
const dk = res.device_keys || {};

Expand Down Expand Up @@ -319,6 +326,10 @@ export default class DeviceList {
this._sessionStore.storeEndToEndDevicesForUser(
userId, storage,
);

if (token) {
this._sessionStore.storeEndToEndDeviceSyncToken(token);
}
}
});
}
Expand Down
Loading

0 comments on commit c3a8aec

Please sign in to comment.