Device manager - verify other devices (PSG-724) (#9274)
* trigger verification of other devices * tests * fix strict errors * add types
This commit is contained in:
parent
236ca2e494
commit
4623d84dd0
6 changed files with 181 additions and 15 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue