@@ -2333,8 +2333,82 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
23332333 } ) ;
23342334
23352335 describe ( "m.room_key.withheld handling" , ( ) => {
2336- // TODO: there are a bunch more tests for this sort of thing in spec/unit/crypto/algorithms/megolm.spec.ts.
2337- // They should be converted to integ tests and moved.
2336+ describe . each ( [
2337+ [ "m.blacklisted" , "The sender has blocked you." , DecryptionFailureCode . MEGOLM_KEY_WITHHELD ] ,
2338+ [
2339+ "m.unverified" ,
2340+ "The sender has disabled encrypting to unverified devices." ,
2341+ DecryptionFailureCode . MEGOLM_KEY_WITHHELD_FOR_UNVERIFIED_DEVICE ,
2342+ ] ,
2343+ ] ) (
2344+ "Decryption fails with withheld error if a withheld notice with code '%s' is received" ,
2345+ ( withheldCode , expectedMessage , expectedErrorCode ) => {
2346+ // TODO: test arrival after the event too.
2347+ it . each ( [ "before" ] ) ( "%s the event" , async ( when ) => {
2348+ expectAliceKeyQuery ( { device_keys : { "@alice:localhost" : { } } , failures : { } } ) ;
2349+ await startClientAndAwaitFirstSync ( ) ;
2350+
2351+ // A promise which resolves, with the MatrixEvent which wraps the event, once the decryption fails.
2352+ const awaitDecryption = emitPromise ( aliceClient , MatrixEventEvent . Decrypted ) ;
2353+
2354+ // Send Alice an encrypted room event which looks like it was encrypted with a megolm session
2355+ async function sendEncryptedEvent ( ) {
2356+ const event = {
2357+ ...testData . ENCRYPTED_EVENT ,
2358+ origin_server_ts : Date . now ( ) ,
2359+ } ;
2360+ const syncResponse = {
2361+ next_batch : 1 ,
2362+ rooms : { join : { [ ROOM_ID ] : { timeline : { events : [ event ] } } } } ,
2363+ } ;
2364+
2365+ syncResponder . sendOrQueueSyncResponse ( syncResponse ) ;
2366+ await syncPromise ( aliceClient ) ;
2367+ }
2368+
2369+ // Send Alice a withheld notice
2370+ async function sendWithheldMessage ( ) {
2371+ const withheldMessage = {
2372+ type : "m.room_key.withheld" ,
2373+ sender : "@bob:example.com" ,
2374+ content : {
2375+ algorithm : "m.megolm.v1.aes-sha2" ,
2376+ room_id : ROOM_ID ,
2377+ sender_key : testData . ENCRYPTED_EVENT . content ! . sender_key ,
2378+ session_id : testData . ENCRYPTED_EVENT . content ! . session_id ,
2379+ code : withheldCode ,
2380+ reason : "zzz" ,
2381+ } ,
2382+ } ;
2383+
2384+ syncResponder . sendOrQueueSyncResponse ( {
2385+ next_batch : 1 ,
2386+ to_device : { events : [ withheldMessage ] } ,
2387+ } ) ;
2388+ await syncPromise ( aliceClient ) ;
2389+ }
2390+
2391+ if ( when === "before" ) {
2392+ await sendWithheldMessage ( ) ;
2393+ await sendEncryptedEvent ( ) ;
2394+ } else {
2395+ await sendEncryptedEvent ( ) ;
2396+ await sendWithheldMessage ( ) ;
2397+ }
2398+
2399+ const ev = await awaitDecryption ;
2400+ expect ( ev . getContent ( ) ) . toEqual ( {
2401+ body : `** Unable to decrypt: DecryptionError: ${ expectedMessage } **` ,
2402+ msgtype : "m.bad.encrypted" ,
2403+ } ) ;
2404+
2405+ expect ( ev . decryptionFailureReason ) . toEqual ( expectedErrorCode ) ;
2406+
2407+ // `isEncryptedDisabledForUnverifiedDevices` should be true for `m.unverified` and false for other errors.
2408+ expect ( ev . isEncryptedDisabledForUnverifiedDevices ) . toEqual ( withheldCode === "m.unverified" ) ;
2409+ } ) ;
2410+ } ,
2411+ ) ;
23382412
23392413 oldBackendOnly ( "does not block decryption on an 'm.unavailable' report" , async function ( ) {
23402414 // there may be a key downloads for alice
0 commit comments