You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-25 05:23:13 +03:00
Make Room.getEncryptionTargetMembers async, as members might be loading
This commit is contained in:
@@ -535,8 +535,9 @@ MegolmEncryption.prototype._checkForUnknownDevices = function(devicesInRoom) {
|
|||||||
* @return {module:client.Promise} Promise which resolves to a map
|
* @return {module:client.Promise} Promise which resolves to a map
|
||||||
* from userId to deviceId to deviceInfo
|
* from userId to deviceId to deviceInfo
|
||||||
*/
|
*/
|
||||||
MegolmEncryption.prototype._getDevicesInRoom = function(room) {
|
MegolmEncryption.prototype._getDevicesInRoom = async function(room) {
|
||||||
const roomMembers = utils.map(room.getEncryptionTargetMembers(), function(u) {
|
const members = await room.getEncryptionTargetMembers();
|
||||||
|
const roomMembers = utils.map(members, function(u) {
|
||||||
return u.userId;
|
return u.userId;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -555,29 +556,28 @@ MegolmEncryption.prototype._getDevicesInRoom = function(room) {
|
|||||||
// common and then added new devices before joining this one? --Matthew
|
// common and then added new devices before joining this one? --Matthew
|
||||||
//
|
//
|
||||||
// yup, see https://github.com/vector-im/riot-web/issues/2305 --richvdh
|
// yup, see https://github.com/vector-im/riot-web/issues/2305 --richvdh
|
||||||
return this._crypto.downloadKeys(roomMembers, false).then((devices) => {
|
const devices = await this._crypto.downloadKeys(roomMembers, false);
|
||||||
// remove any blocked devices
|
// remove any blocked devices
|
||||||
for (const userId in devices) {
|
for (const userId in devices) {
|
||||||
if (!devices.hasOwnProperty(userId)) {
|
if (!devices.hasOwnProperty(userId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userDevices = devices[userId];
|
||||||
|
for (const deviceId in userDevices) {
|
||||||
|
if (!userDevices.hasOwnProperty(deviceId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const userDevices = devices[userId];
|
if (userDevices[deviceId].isBlocked() ||
|
||||||
for (const deviceId in userDevices) {
|
(userDevices[deviceId].isUnverified() && isBlacklisting)
|
||||||
if (!userDevices.hasOwnProperty(deviceId)) {
|
) {
|
||||||
continue;
|
delete userDevices[deviceId];
|
||||||
}
|
|
||||||
|
|
||||||
if (userDevices[deviceId].isBlocked() ||
|
|
||||||
(userDevices[deviceId].isUnverified() && isBlacklisting)
|
|
||||||
) {
|
|
||||||
delete userDevices[deviceId];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return devices;
|
return devices;
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -83,60 +83,62 @@ OlmEncryption.prototype._ensureSession = function(roomMembers) {
|
|||||||
*
|
*
|
||||||
* @return {module:client.Promise} Promise which resolves to the new event body
|
* @return {module:client.Promise} Promise which resolves to the new event body
|
||||||
*/
|
*/
|
||||||
OlmEncryption.prototype.encryptMessage = function(room, eventType, content) {
|
OlmEncryption.prototype.encryptMessage = async function(room, eventType, content) {
|
||||||
// pick the list of recipients based on the membership list.
|
// pick the list of recipients based on the membership list.
|
||||||
//
|
//
|
||||||
// TODO: there is a race condition here! What if a new user turns up
|
// TODO: there is a race condition here! What if a new user turns up
|
||||||
// just as you are sending a secret message?
|
// just as you are sending a secret message?
|
||||||
|
|
||||||
const users = utils.map(room.getEncryptionTargetMembers(), function(u) {
|
const members = await room.getEncryptionTargetMembers();
|
||||||
|
|
||||||
|
const users = utils.map(members, function(u) {
|
||||||
return u.userId;
|
return u.userId;
|
||||||
});
|
});
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
return this._ensureSession(users).then(function() {
|
await this._ensureSession(users);
|
||||||
const payloadFields = {
|
|
||||||
room_id: room.roomId,
|
|
||||||
type: eventType,
|
|
||||||
content: content,
|
|
||||||
};
|
|
||||||
|
|
||||||
const encryptedContent = {
|
const payloadFields = {
|
||||||
algorithm: olmlib.OLM_ALGORITHM,
|
room_id: room.roomId,
|
||||||
sender_key: self._olmDevice.deviceCurve25519Key,
|
type: eventType,
|
||||||
ciphertext: {},
|
content: content,
|
||||||
};
|
};
|
||||||
|
|
||||||
const promises = [];
|
const encryptedContent = {
|
||||||
|
algorithm: olmlib.OLM_ALGORITHM,
|
||||||
|
sender_key: self._olmDevice.deviceCurve25519Key,
|
||||||
|
ciphertext: {},
|
||||||
|
};
|
||||||
|
|
||||||
for (let i = 0; i < users.length; ++i) {
|
const promises = [];
|
||||||
const userId = users[i];
|
|
||||||
const devices = self._crypto.getStoredDevicesForUser(userId);
|
|
||||||
|
|
||||||
for (let j = 0; j < devices.length; ++j) {
|
for (let i = 0; i < users.length; ++i) {
|
||||||
const deviceInfo = devices[j];
|
const userId = users[i];
|
||||||
const key = deviceInfo.getIdentityKey();
|
const devices = self._crypto.getStoredDevicesForUser(userId);
|
||||||
if (key == self._olmDevice.deviceCurve25519Key) {
|
|
||||||
// don't bother sending to ourself
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (deviceInfo.verified == DeviceVerification.BLOCKED) {
|
|
||||||
// don't bother setting up sessions with blocked users
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
promises.push(
|
for (let j = 0; j < devices.length; ++j) {
|
||||||
olmlib.encryptMessageForDevice(
|
const deviceInfo = devices[j];
|
||||||
encryptedContent.ciphertext,
|
const key = deviceInfo.getIdentityKey();
|
||||||
self._userId, self._deviceId, self._olmDevice,
|
if (key == self._olmDevice.deviceCurve25519Key) {
|
||||||
userId, deviceInfo, payloadFields,
|
// don't bother sending to ourself
|
||||||
),
|
continue;
|
||||||
);
|
}
|
||||||
|
if (deviceInfo.verified == DeviceVerification.BLOCKED) {
|
||||||
|
// don't bother setting up sessions with blocked users
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(promises).return(encryptedContent);
|
promises.push(
|
||||||
});
|
olmlib.encryptMessageForDevice(
|
||||||
|
encryptedContent.ciphertext,
|
||||||
|
self._userId, self._deviceId, self._olmDevice,
|
||||||
|
userId, deviceInfo, payloadFields,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await Promise.all(promises).return(encryptedContent);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ Crypto.prototype.setRoomEncryption = async function(roomId, config, inhibitDevic
|
|||||||
throw new Error(`Unable to enable encryption in unknown room ${roomId}`);
|
throw new Error(`Unable to enable encryption in unknown room ${roomId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const members = room.getEncryptionTargetMembers();
|
const members = await room.getEncryptionTargetMembers();
|
||||||
members.forEach((m) => {
|
members.forEach((m) => {
|
||||||
this._deviceList.startTrackingDeviceList(m.userId);
|
this._deviceList.startTrackingDeviceList(m.userId);
|
||||||
});
|
});
|
||||||
@@ -852,7 +852,7 @@ Crypto.prototype.handleDeviceListChanges = async function(syncData, syncDeviceLi
|
|||||||
// If we didn't make this assumption, we'd have to use the /keys/changes API
|
// If we didn't make this assumption, we'd have to use the /keys/changes API
|
||||||
// to get key changes between the sync token in the device list and the 'old'
|
// to get key changes between the sync token in the device list and the 'old'
|
||||||
// sync token used here to make sure we didn't miss any.
|
// sync token used here to make sure we didn't miss any.
|
||||||
this._evalDeviceListChanges(syncDeviceLists);
|
await this._evalDeviceListChanges(syncDeviceLists);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -968,7 +968,7 @@ Crypto.prototype._evalDeviceListChanges = async function(deviceLists) {
|
|||||||
// Check we really don't share any rooms with these users
|
// Check we really don't share any rooms with these users
|
||||||
// any more: the server isn't required to give us the
|
// any more: the server isn't required to give us the
|
||||||
// exact correct set.
|
// exact correct set.
|
||||||
const e2eUserIds = new Set(this._getE2eUsers());
|
const e2eUserIds = new Set(await this._getE2eUsers());
|
||||||
|
|
||||||
deviceLists.left.forEach((u) => {
|
deviceLists.left.forEach((u) => {
|
||||||
if (!e2eUserIds.has(u)) {
|
if (!e2eUserIds.has(u)) {
|
||||||
@@ -983,10 +983,10 @@ Crypto.prototype._evalDeviceListChanges = async function(deviceLists) {
|
|||||||
*
|
*
|
||||||
* @returns {string[]} List of user IDs
|
* @returns {string[]} List of user IDs
|
||||||
*/
|
*/
|
||||||
Crypto.prototype._getE2eUsers = function() {
|
Crypto.prototype._getE2eUsers = async function() {
|
||||||
const e2eUserIds = [];
|
const e2eUserIds = [];
|
||||||
for (const room of this._getE2eRooms()) {
|
for (const room of this._getE2eRooms()) {
|
||||||
const members = room.getEncryptionTargetMembers();
|
const members = await room.getEncryptionTargetMembers();
|
||||||
for (const member of members) {
|
for (const member of members) {
|
||||||
e2eUserIds.push(member.userId);
|
e2eUserIds.push(member.userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -569,10 +569,13 @@ Room.prototype.addEventsToTimeline = function(events, toStartOfTimeline,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of members we should be encrypting for in this room
|
* Get a list of members we should be encrypting for in this room
|
||||||
* @return {RoomMember[]} A list of members who we should encrypt messages for
|
* @return {Promise<RoomMember[]>} A list of members who
|
||||||
* in this room.
|
* we should encrypt messages for in this room.
|
||||||
*/
|
*/
|
||||||
Room.prototype.getEncryptionTargetMembers = function() {
|
Room.prototype.getEncryptionTargetMembers = async function() {
|
||||||
|
if (this._oobMembersPromise) {
|
||||||
|
await _oobMembersPromise;
|
||||||
|
}
|
||||||
let members = this.getMembersWithMembership("join");
|
let members = this.getMembersWithMembership("join");
|
||||||
if (this.shouldEncryptForInvitedMembers()) {
|
if (this.shouldEncryptForInvitedMembers()) {
|
||||||
members = members.concat(this.getMembersWithMembership("invite"));
|
members = members.concat(this.getMembersWithMembership("invite"));
|
||||||
|
|||||||
Reference in New Issue
Block a user