Fix detection of encryption for all users in a room (#10487) (#10489)

(cherry picked from commit dddef858f1)

Co-authored-by: Michael Weimann <michaelw@matrix.org>
This commit is contained in:
ElementRobot 2023-03-31 09:07:47 +01:00 committed by GitHub
parent 500a543662
commit 3693255cd5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 29 deletions

View file

@ -398,16 +398,21 @@ export default async function createRoom(opts: IOpts): Promise<string | null> {
export async function canEncryptToAllUsers(client: MatrixClient, userIds: string[]): Promise<boolean> {
try {
const usersDeviceMap = await client.downloadKeys(userIds);
// { "@user:host": { "DEVICE": {...}, ... }, ... }
return Object.values(usersDeviceMap).every(
(userDevices) =>
// { "DEVICE": {...}, ... }
Object.keys(userDevices).length > 0,
);
// There are no devices at all.
if (usersDeviceMap.size === 0) return false;
for (const devices of usersDeviceMap.values()) {
if (devices.size === 0) {
return false;
}
}
} catch (e) {
logger.error("Error determining if it's possible to encrypt to all users: ", e);
return false; // assume not
}
return true;
}
// Similar to ensureDMExists but also adds creation content

View file

@ -147,35 +147,56 @@ describe("createRoom", () => {
});
describe("canEncryptToAllUsers", () => {
const trueUser = new Map([
[
"@goodUser:localhost",
new Map([
["DEV1", {} as unknown as DeviceInfo],
["DEV2", {} as unknown as DeviceInfo],
]),
],
const user1Id = "@user1:example.com";
const user2Id = "@user2:example.com";
const devices = new Map([
["DEV1", {} as unknown as DeviceInfo],
["DEV2", {} as unknown as DeviceInfo],
]);
const falseUser = {
"@badUser:localhost": {},
};
let client: Mocked<MatrixClient>;
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
beforeAll(() => {
client = mocked(stubClient());
});
it("returns true if all devices have crypto", async () => {
client.downloadKeys.mockResolvedValue(trueUser);
const response = await canEncryptToAllUsers(client, ["@goodUser:localhost"]);
expect(response).toBe(true);
it("should return false if download keys does not return any user", async () => {
client.downloadKeys.mockResolvedValue(new Map());
const result = await canEncryptToAllUsers(client, [user1Id, user2Id]);
expect(result).toBe(false);
});
it("returns false if not all users have crypto", async () => {
client.downloadKeys.mockResolvedValue({ ...trueUser, ...falseUser });
const response = await canEncryptToAllUsers(client, ["@goodUser:localhost", "@badUser:localhost"]);
expect(response).toBe(false);
it("should return false if none of the users has a device", async () => {
client.downloadKeys.mockResolvedValue(
new Map([
[user1Id, new Map()],
[user2Id, new Map()],
]),
);
const result = await canEncryptToAllUsers(client, [user1Id, user2Id]);
expect(result).toBe(false);
});
it("should return false if some of the users don't have a device", async () => {
client.downloadKeys.mockResolvedValue(
new Map([
[user1Id, new Map()],
[user2Id, devices],
]),
);
const result = await canEncryptToAllUsers(client, [user1Id, user2Id]);
expect(result).toBe(false);
});
it("should return true if all users have a device", async () => {
client.downloadKeys.mockResolvedValue(
new Map([
[user1Id, devices],
[user2Id, devices],
]),
);
const result = await canEncryptToAllUsers(client, [user1Id, user2Id]);
expect(result).toBe(true);
});
});