Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new methods for verification to CryptoApi #3474

Merged
merged 4 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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