Start verification sessions in an E2E DM where possible
Fixes https://github.com/vector-im/riot-web/issues/12187
This commit is contained in:
parent
4e2887ded6
commit
28df1e28cf
2 changed files with 77 additions and 1 deletions
|
@ -23,6 +23,7 @@ import dis from "./dispatcher";
|
|||
import * as Rooms from "./Rooms";
|
||||
import DMRoomMap from "./utils/DMRoomMap";
|
||||
import {getAddressType} from "./UserAddress";
|
||||
import SettingsStore from "./settings/SettingsStore";
|
||||
|
||||
/**
|
||||
* Create a new room, and switch to it.
|
||||
|
@ -174,13 +175,47 @@ export function findDMForUser(client, userId) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to ensure the user is already in the megolm session before continuing
|
||||
* NOTE: this assumes you've just created the room and there's not been an opportunity
|
||||
* for other code to run, so we shouldn't miss RoomState.newMember when it comes by.
|
||||
*/
|
||||
export async function _waitForMember(client, roomId, userId, opts = { timeout: 1500 }) {
|
||||
const { timeout } = opts;
|
||||
let handler;
|
||||
return new Promise((resolve) => {
|
||||
handler = function(_event, _roomstate, member) {
|
||||
if (member.userId !== userId) return;
|
||||
if (member.roomId !== roomId) return;
|
||||
resolve(true);
|
||||
};
|
||||
client.on("RoomState.newMember", handler);
|
||||
|
||||
/* We don't want to hang if this goes wrong, so we proceed and hope the other
|
||||
user is already in the megolm session */
|
||||
setTimeout(resolve, timeout, false);
|
||||
}).finally(() => {
|
||||
client.removeListener("RoomState.newMember", handler);
|
||||
});
|
||||
}
|
||||
|
||||
export async function ensureDMExists(client, userId) {
|
||||
const existingDMRoom = findDMForUser(client, userId);
|
||||
let roomId;
|
||||
if (existingDMRoom) {
|
||||
roomId = existingDMRoom.roomId;
|
||||
} else {
|
||||
roomId = await createRoom({dmUserId: userId, spinner: false, andView: false});
|
||||
let encryption;
|
||||
if (SettingsStore.isFeatureEnabled("feature_cross_signing")) {
|
||||
/* If the user's devices can all do encryption, start an encrypted DM */
|
||||
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});
|
||||
await _waitForMember(client, roomId, userId);
|
||||
}
|
||||
return roomId;
|
||||
}
|
||||
|
|
41
test/createRoom-test.js
Normal file
41
test/createRoom-test.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import {_waitForMember} from '../src/createRoom';
|
||||
import {EventEmitter} from 'events';
|
||||
|
||||
/* Shorter timeout, we've got tests to run */
|
||||
const timeout = 30;
|
||||
|
||||
describe("waitForMember", () => {
|
||||
let client;
|
||||
|
||||
beforeEach(() => {
|
||||
client = new EventEmitter();
|
||||
});
|
||||
|
||||
it("resolves with false if the timeout is reached", (done) => {
|
||||
_waitForMember(client, "", "", { timeout: 0 }).then((r) => {
|
||||
expect(r).toBe(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("resolves with false if the timeout is reached, even if other RoomState.newMember events fire", (done) => {
|
||||
const roomId = "!roomId:domain";
|
||||
const userId = "@clientId:domain";
|
||||
_waitForMember(client, roomId, userId, { timeout }).then((r) => {
|
||||
expect(r).toBe(false);
|
||||
done();
|
||||
});
|
||||
client.emit("RoomState.newMember", undefined, undefined, { roomId, userId: "@anotherClient:domain" });
|
||||
})
|
||||
|
||||
it("resolves with true if RoomState.newMember fires", (done) => {
|
||||
const roomId = "!roomId:domain";
|
||||
const userId = "@clientId:domain";
|
||||
_waitForMember(client, roomId, userId, { timeout }).then((r) => {
|
||||
expect(r).toBe(true);
|
||||
expect(client.listeners("RoomState.newMember").length).toBe(0);
|
||||
done();
|
||||
});
|
||||
client.emit("RoomState.newMember", undefined, undefined, { roomId, userId });
|
||||
})
|
||||
});
|
Loading…
Reference in a new issue