Skip to content

Commit

Permalink
Add getUserDeviceInfo to CryptoBackend and old crypto impl
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros committed Apr 12, 2023
1 parent 6049c0b commit 58285ab
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/common-crypto/CryptoBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { CryptoApi } from "../crypto-api";
import { DeviceTrustLevel, UserTrustLevel } from "../crypto/CrossSigning";
import { IEncryptedEventInfo } from "../crypto/api";
import { IEventDecryptionResult } from "../@types/crypto";
import { DeviceMap } from "../crypto/deviceinfo";

/**
* Common interface for the crypto implementations
Expand Down Expand Up @@ -87,6 +88,17 @@ export interface CryptoBackend extends SyncCryptoCallbacks, CryptoApi {
* @param event - event to be checked
*/
getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo;

/**
* Get the device information for the given list of users.
*
* @param userIds - The users to fetch.
* @param downloadUncached - If true, download the device list for users whose device list we are not
* currently tracking. Defaults to false, in which case such users will not appear at all in the result map.
*
* @returns A map `{@link DeviceMap}`.
*/
getUserDeviceInfo(userIds: string[], downloadUncached?: boolean): Promise<DeviceMap>;
}

/** The methods which crypto implementations should expose to the Sync api */
Expand Down
3 changes: 3 additions & 0 deletions src/crypto/deviceinfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export interface IDevice {
signatures?: ISignatures;
}

// user-Id → device-Id → IDevice
export type DeviceMap = Map<string, Map<string, IDevice>>;

enum DeviceVerification {
Blocked = -1,
Unverified = 0,
Expand Down
48 changes: 47 additions & 1 deletion src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { IExportedDevice, OlmDevice } from "./OlmDevice";
import { IOlmDevice } from "./algorithms/megolm";
import * as olmlib from "./olmlib";
import { DeviceInfoMap, DeviceList } from "./DeviceList";
import { DeviceInfo, IDevice } from "./deviceinfo";
import { DeviceInfo, DeviceMap, IDevice } from "./deviceinfo";
import type { DecryptionAlgorithm, EncryptionAlgorithm } from "./algorithms";
import * as algorithms from "./algorithms";
import { createCryptoStoreCacheCallbacks, CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from "./CrossSigning";
Expand Down Expand Up @@ -2016,6 +2016,52 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return this.deviceList.getStoredDevicesForUser(userId);
}

/**
* Get the device information for the given list of users.
*
* @param userIds - The users to fetch.
* @param downloadUncached - If true, download the device list for users whose device list we are not
* currently tracking. Defaults to false, in which case such users will not appear at all in the result map.
*
* @returns A map `{@link DeviceMap}`.
*/
public async getUserDeviceInfo(userIds: string[], downloadUncached = false): Promise<DeviceMap> {
const iDeviceMapByUserId = new Map<string, Map<string, IDevice>>();
// Keep the users without device to download theirs keys
const usersWithoutDeviceInfo: string[] = [];

for (const userId of userIds) {
const deviceInfos = await this.getStoredDevicesForUser(userId);
// If there are device infos for a userId, we transform it into a map
// Else, the keys will be downloaded after
if (deviceInfos) {
const iDeviceMap = new Map(
// Convert DeviceInfo to IDevice
deviceInfos.map((deviceInfo) => [deviceInfo.deviceId, deviceInfo.toStorage()]),
);
iDeviceMapByUserId.set(userId, iDeviceMap);
} else {
usersWithoutDeviceInfo.push(userId);
}
}

// Download device info for users without device infos
if (downloadUncached && usersWithoutDeviceInfo.length > 0) {
const newDeviceInfoMap = await this.downloadKeys(usersWithoutDeviceInfo);

newDeviceInfoMap.forEach((deviceInfoMap, userId) => {
const iDeviceMap = new Map<string, IDevice>();
// Convert DeviceInfo to IDevice
deviceInfoMap.forEach((deviceInfo, deviceId) => iDeviceMap.set(deviceId, deviceInfo.toStorage()));

// Put the new device infos into the returned map
iDeviceMapByUserId.set(userId, iDeviceMap);
});
}

return iDeviceMapByUserId;
}

/**
* Get the stored keys for a single device
*
Expand Down
14 changes: 14 additions & 0 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { RoomEncryptor } from "./RoomEncryptor";
import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor";
import { KeyClaimManager } from "./KeyClaimManager";
import { MapWithDefault } from "../utils";
import { DeviceMap } from "../crypto/deviceinfo";

/**
* An implementation of {@link CryptoBackend} using the Rust matrix-sdk-crypto.
Expand Down Expand Up @@ -165,6 +166,19 @@ export class RustCrypto implements CryptoBackend {
return [];
}

/**
* Get the device information for the given list of users.
*
* @param userIds - The users to fetch.
* @param downloadUncached - If true, download the device list for users whose device list we are not
* currently tracking. Defaults to false, in which case such users will not appear at all in the result map.
*
* @returns A map `{@link DeviceMap}`.
*/
public async getUserDeviceInfo(userIds: string[], downloadUncached = false): Promise<DeviceMap> {
return new Map();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// SyncCryptoCallbacks implementation
Expand Down

0 comments on commit 58285ab

Please sign in to comment.