@@ -19,7 +19,7 @@ import anotherjson from "another-json";
19
19
import fetchMock from "fetch-mock-jest" ;
20
20
import "fake-indexeddb/auto" ;
21
21
import { IDBFactory } from "fake-indexeddb" ;
22
- import { MockResponse } from "fetch-mock" ;
22
+ import { MockResponse , MockResponseFunction } from "fetch-mock" ;
23
23
24
24
import type { IDeviceKeys } from "../../src/@types/crypto" ;
25
25
import * as testUtils from "../test-utils/test-utils" ;
@@ -47,6 +47,7 @@ import {
47
47
import { DeviceInfo } from "../../src/crypto/deviceinfo" ;
48
48
import { E2EKeyReceiver , IE2EKeyReceiver } from "../test-utils/E2EKeyReceiver" ;
49
49
import { ISyncResponder , SyncResponder } from "../test-utils/SyncResponder" ;
50
+ import { escapeRegExp } from "../../src/utils" ;
50
51
51
52
const ROOM_ID = "!room:id" ;
52
53
@@ -438,8 +439,9 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
438
439
} ) ;
439
440
return response ;
440
441
}
442
+ const rootRegexp = escapeRegExp ( new URL ( "/_matrix/client/" , aliceClient . getHomeserverUrl ( ) ) . toString ( ) ) ;
441
443
fetchMock . postOnce (
442
- new URL ( "/_matrix/client/r0 /keys/query", aliceClient . getHomeserverUrl ( ) ) . toString ( ) ,
444
+ new RegExp ( rootRegexp + "(r0|v3) /keys/query") ,
443
445
( url : string , opts : RequestInit ) => onQueryRequest ( JSON . parse ( opts . body as string ) ) ,
444
446
{
445
447
// append to the list of intercepts on this path
@@ -448,6 +450,17 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
448
450
) ;
449
451
}
450
452
453
+ /**
454
+ * Add an expectation for a /keys/claim request for the MatrixClient under test
455
+ *
456
+ * @param response - the response to return from the request. Normally an {@link IClaimOTKsResult}
457
+ * (or a function that returns one).
458
+ */
459
+ function expectAliceKeyClaim ( response : MockResponse | MockResponseFunction ) {
460
+ const rootRegexp = escapeRegExp ( new URL ( "/_matrix/client/" , aliceClient . getHomeserverUrl ( ) ) . toString ( ) ) ;
461
+ fetchMock . postOnce ( new RegExp ( rootRegexp + "(r0|v3)/keys/claim" ) , response ) ;
462
+ }
463
+
451
464
/**
452
465
* Get the device keys for testOlmAccount in a format suitable for a
453
466
* response to /keys/query
@@ -755,10 +768,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
755
768
expectAliceKeyQuery ( getTestKeysQueryResponse ( "@bob:xyz" ) ) ;
756
769
757
770
// ... and then claim one of his OTKs
758
- fetchMock . postOnce (
759
- new URL ( "/_matrix/client/r0/keys/claim" , aliceClient . getHomeserverUrl ( ) ) . toString ( ) ,
760
- getTestKeysClaimResponse ( "@bob:xyz" ) ,
761
- ) ;
771
+ expectAliceKeyClaim ( getTestKeysClaimResponse ( "@bob:xyz" ) ) ;
762
772
763
773
// fire off the prepare request
764
774
const room = aliceClient . getRoom ( ROOM_ID ) ;
@@ -772,7 +782,37 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
772
782
await p ;
773
783
} ) ;
774
784
785
+ it ( "Alice sends a megolm message with GlobalErrorOnUnknownDevices=false" , async ( ) => {
786
+ aliceClient . setGlobalErrorOnUnknownDevices ( false ) ;
787
+ expectAliceKeyQuery ( { device_keys : { "@alice:localhost" : { } } , failures : { } } ) ;
788
+ await startClientAndAwaitFirstSync ( ) ;
789
+
790
+ // Alice shares a room with Bob
791
+ syncResponder . sendOrQueueSyncResponse ( getSyncResponse ( [ "@bob:xyz" ] ) ) ;
792
+ await syncPromise ( aliceClient ) ;
793
+
794
+ // Once we send the message, Alice will check Bob's device list (twice, because reasons) ...
795
+ expectAliceKeyQuery ( getTestKeysQueryResponse ( "@bob:xyz" ) ) ;
796
+ expectAliceKeyQuery ( getTestKeysQueryResponse ( "@bob:xyz" ) ) ;
797
+
798
+ // ... and claim one of his OTKs ...
799
+ expectAliceKeyClaim ( getTestKeysClaimResponse ( "@bob:xyz" ) ) ;
800
+
801
+ // ... and send an m.room_key message
802
+ const inboundGroupSessionPromise = expectSendRoomKey ( "@bob:xyz" , testOlmAccount ) ;
803
+
804
+ // Finally, send the message, and expect to get an `m.room.encrypted` event that we can decrypt.
805
+ await Promise . all ( [
806
+ aliceClient . sendTextMessage ( ROOM_ID , "test" ) ,
807
+ expectSendMegolmMessage ( inboundGroupSessionPromise ) ,
808
+ ] ) ;
809
+ } ) ;
810
+
775
811
oldBackendOnly ( "Alice sends a megolm message" , async ( ) => {
812
+ // TODO: do something about this for the rust backend.
813
+ // Currently it fails because we don't respect the default GlobalErrorOnUnknownDevices and
814
+ // send messages to unknown devices.
815
+
776
816
expectAliceKeyQuery ( { device_keys : { "@alice:localhost" : { } } , failures : { } } ) ;
777
817
await startClientAndAwaitFirstSync ( ) ;
778
818
const p2pSession = await establishOlmSession ( aliceClient , keyReceiver , syncResponder , testOlmAccount ) ;
@@ -1037,14 +1077,11 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
1037
1077
1038
1078
// mark the device as known, and resend.
1039
1079
aliceClient . setDeviceKnown ( aliceClient . getUserId ( ) ! , "DEVICE_ID" ) ;
1040
- fetchMock . postOnce (
1041
- new URL ( "/_matrix/client/r0/keys/claim" , aliceClient . getHomeserverUrl ( ) ) . toString ( ) ,
1042
- ( url : string , opts : RequestInit ) : MockResponse => {
1043
- const content = JSON . parse ( opts . body as string ) ;
1044
- expect ( content . one_time_keys [ aliceClient . getUserId ( ) ! ] . DEVICE_ID ) . toEqual ( "signed_curve25519" ) ;
1045
- return getTestKeysClaimResponse ( aliceClient . getUserId ( ) ! ) ;
1046
- } ,
1047
- ) ;
1080
+ expectAliceKeyClaim ( ( url : string , opts : RequestInit ) : MockResponse => {
1081
+ const content = JSON . parse ( opts . body as string ) ;
1082
+ expect ( content . one_time_keys [ aliceClient . getUserId ( ) ! ] . DEVICE_ID ) . toEqual ( "signed_curve25519" ) ;
1083
+ return getTestKeysClaimResponse ( aliceClient . getUserId ( ) ! ) ;
1084
+ } ) ;
1048
1085
1049
1086
const inboundGroupSessionPromise = expectSendRoomKey ( aliceClient . getUserId ( ) ! , testOlmAccount ) ;
1050
1087
0 commit comments