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

pull/28217/head
Michael Weimann 2023-03-31 09:43:47 +02:00 committed by GitHub
parent ff1468b6d3
commit dddef858f1
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> { export async function canEncryptToAllUsers(client: MatrixClient, userIds: string[]): Promise<boolean> {
try { try {
const usersDeviceMap = await client.downloadKeys(userIds); const usersDeviceMap = await client.downloadKeys(userIds);
// { "@user:host": { "DEVICE": {...}, ... }, ... }
return Object.values(usersDeviceMap).every( // There are no devices at all.
(userDevices) => if (usersDeviceMap.size === 0) return false;
// { "DEVICE": {...}, ... }
Object.keys(userDevices).length > 0, for (const devices of usersDeviceMap.values()) {
); if (devices.size === 0) {
return false;
}
}
} catch (e) { } catch (e) {
logger.error("Error determining if it's possible to encrypt to all users: ", e); logger.error("Error determining if it's possible to encrypt to all users: ", e);
return false; // assume not return false; // assume not
} }
return true;
} }
// Similar to ensureDMExists but also adds creation content // Similar to ensureDMExists but also adds creation content

View File

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