Enable encryption in DMs with device keys

When the cross-signing lab is enabled, this changes DMs to use encryption as
long as all invited users have uploaded device keys (which we're using as a
proxy for "has some client that understands E2E").

Fixes https://github.com/vector-im/riot-web/issues/12005
pull/21833/head
J. Ryan Stinnett 2020-01-23 16:00:55 +00:00
parent 2b16b650fe
commit 1e25b32ba3
2 changed files with 42 additions and 6 deletions

View File

@ -33,6 +33,7 @@ import Modal from "../../../Modal";
import {humanizeTime} from "../../../utils/humanize"; import {humanizeTime} from "../../../utils/humanize";
import createRoom from "../../../createRoom"; import createRoom from "../../../createRoom";
import {inviteMultipleToRoom} from "../../../RoomInvite"; import {inviteMultipleToRoom} from "../../../RoomInvite";
import SettingsStore from '../../../settings/SettingsStore';
export const KIND_DM = "dm"; export const KIND_DM = "dm";
export const KIND_INVITE = "invite"; export const KIND_INVITE = "invite";
@ -493,7 +494,7 @@ export default class InviteDialog extends React.PureComponent {
return false; return false;
} }
_startDm = () => { _startDm = async () => {
this.setState({busy: true}); this.setState({busy: true});
const targetIds = this.state.targets.map(t => t.userId); const targetIds = this.state.targets.map(t => t.userId);
@ -510,14 +511,31 @@ export default class InviteDialog extends React.PureComponent {
return; return;
} }
const createRoomOptions = {};
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
// Check whether all users have uploaded device keys before.
// If so, enable encryption in the new room.
const client = MatrixClientPeg.get();
const usersToDevicesMap = await client.downloadKeys(targetIds);
const allHaveDeviceKeys = Object.values(usersToDevicesMap).every(devices => {
// `devices` is an object of the form { deviceId: deviceInfo, ... }.
return Object.keys(devices).length > 0;
});
if (allHaveDeviceKeys) {
createRoomOptions.encryption = true;
}
}
// Check if it's a traditional DM and create the room if required. // Check if it's a traditional DM and create the room if required.
// TODO: [Canonical DMs] Remove this check and instead just create the multi-person DM // TODO: [Canonical DMs] Remove this check and instead just create the multi-person DM
let createRoomPromise = Promise.resolve(); let createRoomPromise = Promise.resolve();
if (targetIds.length === 1) { if (targetIds.length === 1) {
createRoomPromise = createRoom({dmUserId: targetIds[0]}); createRoomOptions.dmUserId = targetIds[0];
createRoomPromise = createRoom(createRoomOptions);
} else { } else {
// Create a boring room and try to invite the targets manually. // Create a boring room and try to invite the targets manually.
createRoomPromise = createRoom().then(roomId => { createRoomPromise = createRoom(createRoomOptions).then(roomId => {
return inviteMultipleToRoom(roomId, targetIds); return inviteMultipleToRoom(roomId, targetIds);
}).then(result => { }).then(result => {
if (this._shouldAbortAfterInviteError(result)) { if (this._shouldAbortAfterInviteError(result)) {

View File

@ -82,7 +82,7 @@ const _getE2EStatus = (cli, userId, devices) => {
return "warning"; return "warning";
}; };
function openDMForUser(matrixClient, userId) { async function openDMForUser(matrixClient, userId) {
const dmRooms = DMRoomMap.shared().getDMRoomsForUserId(userId); const dmRooms = DMRoomMap.shared().getDMRoomsForUserId(userId);
const lastActiveRoom = dmRooms.reduce((lastActiveRoom, roomId) => { const lastActiveRoom = dmRooms.reduce((lastActiveRoom, roomId) => {
const room = matrixClient.getRoom(roomId); const room = matrixClient.getRoom(roomId);
@ -100,9 +100,27 @@ function openDMForUser(matrixClient, userId) {
action: 'view_room', action: 'view_room',
room_id: lastActiveRoom.roomId, room_id: lastActiveRoom.roomId,
}); });
} else { return;
createRoom({dmUserId: userId});
} }
const createRoomOptions = {
dmUserId: userId,
};
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
// Check whether all users have uploaded device keys before.
// If so, enable encryption in the new room.
const usersToDevicesMap = await matrixClient.downloadKeys([userId]);
const allHaveDeviceKeys = Object.values(usersToDevicesMap).every(devices => {
// `devices` is an object of the form { deviceId: deviceInfo, ... }.
return Object.keys(devices).length > 0;
});
if (allHaveDeviceKeys) {
createRoomOptions.encryption = true;
}
}
createRoom(createRoomOptions);
} }
function useIsEncrypted(cli, room) { function useIsEncrypted(cli, room) {