From af63d9bd05491b4ace9064f2f288db13cd4455df Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Thu, 5 Oct 2023 10:17:39 +0200 Subject: [PATCH] Element-R: Avoid errors in `VerificationRequest.generateQRCode` when QR code is unavailable (#3779) * Avoid `VerificationRequest.generateQRCode` to crash when QRCode is unavailable * Add tests `can try to generate a QR code when QR code is not supported` --- spec/integ/crypto/verification.spec.ts | 23 +++++++++++++++++++++++ src/rust-crypto/verification.ts | 5 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/spec/integ/crypto/verification.spec.ts b/spec/integ/crypto/verification.spec.ts index 84be643278f..918ed7cab67 100644 --- a/spec/integ/crypto/verification.spec.ts +++ b/spec/integ/crypto/verification.spec.ts @@ -498,6 +498,29 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("verification (%s)", (backend: st expect(request.phase).toEqual(VerificationPhase.Done); }); + it("can try to generate a QR code when QR code is not supported", async () => { + aliceClient = await startTestClient(); + // we need cross-signing keys for a QR code verification + e2eKeyResponder.addCrossSigningData(SIGNED_CROSS_SIGNING_KEYS_DATA); + await waitForDeviceList(); + + // Alice sends 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, indicating it can only use SaS + returnToDeviceMessageFromSync(buildReadyMessage(transactionId, ["m.sas.v1"])); + await waitForVerificationRequestChanged(request); + expect(request.phase).toEqual(VerificationPhase.Ready); + + // Alice tries to generate a QR Code but it's unavailable + const qrCodeBuffer = await request.generateQRCode(); + expect(qrCodeBuffer).toBeUndefined(); + }); + newBackendOnly("can verify another by scanning their QR code", async () => { aliceClient = await startTestClient(); // we need cross-signing keys for a QR code verification diff --git a/src/rust-crypto/verification.ts b/src/rust-crypto/verification.ts index ef8c9453812..308e7169c83 100644 --- a/src/rust-crypto/verification.ts +++ b/src/rust-crypto/verification.ts @@ -392,7 +392,10 @@ export class RustVerificationRequest * Implementation of {@link Crypto.VerificationRequest#generateQRCode}. */ public async generateQRCode(): Promise { - const innerVerifier: RustSdkCryptoJs.Qr = await this.inner.generateQrCode(); + const innerVerifier: RustSdkCryptoJs.Qr | undefined = await this.inner.generateQrCode(); + // If we are unable to generate a QRCode, we return undefined + if (!innerVerifier) return; + return Buffer.from(innerVerifier.toBytes()); }