Device manager - verify other devices (PSG-724) (#9274)

* trigger verification of other devices

* tests

* fix strict errors

* add types
This commit is contained in:
Kerry 2022-09-14 12:40:26 +02:00 committed by GitHub
parent 236ca2e494
commit 4623d84dd0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 181 additions and 15 deletions

View file

@ -17,10 +17,13 @@ limitations under the License.
import { useCallback, useContext, useEffect, useState } from "react";
import { IMyDevice, MatrixClient } from "matrix-js-sdk/src/matrix";
import { CrossSigningInfo } from "matrix-js-sdk/src/crypto/CrossSigning";
import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
import { User } from "matrix-js-sdk/src/models/user";
import { MatrixError } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import MatrixClientContext from "../../../../contexts/MatrixClientContext";
import { DevicesDictionary } from "./types";
import { DevicesDictionary, DeviceWithVerification } from "./types";
const isDeviceVerified = (
matrixClient: MatrixClient,
@ -28,7 +31,14 @@ const isDeviceVerified = (
device: IMyDevice,
): boolean | null => {
try {
const deviceInfo = matrixClient.getStoredDevice(matrixClient.getUserId(), device.device_id);
const userId = matrixClient.getUserId();
if (!userId) {
throw new Error('No user id');
}
const deviceInfo = matrixClient.getStoredDevice(userId, device.device_id);
if (!deviceInfo) {
throw new Error('No device info available');
}
return crossSigningInfo.checkDeviceTrust(
crossSigningInfo,
deviceInfo,
@ -41,9 +51,13 @@ const isDeviceVerified = (
}
};
const fetchDevicesWithVerification = async (matrixClient: MatrixClient): Promise<DevicesState['devices']> => {
const fetchDevicesWithVerification = async (
matrixClient: MatrixClient,
userId: string,
): Promise<DevicesState['devices']> => {
const { devices } = await matrixClient.getDevices();
const crossSigningInfo = matrixClient.getStoredCrossSigningForUser(matrixClient.getUserId());
const crossSigningInfo = matrixClient.getStoredCrossSigningForUser(userId);
const devicesDict = devices.reduce((acc, device: IMyDevice) => ({
...acc,
@ -63,7 +77,10 @@ export enum OwnDevicesError {
type DevicesState = {
devices: DevicesDictionary;
currentDeviceId: string;
currentUserMember?: User;
isLoading: boolean;
// not provided when current session cannot request verification
requestDeviceVerification?: (deviceId: DeviceWithVerification['device_id']) => Promise<VerificationRequest>;
refreshDevices: () => Promise<void>;
error?: OwnDevicesError;
};
@ -71,6 +88,7 @@ export const useOwnDevices = (): DevicesState => {
const matrixClient = useContext(MatrixClientContext);
const currentDeviceId = matrixClient.getDeviceId();
const userId = matrixClient.getUserId();
const [devices, setDevices] = useState<DevicesState['devices']>({});
const [isLoading, setIsLoading] = useState(true);
@ -79,11 +97,16 @@ export const useOwnDevices = (): DevicesState => {
const refreshDevices = useCallback(async () => {
setIsLoading(true);
try {
const devices = await fetchDevicesWithVerification(matrixClient);
// realistically we should never hit this
// but it satisfies types
if (!userId) {
throw new Error('Cannot fetch devices without user id');
}
const devices = await fetchDevicesWithVerification(matrixClient, userId);
setDevices(devices);
setIsLoading(false);
} catch (error) {
if (error.httpStatus == 404) {
if ((error as MatrixError).httpStatus == 404) {
// 404 probably means the HS doesn't yet support the API.
setError(OwnDevicesError.Unsupported);
} else {
@ -92,15 +115,28 @@ export const useOwnDevices = (): DevicesState => {
}
setIsLoading(false);
}
}, [matrixClient]);
}, [matrixClient, userId]);
useEffect(() => {
refreshDevices();
}, [refreshDevices]);
const isCurrentDeviceVerified = !!devices[currentDeviceId]?.isVerified;
const requestDeviceVerification = isCurrentDeviceVerified && userId
? async (deviceId: DeviceWithVerification['device_id']) => {
return await matrixClient.requestVerification(
userId,
[deviceId],
);
}
: undefined;
return {
devices,
currentDeviceId,
currentUserMember: userId && matrixClient.getUser(userId) || undefined,
requestDeviceVerification,
refreshDevices,
isLoading,
error,