@@ -1486,7 +1486,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
1486
1486
this . logger . debug (
1487
1487
`Got update for session ${ key . senderKey . toBase64 ( ) } |${ key . sessionId } in ${ key . roomId . toString ( ) } ` ,
1488
1488
) ;
1489
- const pendingList = this . eventDecryptor . getEventsPendingRoomKey ( key ) ;
1489
+ const pendingList = this . eventDecryptor . getEventsPendingRoomKey ( key . roomId . toString ( ) , key . sessionId ) ;
1490
1490
if ( pendingList . length === 0 ) return ;
1491
1491
1492
1492
this . logger . debug (
@@ -1507,6 +1507,37 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
1507
1507
}
1508
1508
}
1509
1509
1510
+ /**
1511
+ * Callback for `OlmMachine.registerRoomKeyWithheldCallback`.
1512
+ *
1513
+ * Called by the rust sdk whenever we are told that a key has been withheld. We see if we had any events that
1514
+ * failed to decrypt for the given session, and update their status if so.
1515
+ *
1516
+ * @param withheld - Details of the withheld sessions.
1517
+ */
1518
+ public async onRoomKeysWithheld ( withheld : RustSdkCryptoJs . RoomKeyWithheldInfo [ ] ) : Promise < void > {
1519
+ for ( const session of withheld ) {
1520
+ this . logger . debug ( `Got withheld message for session ${ session . sessionId } in ${ session . roomId . toString ( ) } ` ) ;
1521
+ const pendingList = this . eventDecryptor . getEventsPendingRoomKey (
1522
+ session . roomId . toString ( ) ,
1523
+ session . sessionId ,
1524
+ ) ;
1525
+ if ( pendingList . length === 0 ) return ;
1526
+
1527
+ // The easiest way to update the status of the event is to have another go at decrypting it.
1528
+ this . logger . debug (
1529
+ "Retrying decryption on events:" ,
1530
+ pendingList . map ( ( e ) => `${ e . getId ( ) } ` ) ,
1531
+ ) ;
1532
+
1533
+ for ( const ev of pendingList ) {
1534
+ ev . attemptDecryption ( this , { isRetry : true } ) . catch ( ( _e ) => {
1535
+ // It's somewhat expected that we still can't decrypt here.
1536
+ } ) ;
1537
+ }
1538
+ }
1539
+ }
1540
+
1510
1541
/**
1511
1542
* Callback for `OlmMachine.registerUserIdentityUpdatedCallback`
1512
1543
*
@@ -1683,7 +1714,7 @@ class EventDecryptor {
1683
1714
/**
1684
1715
* Events which we couldn't decrypt due to unknown sessions / indexes.
1685
1716
*
1686
- * Map from senderKey to sessionId to Set of MatrixEvents
1717
+ * Map from roomId to sessionId to Set of MatrixEvents
1687
1718
*/
1688
1719
private eventsPendingKey = new MapWithDefault < string , MapWithDefault < string , Set < MatrixEvent > > > (
1689
1720
( ) => new MapWithDefault < string , Set < MatrixEvent > > ( ( ) => new Set ( ) ) ,
@@ -1843,54 +1874,50 @@ class EventDecryptor {
1843
1874
* Look for events which are waiting for a given megolm session
1844
1875
*
1845
1876
* Returns a list of events which were encrypted by `session` and could not be decrypted
1846
- *
1847
- * @param session -
1848
1877
*/
1849
- public getEventsPendingRoomKey ( session : RustSdkCryptoJs . RoomKeyInfo ) : MatrixEvent [ ] {
1850
- const senderPendingEvents = this . eventsPendingKey . get ( session . senderKey . toBase64 ( ) ) ;
1851
- if ( ! senderPendingEvents ) return [ ] ;
1878
+ public getEventsPendingRoomKey ( roomId : string , sessionId : string ) : MatrixEvent [ ] {
1879
+ const roomPendingEvents = this . eventsPendingKey . get ( roomId ) ;
1880
+ if ( ! roomPendingEvents ) return [ ] ;
1852
1881
1853
- const sessionPendingEvents = senderPendingEvents . get ( session . sessionId ) ;
1882
+ const sessionPendingEvents = roomPendingEvents . get ( sessionId ) ;
1854
1883
if ( ! sessionPendingEvents ) return [ ] ;
1855
1884
1856
- const roomId = session . roomId . toString ( ) ;
1857
- return [ ...sessionPendingEvents ] . filter ( ( ev ) => ev . getRoomId ( ) === roomId ) ;
1885
+ return [ ...sessionPendingEvents ] ;
1858
1886
}
1859
1887
1860
1888
/**
1861
1889
* Add an event to the list of those awaiting their session keys.
1862
1890
*/
1863
1891
private addEventToPendingList ( event : MatrixEvent ) : void {
1864
- const content = event . getWireContent ( ) ;
1865
- const senderKey = content . sender_key ;
1866
- const sessionId = content . session_id ;
1892
+ const roomId = event . getRoomId ( ) ;
1893
+ // We shouldn't have events without a room id here.
1894
+ if ( ! roomId ) return ;
1867
1895
1868
- const senderPendingEvents = this . eventsPendingKey . getOrCreate ( senderKey ) ;
1869
- const sessionPendingEvents = senderPendingEvents . getOrCreate ( sessionId ) ;
1896
+ const roomPendingEvents = this . eventsPendingKey . getOrCreate ( roomId ) ;
1897
+ const sessionPendingEvents = roomPendingEvents . getOrCreate ( event . getWireContent ( ) . session_id ) ;
1870
1898
sessionPendingEvents . add ( event ) ;
1871
1899
}
1872
1900
1873
1901
/**
1874
1902
* Remove an event from the list of those awaiting their session keys.
1875
1903
*/
1876
1904
private removeEventFromPendingList ( event : MatrixEvent ) : void {
1877
- const content = event . getWireContent ( ) ;
1878
- const senderKey = content . sender_key ;
1879
- const sessionId = content . session_id ;
1905
+ const roomId = event . getRoomId ( ) ;
1906
+ if ( ! roomId ) return ;
1880
1907
1881
- const senderPendingEvents = this . eventsPendingKey . get ( senderKey ) ;
1882
- if ( ! senderPendingEvents ) return ;
1908
+ const roomPendingEvents = this . eventsPendingKey . getOrCreate ( roomId ) ;
1909
+ if ( ! roomPendingEvents ) return ;
1883
1910
1884
- const sessionPendingEvents = senderPendingEvents . get ( sessionId ) ;
1911
+ const sessionPendingEvents = roomPendingEvents . get ( event . getWireContent ( ) . session_id ) ;
1885
1912
if ( ! sessionPendingEvents ) return ;
1886
1913
1887
1914
sessionPendingEvents . delete ( event ) ;
1888
1915
1889
1916
// also clean up the higher-level maps if they are now empty
1890
1917
if ( sessionPendingEvents . size === 0 ) {
1891
- senderPendingEvents . delete ( sessionId ) ;
1892
- if ( senderPendingEvents . size === 0 ) {
1893
- this . eventsPendingKey . delete ( senderKey ) ;
1918
+ roomPendingEvents . delete ( event . getWireContent ( ) . session_id ) ;
1919
+ if ( roomPendingEvents . size === 0 ) {
1920
+ this . eventsPendingKey . delete ( roomId ) ;
1894
1921
}
1895
1922
}
1896
1923
}
0 commit comments