1
1
/*
2
- Copyright 2022 The Matrix.org Foundation C.I.C.
2
+ Copyright 2022 - 2023 The Matrix.org Foundation C.I.C.
3
3
4
4
Licensed under the Apache License, Version 2.0 (the "License");
5
5
you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@ limitations under the License.
16
16
17
17
import { mocked , MockedObject } from "jest-mock" ;
18
18
19
+ import type { DeviceInfoMap } from "../../../../src/crypto/DeviceList" ;
19
20
import "../../../olm-loader" ;
20
21
import type { OutboundGroupSession } from "@matrix-org/olm" ;
21
22
import * as algorithms from "../../../../src/crypto/algorithms" ;
@@ -33,6 +34,7 @@ import { ClientEvent, MatrixClient, RoomMember } from "../../../../src";
33
34
import { DeviceInfo , IDevice } from "../../../../src/crypto/deviceinfo" ;
34
35
import { DeviceTrustLevel } from "../../../../src/crypto/CrossSigning" ;
35
36
import { MegolmEncryption as MegolmEncryptionClass } from "../../../../src/crypto/algorithms/megolm" ;
37
+ import { sleep } from "../../../../src/utils" ;
36
38
37
39
const MegolmDecryption = algorithms . DECRYPTION_CLASSES . get ( "m.megolm.v1.aes-sha2" ) ! ;
38
40
const MegolmEncryption = algorithms . ENCRYPTION_CLASSES . get ( "m.megolm.v1.aes-sha2" ) ! ;
@@ -58,6 +60,12 @@ describe("MegolmDecryption", function () {
58
60
59
61
beforeEach ( async function ( ) {
60
62
mockCrypto = testUtils . mock ( Crypto , "Crypto" ) as MockedObject < Crypto > ;
63
+
64
+ // @ts -ignore assigning to readonly prop
65
+ mockCrypto . backupManager = {
66
+ backupGroupSession : ( ) => { } ,
67
+ } ;
68
+
61
69
mockBaseApis = {
62
70
claimOneTimeKeys : jest . fn ( ) ,
63
71
sendToDevice : jest . fn ( ) ,
@@ -314,10 +322,6 @@ describe("MegolmDecryption", function () {
314
322
let olmDevice : OlmDevice ;
315
323
316
324
beforeEach ( async ( ) => {
317
- // @ts -ignore assigning to readonly prop
318
- mockCrypto . backupManager = {
319
- backupGroupSession : ( ) => { } ,
320
- } ;
321
325
const cryptoStore = new MemoryCryptoStore ( ) ;
322
326
323
327
olmDevice = new OlmDevice ( cryptoStore ) ;
@@ -515,6 +519,76 @@ describe("MegolmDecryption", function () {
515
519
} ) ;
516
520
} ) ;
517
521
522
+ describe ( "prepareToEncrypt" , ( ) => {
523
+ let megolm : MegolmEncryptionClass ;
524
+ let room : jest . Mocked < Room > ;
525
+
526
+ const deviceMap : DeviceInfoMap = {
527
+ "user-a" : {
528
+ "device-a" : new DeviceInfo ( "device-a" ) ,
529
+ "device-b" : new DeviceInfo ( "device-b" ) ,
530
+ "device-c" : new DeviceInfo ( "device-c" ) ,
531
+ } ,
532
+ "user-b" : {
533
+ "device-d" : new DeviceInfo ( "device-d" ) ,
534
+ "device-e" : new DeviceInfo ( "device-e" ) ,
535
+ "device-f" : new DeviceInfo ( "device-f" ) ,
536
+ } ,
537
+ "user-c" : {
538
+ "device-g" : new DeviceInfo ( "device-g" ) ,
539
+ "device-h" : new DeviceInfo ( "device-h" ) ,
540
+ "device-i" : new DeviceInfo ( "device-i" ) ,
541
+ } ,
542
+ } ;
543
+
544
+ beforeEach ( ( ) => {
545
+ room = testUtils . mock ( Room , "Room" ) as jest . Mocked < Room > ;
546
+ room . getEncryptionTargetMembers . mockImplementation ( async ( ) => [
547
+ new RoomMember ( room . roomId , "@user:example.org" ) ,
548
+ ] ) ;
549
+ room . getBlacklistUnverifiedDevices . mockReturnValue ( false ) ;
550
+
551
+ mockCrypto . downloadKeys . mockImplementation ( async ( ) => deviceMap ) ;
552
+
553
+ mockCrypto . checkDeviceTrust . mockImplementation ( ( ) => new DeviceTrustLevel ( true , true , true , true ) ) ;
554
+
555
+ const olmDevice = new OlmDevice ( new MemoryCryptoStore ( ) ) ;
556
+ megolm = new MegolmEncryptionClass ( {
557
+ userId : "@user:id" ,
558
+ deviceId : "12345" ,
559
+ crypto : mockCrypto ,
560
+ olmDevice,
561
+ baseApis : mockBaseApis ,
562
+ roomId : room . roomId ,
563
+ config : {
564
+ algorithm : "m.megolm.v1.aes-sha2" ,
565
+ rotation_period_ms : 9_999_999 ,
566
+ } ,
567
+ } ) ;
568
+ } ) ;
569
+
570
+ it ( "checks each device" , async ( ) => {
571
+ megolm . prepareToEncrypt ( room ) ;
572
+ //@ts -ignore private member access, gross
573
+ await megolm . encryptionPreparation ?. promise ;
574
+
575
+ for ( const userId in deviceMap ) {
576
+ for ( const deviceId in deviceMap [ userId ] ) {
577
+ expect ( mockCrypto . checkDeviceTrust ) . toHaveBeenCalledWith ( userId , deviceId ) ;
578
+ }
579
+ }
580
+ } ) ;
581
+
582
+ it ( "defers before completing" , async ( ) => {
583
+ megolm . prepareToEncrypt ( room ) ;
584
+ // Ensure that `Crypto#checkDeviceTrust` has been called *fewer*
585
+ // than the full nine times, after yielding once.
586
+ await sleep ( 0 ) ;
587
+ const callCount = mockCrypto . checkDeviceTrust . mock . calls . length ;
588
+ expect ( callCount ) . toBeLessThan ( 9 ) ;
589
+ } ) ;
590
+ } ) ;
591
+
518
592
it ( "notifies devices that have been blocked" , async function ( ) {
519
593
const aliceClient = new TestClient ( "@alice:example.com" , "alicedevice" ) . client ;
520
594
const bobClient1 = new TestClient ( "@bob:example.com" , "bobdevice1" ) . client ;
0 commit comments