From d87f7d8687e36148a735a57d5d55ef2cac5ee0f7 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Wed, 2 Aug 2023 17:06:59 -0400 Subject: [PATCH] Add crypto test for to-device messages --- test/MatrixClientTest.ts | 3 +- test/encryption/CryptoClientTest.ts | 67 ++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/test/MatrixClientTest.ts b/test/MatrixClientTest.ts index 21bee16e..e1764e09 100644 --- a/test/MatrixClientTest.ts +++ b/test/MatrixClientTest.ts @@ -1400,8 +1400,7 @@ describe('MatrixClient', () => { describe('processSync', () => { interface ProcessSyncClient { userId: string; - - processSync(raw: any): Promise; + processSync(raw: any): MatrixClient["processSync"]; } it('should process non-room account data', async () => { diff --git a/test/encryption/CryptoClientTest.ts b/test/encryption/CryptoClientTest.ts index bab445f6..f472d57d 100644 --- a/test/encryption/CryptoClientTest.ts +++ b/test/encryption/CryptoClientTest.ts @@ -1,7 +1,7 @@ import * as simple from "simple-mock"; import HttpBackend from 'matrix-mock-request'; -import { EncryptedFile, MatrixClient, MembershipEvent, OTKAlgorithm, RoomEncryptionAlgorithm } from "../../src"; +import { EncryptedFile, EncryptionAlgorithm, IOlmEncrypted, IToDeviceMessage, MatrixClient, MembershipEvent, OTKAlgorithm, RoomEncryptionAlgorithm } from "../../src"; import { createTestClient, testCryptoStores, TEST_DEVICE_ID } from "../TestUtils"; export function bindNullEngine(http: HttpBackend) { @@ -85,6 +85,71 @@ describe('CryptoClient', () => { })); }); + describe('processSync', () => { + /** + * Helper class to be able to call {@link MatrixClient#processSync}, which is otherwise private. + */ + interface ProcessSyncClient { + processSync: MatrixClient["processSync"]; + } + + it('should process encrypted to-device messages', () => testCryptoStores(async (cryptoStoreType) => { + const userId = "@alice:example.org"; + const { client, http } = createTestClient(null, userId, cryptoStoreType); + const psClient = (client); + + await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); + + const toDeviceMessage: IToDeviceMessage = { + type: "m.room.encrypted", + sender: userId, + content: { + algorithm: EncryptionAlgorithm.OlmV1Curve25519AesSha2, + sender_key: "sender_curve25519_key", + ciphertext: { + ["device_curve25519_key"]: { + type: 0, + body: "encrypted_payload_base_64", + }, + }, + }, + }; + const sync = { + to_device: { events: [toDeviceMessage] }, + device_unused_fallback_key_types: [OTKAlgorithm.Signed], + device_one_time_keys_count: { + [OTKAlgorithm.Signed]: 12, + [OTKAlgorithm.Unsigned]: 14, + }, + device_lists: { + changed: ["@bob:example.org"], + left: ["@charlie:example.org"], + }, + }; + + const toDeviceSpy = simple.stub().callFn((ev) => { + for (const prop in toDeviceMessage) { + expect(ev).toHaveProperty(prop); + } + }); + client.on("to_device.decrypted", toDeviceSpy); + + bindNullEngine(http); + await Promise.all([ + client.crypto.prepare([]), + http.flushAllExpected(), + ]); + + bindNullEngine(http); + await Promise.all([ + psClient.processSync(sync), + http.flushAllExpected(), + ]); + + expect(toDeviceSpy.callCount).toBe(1); + })); + }); + describe('isRoomEncrypted', () => { it('should fail when the crypto has not been prepared', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org";