Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Fix detection of encryption for all users in a room (#10487)
Browse files Browse the repository at this point in the history
  • Loading branch information
weeman1337 authored Mar 31, 2023
1 parent ff1468b commit dddef85
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 29 deletions.
17 changes: 11 additions & 6 deletions src/createRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
67 changes: 44 additions & 23 deletions test/createRoom-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 falseUser = {
"@badUser:localhost": {},
};
const devices = new Map([
["DEV1", {} as unknown as DeviceInfo],
["DEV2", {} as unknown as DeviceInfo],
]);

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);
});
});

0 comments on commit dddef85

Please sign in to comment.