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

Element-R: implement cancellation of verification requests #3505

Merged
merged 1 commit into from
Jun 26, 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
36 changes: 35 additions & 1 deletion spec/integ/crypto/verification.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
await verificationPromise;
expect(request.phase).toEqual(VerificationPhase.Done);

// at this point, cancelling should do nothing.
await request.cancel();
expect(request.phase).toEqual(VerificationPhase.Done);

// we're done with the temporary keypair
olmSAS.free();
});
Expand Down Expand Up @@ -406,11 +410,41 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st
await verificationPromise;
expect(request.phase).toEqual(VerificationPhase.Done);
});
});

describe("cancellation", () => {
beforeEach(async () => {
// pretend that we have another device, which we will start verifying
e2eKeyResponder.addDeviceKeys(TEST_USER_ID, TEST_DEVICE_ID, SIGNED_TEST_DEVICE_DATA);

it("can cancel during the SAS phase", async () => {
aliceClient = await startTestClient();
await waitForDeviceList();
});

it("can cancel during the Ready phase", async () => {
// have alice initiate a verification. She should send a m.key.verification.request
const [, request] = await Promise.all([
expectSendToDeviceMessage("m.key.verification.request"),
aliceClient.getCrypto()!.requestDeviceVerification(TEST_USER_ID, TEST_DEVICE_ID),
]);
const transactionId = request.transactionId!;

// The dummy device replies with an m.key.verification.ready...
returnToDeviceMessageFromSync(buildReadyMessage(transactionId, ["m.sas.v1"]));
await waitForVerificationRequestChanged(request);

// now alice changes her mind
const [requestBody] = await Promise.all([
expectSendToDeviceMessage("m.key.verification.cancel"),
request.cancel(),
]);
const toDeviceMessage = requestBody.messages[TEST_USER_ID][TEST_DEVICE_ID];
expect(toDeviceMessage.transaction_id).toEqual(transactionId);
expect(toDeviceMessage.code).toEqual("m.user");
richvdh marked this conversation as resolved.
Show resolved Hide resolved
expect(request.phase).toEqual(VerificationPhase.Cancelled);
});

it("can cancel during the SAS phase", async () => {
// have alice initiate a verification. She should send a m.key.verification.request
const [, request] = await Promise.all([
expectSendToDeviceMessage("m.key.verification.request"),
Expand Down
2 changes: 1 addition & 1 deletion src/crypto-api/verification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export interface VerificationRequest
* Cancels the request, sending a cancellation to the other party
*
* @param params - Details for the cancellation, including `reason` (defaults to "User declined"), and `code`
* (defaults to `m.user`).
* (defaults to `m.user`). **Deprecated**: this parameter is ignored by the Rust cryptography implementation.
*
* @returns Promise which resolves when the event has been sent.
*/
Expand Down
9 changes: 6 additions & 3 deletions src/rust-crypto/verification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class RustVerificationRequest

public constructor(
private readonly inner: RustSdkCryptoJs.VerificationRequest,
outgoingRequestProcessor: OutgoingRequestProcessor,
private readonly outgoingRequestProcessor: OutgoingRequestProcessor,
) {
super();

Expand Down Expand Up @@ -210,8 +210,11 @@ export class RustVerificationRequest
*
* @returns Promise which resolves when the event has been sent.
*/
public cancel(params?: { reason?: string; code?: string }): Promise<void> {
throw new Error("not implemented");
public async cancel(params?: { reason?: string; code?: string }): Promise<void> {
const req: undefined | OutgoingRequest = this.inner.cancel();
if (req) {
await this.outgoingRequestProcessor.makeOutgoingRequest(req);
}
}

/**
Expand Down
Loading