From cc842aac8a0bd1925cfc9aeb61b6489b5b1d3121 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 19 May 2023 11:57:45 +0100 Subject: [PATCH] shieldStatusForRoom: avoid deprecated MatrixClient methods (#10944) Update this method to use modern crypto methods --- src/utils/ShieldUtils.ts | 20 +++++++++++++++++--- src/utils/arrays.ts | 4 ++-- test/utils/ShieldUtils-test.ts | 4 +++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/utils/ShieldUtils.ts b/src/utils/ShieldUtils.ts index a9efe4584f..037084eb67 100644 --- a/src/utils/ShieldUtils.ts +++ b/src/utils/ShieldUtils.ts @@ -16,6 +16,7 @@ limitations under the License. import { MatrixClient } from "matrix-js-sdk/src/client"; import { Room } from "matrix-js-sdk/src/models/room"; +import { logger } from "matrix-js-sdk/src/logger"; import DMRoomMap from "./DMRoomMap"; import { asyncSome } from "./arrays"; @@ -27,6 +28,11 @@ export enum E2EStatus { } export async function shieldStatusForRoom(client: MatrixClient, room: Room): Promise { + const crypto = client.getCrypto(); + if (!crypto) { + return E2EStatus.Warning; + } + const members = (await room.getEncryptionTargetMembers()).map(({ userId }) => userId); const inDMMap = !!DMRoomMap.shared().getUserIdForRoomId(room.roomId); @@ -53,10 +59,18 @@ export async function shieldStatusForRoom(client: MatrixClient, room: Room): Pro members.length !== 2) || // Don't alarm for self in 1:1 chats with other users members.length === 1; // Do alarm for self if we're alone in a room const targets = includeUser ? [...verified, client.getUserId()!] : verified; + const devicesByUser = await crypto.getUserDeviceInfo(targets); for (const userId of targets) { - const devices = client.getStoredDevicesForUser(userId); - const anyDeviceNotVerified = await asyncSome(devices, async ({ deviceId }) => { - const verificationStatus = await client.getCrypto()?.getDeviceVerificationStatus(userId, deviceId); + const devices = devicesByUser.get(userId); + if (!devices) { + // getUserDeviceInfo returned nothing about this user, which means we know nothing about their device list. + // That seems odd, so treat it as a warning. + logger.warn(`No device info for user ${userId}`); + return E2EStatus.Warning; + } + + const anyDeviceNotVerified = await asyncSome(devices.keys(), async (deviceId) => { + const verificationStatus = await crypto.getDeviceVerificationStatus(userId, deviceId); return !verificationStatus?.isVerified(); }); if (anyDeviceNotVerified) { diff --git a/src/utils/arrays.ts b/src/utils/arrays.ts index 63d2e26739..5f7c301d55 100644 --- a/src/utils/arrays.ts +++ b/src/utils/arrays.ts @@ -319,7 +319,7 @@ export const concat = (...arrays: Uint8Array[]): Uint8Array => { /** * Async version of Array.every. */ -export async function asyncEvery(values: T[], predicate: (value: T) => Promise): Promise { +export async function asyncEvery(values: Iterable, predicate: (value: T) => Promise): Promise { for (const value of values) { if (!(await predicate(value))) return false; } @@ -329,7 +329,7 @@ export async function asyncEvery(values: T[], predicate: (value: T) => Promis /** * Async version of Array.some. */ -export async function asyncSome(values: T[], predicate: (value: T) => Promise): Promise { +export async function asyncSome(values: Iterable, predicate: (value: T) => Promise): Promise { for (const value of values) { if (await predicate(value)) return true; } diff --git a/test/utils/ShieldUtils-test.ts b/test/utils/ShieldUtils-test.ts index 8759252727..4a5095c0c7 100644 --- a/test/utils/ShieldUtils-test.ts +++ b/test/utils/ShieldUtils-test.ts @@ -27,12 +27,14 @@ function mkClient(selfTrust = false) { Promise.resolve({ isVerified: () => (userId === "@self:localhost" ? selfTrust : userId[2] == "T"), }), + getUserDeviceInfo: async (userIds: string[]) => { + return new Map(userIds.map((u) => [u, new Map([["DEVICE", {}]])])); + }, }), checkUserTrust: (userId: string) => ({ isCrossSigningVerified: () => userId[1] == "T", wasCrossSigningVerified: () => userId[1] == "T" || userId[1] == "W", }), - getStoredDevicesForUser: (userId: string) => ["DEVICE"], } as unknown as MatrixClient; }