From 6a761af86746517edbf415f4b3e16d4bd888d3b1 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Tue, 3 Oct 2023 13:37:58 +0100 Subject: [PATCH] Element-R: emit `VerificationRequestReceived` on incoming request (#3762) --- spec/integ/crypto/verification.spec.ts | 50 ++++++++++++++++++++------ src/rust-crypto/rust-crypto.ts | 28 ++++++++++++++- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/spec/integ/crypto/verification.spec.ts b/spec/integ/crypto/verification.spec.ts index f477db48b78..84be643278f 100644 --- a/spec/integ/crypto/verification.spec.ts +++ b/spec/integ/crypto/verification.spec.ts @@ -980,12 +980,43 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st }); } + it("Verification request not found", async () => { + // Expect to not find any verification request + const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz"); + expect(request).toBeUndefined(); + }); + + it("ignores old verification requests", async () => { + const eventHandler = jest.fn(); + aliceClient.on(CryptoEvent.VerificationRequestReceived, eventHandler); + + const verificationRequestEvent = createVerificationRequestEvent(); + verificationRequestEvent.origin_server_ts -= 1000000; + returnRoomMessageFromSync(TEST_ROOM_ID, verificationRequestEvent); + + await syncPromise(aliceClient); + + // make sure the event has arrived + const room = aliceClient.getRoom(TEST_ROOM_ID)!; + const matrixEvent = room.getLiveTimeline().getEvents()[0]; + expect(matrixEvent.getId()).toEqual(verificationRequestEvent.event_id); + + // check that an event has not been raised, and that the request is not found + expect(eventHandler).not.toHaveBeenCalled(); + expect( + aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz"), + ).not.toBeDefined(); + }); + it("Plaintext verification request from Bob to Alice", async () => { // Add verification request from Bob to Alice in the DM between them returnRoomMessageFromSync(TEST_ROOM_ID, createVerificationRequestEvent()); - // Wait for the sync response to be processed - await syncPromise(aliceClient); + // Wait for the request to be received + const request1 = await emitPromise(aliceClient, CryptoEvent.VerificationRequestReceived); + expect(request1.roomId).toBe(TEST_ROOM_ID); + expect(request1.isSelfVerification).toBe(false); + expect(request1.otherUserId).toBe("@bob:xyz"); const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz"); // Expect to find the verification request received during the sync @@ -994,12 +1025,6 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st expect(request?.otherUserId).toBe("@bob:xyz"); }); - it("Verification request not found", async () => { - // Expect to not find any verification request - const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz"); - expect(request).not.toBeDefined(); - }); - it("Encrypted verification request from Bob to Alice", async () => { const p2pSession = await createOlmSession(testOlmAccount, e2eKeyReceiver); const groupSession = new Olm.OutboundGroupSession(); @@ -1021,14 +1046,19 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st await awaitDecryption(matrixEvent); expect(matrixEvent.getContent().msgtype).toEqual("m.bad.encrypted"); + const requestEventPromise = emitPromise(aliceClient, CryptoEvent.VerificationRequestReceived); + // Send Bob the room keys returnToDeviceMessageFromSync(toDeviceEvent); // advance the clock, because the devicelist likes to sleep for 5ms during key downloads await jest.advanceTimersByTimeAsync(10); - // Wait for the message to be decrypted - await awaitDecryption(matrixEvent, { waitOnDecryptionFailure: true }); + // Wait for the request to be decrypted + const request1 = await requestEventPromise; + expect(request1.roomId).toBe(TEST_ROOM_ID); + expect(request1.isSelfVerification).toBe(false); + expect(request1.otherUserId).toBe("@bob:xyz"); const request = aliceClient.getCrypto()!.findVerificationRequestDMInProgress(TEST_ROOM_ID, "@bob:xyz"); // Expect to find the verification request received during the sync diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 852993b763b..997d7d137a3 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -62,7 +62,7 @@ import { keyFromPassphrase } from "../crypto/key_passphrase"; import { encodeRecoveryKey } from "../crypto/recoverykey"; import { crypto } from "../crypto/crypto"; import { isVerificationEvent, RustVerificationRequest, verificationMethodIdentifierToMethod } from "./verification"; -import { EventType } from "../@types/event"; +import { EventType, MsgType } from "../@types/event"; import { CryptoEvent } from "../crypto"; import { TypedEventEmitter } from "../models/typed-event-emitter"; import { RustBackupCryptoEventMap, RustBackupCryptoEvents, RustBackupDecryptor, RustBackupManager } from "./backup"; @@ -1407,6 +1407,32 @@ export class RustCrypto extends TypedEventEmitter