@@ -5,10 +5,11 @@ use assert_matches::assert_matches;
55use assert_matches2:: assert_let;
66use assign:: assign;
77use matrix_sdk:: {
8+ assert_next_eq_with_timeout,
89 crypto:: { format_emojis, SasState } ,
910 encryption:: {
1011 backups:: BackupState ,
11- recovery:: RecoveryState ,
12+ recovery:: { Recovery , RecoveryState } ,
1213 verification:: {
1314 QrVerificationData , QrVerificationState , Verification , VerificationRequestState ,
1415 } ,
@@ -22,13 +23,15 @@ use matrix_sdk::{
2223 MessageType , OriginalSyncRoomMessageEvent , RoomMessageEventContent ,
2324 SyncRoomMessageEvent ,
2425 } ,
25- OriginalSyncMessageLikeEvent ,
26+ secret_storage:: { key:: SecretStorageKeyEventContent , secret:: SecretEventContent } ,
27+ EventContentFromType , GlobalAccountDataEventType , OriginalSyncMessageLikeEvent ,
2628 } ,
2729 } ,
2830 Client ,
2931} ;
32+ use serde_json:: value:: to_raw_value;
3033use similar_asserts:: assert_eq;
31- use tracing:: warn;
34+ use tracing:: { debug , warn} ;
3235
3336use crate :: helpers:: { SyncTokenAwareClient , TestClientBuilder } ;
3437
@@ -974,3 +977,107 @@ async fn test_secret_gossip_after_interactive_verification() -> Result<()> {
974977
975978 Ok ( ( ) )
976979}
980+
981+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 4 ) ]
982+ async fn test_recovery_disabling_deletes_secret_storage_secrets ( ) -> Result < ( ) > {
983+ let encryption_settings = EncryptionSettings {
984+ auto_enable_cross_signing : true ,
985+ auto_enable_backups : true ,
986+ ..Default :: default ( )
987+ } ;
988+ let client = SyncTokenAwareClient :: new (
989+ TestClientBuilder :: new ( "alice_recovery_deletion_test" )
990+ . encryption_settings ( encryption_settings)
991+ . build ( )
992+ . await ?,
993+ ) ;
994+
995+ debug ! ( "Enabling recovery" ) ;
996+
997+ client. encryption ( ) . wait_for_e2ee_initialization_tasks ( ) . await ;
998+ client. encryption ( ) . recovery ( ) . enable ( ) . await ?;
999+
1000+ // Let's wait for recovery to become enabled.
1001+ let mut recovery_state = client. encryption ( ) . recovery ( ) . state_stream ( ) ;
1002+
1003+ debug ! ( "Checking that recovery has been enabled" ) ;
1004+
1005+ assert_next_eq_with_timeout ! (
1006+ recovery_state,
1007+ RecoveryState :: Enabled ,
1008+ "Recovery should have been enabled"
1009+ ) ;
1010+
1011+ debug ! ( "Checking that the secrets have been stored on the server" ) ;
1012+
1013+ let default_event = client
1014+ . encryption ( )
1015+ . secret_storage ( )
1016+ . fetch_default_key_id ( )
1017+ . await ?
1018+ . expect ( "The default key event should have been uploaded to the server" )
1019+ . deserialize ( )
1020+ . expect ( "We should be able to deserialize the default event content" ) ;
1021+
1022+ let key_id = default_event. key_id ;
1023+
1024+ for event_type in Recovery :: KNOWN_SECRETS {
1025+ let event_type = GlobalAccountDataEventType :: from ( event_type. clone ( ) ) ;
1026+ let event = client
1027+ . account ( )
1028+ . fetch_account_data ( event_type. clone ( ) )
1029+ . await ?
1030+ . expect ( "The secret event should still exist" ) ;
1031+
1032+ let event = event
1033+ . deserialize_as :: < SecretEventContent > ( )
1034+ . expect ( "We should be able to deserialize the content of known secrets" ) ;
1035+
1036+ assert ! (
1037+ !event. encrypted. is_empty( ) ,
1038+ "The known secret {event_type} should exist on the server"
1039+ ) ;
1040+ }
1041+
1042+ debug ! ( "Disabling recovery" ) ;
1043+
1044+ client. encryption ( ) . recovery ( ) . disable ( ) . await ?;
1045+
1046+ debug ! ( "Checking that the secrets have been removed from the server" ) ;
1047+
1048+ for event_type in Recovery :: KNOWN_SECRETS {
1049+ let event_type = GlobalAccountDataEventType :: from ( event_type. clone ( ) ) ;
1050+ let event = client
1051+ . account ( )
1052+ . fetch_account_data ( event_type. clone ( ) )
1053+ . await ?
1054+ . expect ( "The secret event should still exist" ) ;
1055+
1056+ let event = event
1057+ . deserialize_as :: < SecretEventContent > ( )
1058+ . expect ( "We should be able to deserialize the content since that's what we uploaded" ) ;
1059+
1060+ assert ! (
1061+ event. encrypted. is_empty( ) ,
1062+ "The known secret {event_type} should have been deleted from the server"
1063+ ) ;
1064+ }
1065+
1066+ debug ! ( "Checking that the info about the default key has been deleted" ) ;
1067+ let event_type = GlobalAccountDataEventType :: SecretStorageKey ( key_id) ;
1068+ let content = client
1069+ . account ( )
1070+ . fetch_account_data ( event_type. clone ( ) )
1071+ . await ?
1072+ . expect ( "The key event should be available on the server" ) ;
1073+
1074+ SecretStorageKeyEventContent :: from_parts (
1075+ & event_type. to_string ( ) ,
1076+ & to_raw_value ( & content) . unwrap ( ) ,
1077+ )
1078+ . expect_err (
1079+ "The key event should have been “deleted” so we shouldn't be able to deserialize it" ,
1080+ ) ;
1081+
1082+ Ok ( ( ) )
1083+ }
0 commit comments