From 74fae45f05989031f3e246bdc9fe730b0dfc7533 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Fri, 21 Apr 2023 14:40:02 +0200 Subject: [PATCH] Review of `device.ts` --- spec/unit/device-converter.spec.ts | 17 +++++++-------- src/crypto/device-converter.ts | 4 ++-- src/crypto/deviceinfo.ts | 7 +----- src/matrix.ts | 1 + src/models/device.ts | 33 +++++++++++++++-------------- src/rust-crypto/device-converter.ts | 16 ++++---------- 6 files changed, 33 insertions(+), 45 deletions(-) diff --git a/spec/unit/device-converter.spec.ts b/spec/unit/device-converter.spec.ts index 261d015ed6c..0dd1780b635 100644 --- a/spec/unit/device-converter.spec.ts +++ b/spec/unit/device-converter.spec.ts @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { DeviceInfo, DeviceVerification } from "../../src/crypto/deviceinfo"; -import { DeviceKeys } from "../../src"; +import { DeviceInfo } from "../../src/crypto/deviceinfo"; +import { DeviceKeys, DeviceVerification } from "../../src"; import { downloadDeviceToJsDevice } from "../../src/rust-crypto/device-converter"; import { deviceInfoToDevice } from "../../src/crypto/device-converter"; @@ -31,8 +31,9 @@ describe("device-converter", () => { const algorithms = ["algo1", "algo2"]; const verified = DeviceVerification.Verified; const signatures = { [userId]: { [deviceId]: "sign1" } }; + const displayName = "display name"; const unsigned = { - device_display_name: "display name", + device_display_name: displayName, }; describe("deviceInfoToDevice", () => { @@ -45,14 +46,13 @@ describe("device-converter", () => { expect(device.verified).toBe(verified); expect(device.getIdentityKey()).toBe(keys[`curve25519:${deviceId}`]); expect(device.getFingerprint()).toBe(keys[`ed25519:${deviceId}`]); - expect(device.getDisplayName()).toBe(unsigned.device_display_name); + expect(device.displayName).toBe(displayName); }); - it("should add empty signatures and unsigned map", () => { + it("should add empty signatures", () => { const deviceInfo = DeviceInfo.fromStorage({ keys, algorithms, verified }, deviceId); const device = deviceInfoToDevice(deviceInfo, userId); - expect(device.unsigned.size).toBe(0); expect(device.signatures.size).toBe(0); }); }); @@ -74,10 +74,10 @@ describe("device-converter", () => { expect(device.verified).toBe(DeviceVerification.Unverified); expect(device.getIdentityKey()).toBe(keys[`curve25519:${deviceId}`]); expect(device.getFingerprint()).toBe(keys[`ed25519:${deviceId}`]); - expect(device.getDisplayName()).toBe(unsigned.device_display_name); + expect(device.displayName).toBe(displayName); }); - it("should add empty signatures and unsigned map", () => { + it("should add empty signatures", () => { const queryDevice: DeviceKeys[keyof DeviceKeys] = { keys, algorithms, @@ -86,7 +86,6 @@ describe("device-converter", () => { }; const device = downloadDeviceToJsDevice(queryDevice); - expect(device.unsigned.size).toBe(0); expect(device.signatures.size).toBe(0); }); }); diff --git a/src/crypto/device-converter.ts b/src/crypto/device-converter.ts index 4776f67d171..91e21194888 100644 --- a/src/crypto/device-converter.ts +++ b/src/crypto/device-converter.ts @@ -24,7 +24,7 @@ import { DeviceInfo } from "./deviceinfo"; */ export function deviceInfoToDevice(deviceInfo: DeviceInfo, userId: string): Device { const keys = new Map(Object.entries(deviceInfo.keys)); - const unsigned = new Map(Object.entries(deviceInfo.unsigned || {})); + const displayName = deviceInfo.getDisplayName() || undefined; const signatures = new Map>(); if (deviceInfo.signatures) { @@ -40,6 +40,6 @@ export function deviceInfoToDevice(deviceInfo: DeviceInfo, userId: string): Devi algorithms: deviceInfo.algorithms, verified: deviceInfo.verified, signatures, - unsigned, + displayName, }); } diff --git a/src/crypto/deviceinfo.ts b/src/crypto/deviceinfo.ts index 993e768f1c6..76113e3ad76 100644 --- a/src/crypto/deviceinfo.ts +++ b/src/crypto/deviceinfo.ts @@ -15,6 +15,7 @@ limitations under the License. */ import { ISignatures } from "../@types/signed"; +import { DeviceVerification } from "../models/device"; export interface IDevice { keys: Record; @@ -25,12 +26,6 @@ export interface IDevice { signatures?: ISignatures; } -export enum DeviceVerification { - Blocked = -1, - Unverified = 0, - Verified = 1, -} - /** * Information about a user's device */ diff --git a/src/matrix.ts b/src/matrix.ts index 2fb71ab6402..a60376df6a4 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -38,6 +38,7 @@ export * from "./models/poll"; export * from "./models/room-member"; export * from "./models/room-state"; export * from "./models/user"; +export * from "./models/device"; export * from "./scheduler"; export * from "./filter"; export * from "./timeline-window"; diff --git a/src/models/device.ts b/src/models/device.ts index e21b2f44dac..c40c4552778 100644 --- a/src/models/device.ts +++ b/src/models/device.ts @@ -14,18 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { DeviceVerification } from "../crypto/deviceinfo"; +/** State of the verification of the device. + * Beware that the enum values are numbers instead of plain strings + */ +export enum DeviceVerification { + Blocked = -1, + Unverified = 0, + Verified = 1, +} -// user-Id → device-Id → IDevice +/** A map from user ID to device ID to Device */ export type DeviceMap = Map>; type DeviceParameters = Pick & Partial; +/** + * Information on a user's device, as returned by {@link CryptoApi.getUserDeviceInfo}. + */ export class Device { /** id of the device */ public readonly deviceId: string; - /** id of the device user */ + /** id of the user that owns the device */ public readonly userId: string; /** list of algorithms supported by this device */ @@ -37,20 +47,20 @@ export class Device { /** whether the device has been verified/blocked by the user */ public readonly verified: DeviceVerification; - /** additional data from the homeserver */ - public readonly unsigned: Map; - /** a map `>` */ public readonly signatures: Map>; + /** display name of the device */ + public readonly displayName?: string; + public constructor(opts: DeviceParameters) { this.deviceId = opts.deviceId; this.userId = opts.userId; this.algorithms = opts.algorithms; this.keys = opts.keys; this.verified = opts.verified || DeviceVerification.Unverified; - this.unsigned = opts.unsigned || new Map(); this.signatures = opts.signatures || new Map(); + this.displayName = opts.displayName; } /** @@ -70,13 +80,4 @@ export class Device { public getIdentityKey(): string | undefined { return this.keys.get(`curve25519:${this.deviceId}`); } - - /** - * Get the configured display name for this device, if any - * In `unsigned.device_display_name` - * @returns the device display name - */ - public getDisplayName(): string | undefined { - return this.unsigned.get("device_display_name"); - } } diff --git a/src/rust-crypto/device-converter.ts b/src/rust-crypto/device-converter.ts index 3d6374302f9..54dc838fe1f 100644 --- a/src/rust-crypto/device-converter.ts +++ b/src/rust-crypto/device-converter.ts @@ -16,8 +16,7 @@ limitations under the License. import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-js"; -import { DeviceVerification } from "../crypto/deviceinfo"; -import { Device } from "../models/device"; +import { Device, DeviceVerification } from "../models/device"; import { DeviceKeys } from "../client"; /** @@ -71,13 +70,6 @@ export function rustDeviceToJsDevice(device: RustSdkCryptoJs.Device, userId: Rus } }); - // Add device display name to unsigned field - const unsigned = new Map(); - const { displayName } = device; - if (displayName) { - unsigned.set("device_display_name", displayName); - } - return new Device({ deviceId: device.deviceId.toString(), userId: userId.toString(), @@ -85,7 +77,7 @@ export function rustDeviceToJsDevice(device: RustSdkCryptoJs.Device, userId: Rus algorithms: Array.from(algorithms), verified, signatures, - unsigned, + displayName: device.displayName, }); } @@ -108,7 +100,7 @@ type QueryDevice = DeviceKeys[keyof DeviceKeys]; */ export function downloadDeviceToJsDevice(device: QueryDevice): Device { const keys = new Map(Object.entries(device.keys)); - const unsigned = new Map(Object.entries(device.unsigned || {})); + const displayName = device.unsigned?.device_display_name; const signatures = new Map>(); if (device.signatures) { @@ -124,6 +116,6 @@ export function downloadDeviceToJsDevice(device: QueryDevice): Device { algorithms: device.algorithms, verified: DeviceVerification.Unverified, signatures, - unsigned, + displayName, }); }