element-web/src/utils/ShieldUtils.ts
David Baker 719faed2ff Separate toasts for existing & new device verification
Separate device verification toasts into ones for devices that were
there when the app loaded and a separate toast for each device that
has appeared since.

Reverts part of https://github.com/matrix-org/matrix-react-sdk/pull/4506
(clicking a device from your own UserInfo now triggers the legacy
verification flow again).

Fixes https://github.com/vector-im/riot-web/issues/13422
Fixes https://github.com/vector-im/riot-web/issues/13418
2020-04-28 18:35:16 +01:00

58 lines
2.3 KiB
TypeScript

import DMRoomMap from './DMRoomMap';
/* For now, a cut-down type spec for the client */
interface Client {
getUserId: () => string;
checkUserTrust: (userId: string) => {
isCrossSigningVerified: () => boolean
wasCrossSigningVerified: () => boolean
};
getStoredDevicesForUser: (userId: string) => [{ deviceId: string }];
checkDeviceTrust: (userId: string, deviceId: string) => {
isVerified: () => boolean
}
}
interface Room {
getEncryptionTargetMembers: () => Promise<[{userId: string}]>;
roomId: string;
}
export async function shieldStatusForRoom(client: Client, room: Room): Promise<string> {
const members = (await room.getEncryptionTargetMembers()).map(({userId}) => userId);
const inDMMap = !!DMRoomMap.shared().getUserIdForRoomId(room.roomId);
const verified: string[] = [];
const unverified: string[] = [];
members.filter((userId) => userId !== client.getUserId())
.forEach((userId) => {
(client.checkUserTrust(userId).isCrossSigningVerified() ?
verified : unverified).push(userId);
});
/* Alarm if any unverified users were verified before. */
for (const userId of unverified) {
if (client.checkUserTrust(userId).wasCrossSigningVerified()) {
return "warning";
}
}
/* Check all verified user devices. */
/* Don't alarm if no other users are verified */
const includeUser = (verified.length > 0) && // Don't alarm for self in rooms where nobody else is verified
!inDMMap && // Don't alarm for self in DMs with other users
(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;
for (const userId of targets) {
const devices = client.getStoredDevicesForUser(userId);
const anyDeviceNotVerified = devices.some(({deviceId}) => {
return !client.checkDeviceTrust(userId, deviceId).isVerified();
});
if (anyDeviceNotVerified) {
return "warning";
}
}
return unverified.length === 0 ? "verified" : "normal";
}