Skip to content

Commit

Permalink
Add new methods for verification to CryptoApi (#3474)
Browse files Browse the repository at this point in the history
* Add accessors for verification requests to CryptoApi

Part of element-hq/crypto-internal#97

* Add new methods for verification to `CryptoApi` and deprecate old method

element-hq/crypto-internal#98
  • Loading branch information
richvdh committed Jun 15, 2023
1 parent 1bae10c commit 22f0b78
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 29 deletions.
10 changes: 5 additions & 5 deletions spec/integ/crypto/verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import { MockResponse } from "fetch-mock";

import { createClient, CryptoEvent, MatrixClient } from "../../../src";
import {
canAcceptVerificationRequest,
ShowQrCodeCallbacks,
ShowSasCallbacks,
Verifier,
VerifierEvent,
VerificationPhase,
VerificationRequest,
VerificationRequestEvent,
canAcceptVerificationRequest,
Verifier,
VerifierEvent,
} from "../../../src/crypto-api/verification";
import { escapeRegExp } from "../../../src/utils";
import { CRYPTO_BACKENDS, emitPromise, InitCrypto } from "../../test-utils/test-utils";
Expand Down Expand Up @@ -130,7 +130,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
// have alice initiate a verification. She should send a m.key.verification.request
let [requestBody, request] = await Promise.all([
expectSendToDeviceMessage("m.key.verification.request"),
aliceClient.requestVerification(TEST_USER_ID, [TEST_DEVICE_ID]),
aliceClient.getCrypto()!.requestDeviceVerification(TEST_USER_ID, TEST_DEVICE_ID),
]);
const transactionId = request.transactionId;
expect(transactionId).toBeDefined();
Expand Down Expand Up @@ -273,7 +273,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
// have alice initiate a verification. She should send a m.key.verification.request
const [requestBody, request] = await Promise.all([
expectSendToDeviceMessage("m.key.verification.request"),
aliceClient.requestVerification(TEST_USER_ID, [TEST_DEVICE_ID]),
aliceClient.getCrypto()!.requestDeviceVerification(TEST_USER_ID, TEST_DEVICE_ID),
]);
const transactionId = request.transactionId;

Expand Down
10 changes: 9 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2431,12 +2431,17 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @param roomId - the room to use for verification
*
* @returns the VerificationRequest that is in progress, if any
* @deprecated Prefer {@link CryptoApi.findVerificationRequestDMInProgress}.
*/
public findVerificationRequestDMInProgress(roomId: string): VerificationRequest | undefined {
if (!this.cryptoBackend) {
throw new Error("End-to-end encryption disabled");
} else if (!this.crypto) {
// Hack for element-R to avoid breaking the cypress tests. We can get rid of this once the react-sdk is
// updated to use CryptoApi.findVerificationRequestDMInProgress.
return undefined;
}
return this.cryptoBackend.findVerificationRequestDMInProgress(roomId);
return this.crypto.findVerificationRequestDMInProgress(roomId);
}

/**
Expand All @@ -2445,6 +2450,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @param userId - the ID of the user to query
*
* @returns the VerificationRequests that are in progress
* @deprecated Prefer {@link CryptoApi.getVerificationRequestsToDeviceInProgress}.
*/
public getVerificationRequestsToDeviceInProgress(userId: string): VerificationRequest[] {
if (!this.crypto) {
Expand All @@ -2462,6 +2468,8 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
*
* @returns resolves to a VerificationRequest
* when the request has been sent to the other party.
*
* @deprecated Prefer {@link CryptoApi#requestOwnUserVerification} or {@link CryptoApi#requestDeviceVerification}.
*/
public requestVerification(userId: string, devices?: string[]): Promise<VerificationRequest> {
if (!this.crypto) {
Expand Down
10 changes: 0 additions & 10 deletions src/common-crypto/CryptoBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { CryptoApi } from "../crypto-api";
import { CrossSigningInfo, UserTrustLevel } from "../crypto/CrossSigning";
import { IEncryptedEventInfo } from "../crypto/api";
import { IEventDecryptionResult } from "../@types/crypto";
import { VerificationRequest } from "../crypto/verification/request/VerificationRequest";

/**
* Common interface for the crypto implementations
Expand Down Expand Up @@ -79,15 +78,6 @@ export interface CryptoBackend extends SyncCryptoCallbacks, CryptoApi {
*/
getEventEncryptionInfo(event: MatrixEvent): IEncryptedEventInfo;

/**
* Finds a DM verification request that is already in progress for the given room id
*
* @param roomId - the room to use for verification
*
* @returns the VerificationRequest that is in progress, if any
*/
findVerificationRequestDMInProgress(roomId: string): VerificationRequest | undefined;

/**
* Get the cross signing information for a given user.
*
Expand Down
46 changes: 46 additions & 0 deletions src/crypto-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Room } from "./models/room";
import { DeviceMap } from "./models/device";
import { UIAuthCallback } from "./interactive-auth";
import { AddSecretStorageKeyOpts } from "./secret-storage";
import { VerificationRequest } from "./crypto-api/verification";

/** Types of cross-signing key */
export enum CrossSigningKey {
Expand Down Expand Up @@ -227,6 +228,51 @@ export interface CryptoApi {
* The private key should be disposed of after displaying to the use.
*/
createRecoveryKeyFromPassphrase(password?: string): Promise<GeneratedSecretStorageKey>;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Device/User verification
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Returns to-device verification requests that are already in progress for the given user id.
*
* @param userId - the ID of the user to query
*
* @returns the VerificationRequests that are in progress
*/
getVerificationRequestsToDeviceInProgress(userId: string): VerificationRequest[];

/**
* Finds a DM verification request that is already in progress for the given room id
*
* @param roomId - the room to use for verification
*
* @returns the VerificationRequest that is in progress, if any
*/
findVerificationRequestDMInProgress(roomId: string): VerificationRequest | undefined;

/**
* Send a verification request to our other devices.
*
* If a verification is already in flight, returns it. Otherwise, initiates a new one.
*
* @returns a VerificationRequest when the request has been sent to the other party.
*/
requestOwnUserVerification(): Promise<VerificationRequest>;

/**
* Request an interactive verification with the given device.
*
* If a verification is already in flight, returns it. Otherwise, initiates a new one.
*
* @param userId - ID of the owner of the device to verify
* @param deviceId - ID of the device to verify
*
* @returns a VerificationRequest when the request has been sent to the other party.
*/
requestDeviceVerification(userId: string, deviceId: string): Promise<VerificationRequest>;
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2356,6 +2356,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return this.requestVerificationWithChannel(userId, channel, this.inRoomVerificationRequests);
}

/** @deprecated Use `requestOwnUserVerificationToDevice` or `requestDeviceVerification` */
public requestVerification(userId: string, devices?: string[]): Promise<VerificationRequest> {
if (!devices) {
devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(userId));
Expand All @@ -2368,6 +2369,14 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return this.requestVerificationWithChannel(userId, channel, this.toDeviceVerificationRequests);
}

public requestOwnUserVerification(): Promise<VerificationRequest> {
return this.requestVerification(this.userId);
}

public requestDeviceVerification(userId: string, deviceId: string): Promise<VerificationRequest> {
return this.requestVerification(userId, [deviceId]);
}

private async requestVerificationWithChannel(
userId: string,
channel: IVerificationChannel,
Expand Down
73 changes: 60 additions & 13 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ import { KeyClaimManager } from "./KeyClaimManager";
import { MapWithDefault } from "../utils";
import {
BootstrapCrossSigningOpts,
CrossSigningKey,
CrossSigningStatus,
DeviceVerificationStatus,
GeneratedSecretStorageKey,
ImportRoomKeyProgressData,
ImportRoomKeysOpts,
CrossSigningKey,
VerificationRequest,
} from "../crypto-api";
import { deviceKeysToDeviceMap, rustDeviceToJsDevice } from "./device-converter";
import { IDownloadKeyResult, IQueryKeysRequest } from "../client";
Expand Down Expand Up @@ -165,18 +166,6 @@ export class RustCrypto implements CryptoBackend {
return new UserTrustLevel(false, false, false);
}

/**
* Finds a DM verification request that is already in progress for the given room id
*
* @param roomId - the room to use for verification
*
* @returns the VerificationRequest that is in progress, if any
*/
public findVerificationRequestDMInProgress(roomId: string): undefined {
// TODO
return;
}

/**
* Get the cross signing information for a given user.
*
Expand Down Expand Up @@ -439,6 +428,64 @@ export class RustCrypto implements CryptoBackend {
};
}

/**
* Returns to-device verification requests that are already in progress for the given user id.
*
* Implementation of {@link CryptoApi#getVerificationRequestsToDeviceInProgress}
*
* @param userId - the ID of the user to query
*
* @returns the VerificationRequests that are in progress
*/
public getVerificationRequestsToDeviceInProgress(userId: string): VerificationRequest[] {
// TODO
return [];
}

/**
* Finds a DM verification request that is already in progress for the given room id
*
* Implementation of {@link CryptoApi#findVerificationRequestDMInProgress}
*
* @param roomId - the room to use for verification
*
* @returns the VerificationRequest that is in progress, if any
*
*/
public findVerificationRequestDMInProgress(roomId: string): undefined {
// TODO
return;
}

/**
* Send a verification request to our other devices.
*
* If a verification is already in flight, returns it. Otherwise, initiates a new one.
*
* Implementation of {@link CryptoApi#requestOwnUserVerification}.
*
* @returns a VerificationRequest when the request has been sent to the other party.
*/
public requestOwnUserVerification(): Promise<VerificationRequest> {
throw new Error("not implemented");
}

/**
* Request an interactive verification with the given device.
*
* If a verification is already in flight, returns it. Otherwise, initiates a new one.
*
* Implementation of {@link CryptoApi#requestDeviceVerification }.
*
* @param userId - ID of the owner of the device to verify
* @param deviceId - ID of the device to verify
*
* @returns a VerificationRequest when the request has been sent to the other party.
*/
public requestDeviceVerification(userId: string, deviceId: string): Promise<VerificationRequest> {
throw new Error("not implemented");
}

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

0 comments on commit 22f0b78

Please sign in to comment.