abstract out the check for available target devices
This commit is contained in:
parent
23596031db
commit
164b355ffe
3 changed files with 47 additions and 12 deletions
|
@ -535,11 +535,7 @@ export default class InviteDialog extends React.PureComponent {
|
||||||
// Check whether all users have uploaded device keys before.
|
// Check whether all users have uploaded device keys before.
|
||||||
// If so, enable encryption in the new room.
|
// If so, enable encryption in the new room.
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
const usersToDevicesMap = await client.downloadKeys(targetIds);
|
const allHaveDeviceKeys = await createRoom.canEncryptToAllUsers(client, 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) {
|
if (allHaveDeviceKeys) {
|
||||||
createRoomOptions.encryption = true;
|
createRoomOptions.encryption = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,19 @@ export async function _waitForMember(client, roomId, userId, opts = { timeout: 1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure that for every user in a room, there is at least one device that we
|
||||||
|
* can encrypt to.
|
||||||
|
*/
|
||||||
|
export async function canEncryptToAllUsers(client, userIds) {
|
||||||
|
const usersDeviceMap = await client.downloadKeys(userIds);
|
||||||
|
// { "@user:host": { "DEVICE": {...}, ... }, ... }
|
||||||
|
return Object.values(usersDeviceMap).every((userDevices) =>
|
||||||
|
// { "DEVICE": {...}, ... }
|
||||||
|
Object.keys(userDevices).length > 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export async function ensureDMExists(client, userId) {
|
export async function ensureDMExists(client, userId) {
|
||||||
const existingDMRoom = findDMForUser(client, userId);
|
const existingDMRoom = findDMForUser(client, userId);
|
||||||
let roomId;
|
let roomId;
|
||||||
|
@ -207,12 +220,7 @@ export async function ensureDMExists(client, userId) {
|
||||||
} else {
|
} else {
|
||||||
let encryption;
|
let encryption;
|
||||||
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||||
/* If the user's devices can all do encryption, start an encrypted DM */
|
encryption = canEncryptToAllUsers(client, [userId]);
|
||||||
const userDeviceMap = await client.downloadKeys([userId]);
|
|
||||||
// => { "@userId:host": { DEVICE: DeviceInfo, ... }}
|
|
||||||
const userDevices = Object.values(userDeviceMap[userId]);
|
|
||||||
// => [DeviceInfo, DeviceInfo...]
|
|
||||||
encryption = userDevices.every((device) => device.keys);
|
|
||||||
}
|
}
|
||||||
roomId = await createRoom({encryption, dmUserId: userId, spinner: false, andView: false});
|
roomId = await createRoom({encryption, dmUserId: userId, spinner: false, andView: false});
|
||||||
await _waitForMember(client, roomId, userId);
|
await _waitForMember(client, roomId, userId);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {_waitForMember} from '../src/createRoom';
|
import {_waitForMember, canEncryptToAllUsers} from '../src/createRoom';
|
||||||
import {EventEmitter} from 'events';
|
import {EventEmitter} from 'events';
|
||||||
|
|
||||||
/* Shorter timeout, we've got tests to run */
|
/* Shorter timeout, we've got tests to run */
|
||||||
|
@ -39,3 +39,34 @@ describe("waitForMember", () => {
|
||||||
client.emit("RoomState.newMember", undefined, undefined, { roomId, userId });
|
client.emit("RoomState.newMember", undefined, undefined, { roomId, userId });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("canEncryptToAllUsers", () => {
|
||||||
|
const trueUser = {
|
||||||
|
"@goodUser:localhost": {
|
||||||
|
"DEV1": {},
|
||||||
|
"DEV2": {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const falseUser = {
|
||||||
|
"@badUser:localhost": {},
|
||||||
|
};
|
||||||
|
|
||||||
|
it("returns true if all devices have crypto", async (done) => {
|
||||||
|
const client = {
|
||||||
|
downloadKeys: async function(userIds) { return trueUser; },
|
||||||
|
};
|
||||||
|
const response = await canEncryptToAllUsers(client, ["@goodUser:localhost"]);
|
||||||
|
expect(response).toBe(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("returns false if not all users have crypto", async (done) => {
|
||||||
|
const client = {
|
||||||
|
downloadKeys: async function(userIds) { return {...trueUser, ...falseUser}; },
|
||||||
|
};
|
||||||
|
const response = await canEncryptToAllUsers(client, ["@goodUser:localhost", "@badUser:localhost"]);
|
||||||
|
expect(response).toBe(false);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue