@@ -3,7 +3,7 @@ use std::time::Duration;
33use deltachat_contact_tools:: EmailAddress ;
44
55use super :: * ;
6- use crate :: chat:: { CantSendReason , remove_contact_from_chat} ;
6+ use crate :: chat:: { CantSendReason , add_contact_to_chat , remove_contact_from_chat} ;
77use crate :: chatlist:: Chatlist ;
88use crate :: constants:: Chattype ;
99use crate :: key:: self_fingerprint;
@@ -1155,3 +1155,65 @@ async fn test_two_group_securejoins() -> Result<()> {
11551155
11561156 Ok ( ( ) )
11571157}
1158+
1159+ /// Tests that scanning an outdated QR code does not add the removed inviter back to the group.
1160+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 2 ) ]
1161+ async fn test_qr_no_implicit_inviter_addition ( ) -> Result < ( ) > {
1162+ let mut tcm = TestContextManager :: new ( ) ;
1163+ let alice = & tcm. alice ( ) . await ;
1164+ let bob = & tcm. bob ( ) . await ;
1165+ let charlie = & tcm. charlie ( ) . await ;
1166+
1167+ // Alice creates a group with Bob.
1168+ let alice_chat_id = alice
1169+ . create_group_with_members ( "Group with Bob" , & [ bob] )
1170+ . await ;
1171+ let alice_qr = get_securejoin_qr ( alice, Some ( alice_chat_id) ) . await ?;
1172+
1173+ // Bob joins the group via QR code.
1174+ let bob_chat_id = tcm. exec_securejoin_qr ( bob, alice, & alice_qr) . await ;
1175+
1176+ // Bob creates a QR code for joining the group.
1177+ let bob_qr = get_securejoin_qr ( bob, Some ( bob_chat_id) ) . await ?;
1178+
1179+ // Alice removes Bob from the group.
1180+ let alice_bob_contact_id = alice. add_or_lookup_contact_id ( bob) . await ;
1181+ remove_contact_from_chat ( alice, alice_chat_id, alice_bob_contact_id) . await ?;
1182+
1183+ // Deliver the removal message to Bob.
1184+ let removal_msg = alice. pop_sent_msg ( ) . await ;
1185+ bob. recv_msg ( & removal_msg) . await ;
1186+
1187+ // Charlie scans Bob's outdated QR code.
1188+ let charlie_chat_id = join_securejoin ( charlie, & bob_qr) . await ?;
1189+
1190+ // Charlie sends vg-request to Bob.
1191+ let sent = charlie. pop_sent_msg ( ) . await ;
1192+ bob. recv_msg_trash ( & sent) . await ;
1193+
1194+ // Bob sends vg-auth-required to Charlie.
1195+ let sent = bob. pop_sent_msg ( ) . await ;
1196+ charlie. recv_msg_trash ( & sent) . await ;
1197+
1198+ // Bob receives vg-request-with-auth, but cannot add Charlie
1199+ // because Bob himself is not in the group.
1200+ let sent = charlie. pop_sent_msg ( ) . await ;
1201+ bob. recv_msg_trash ( & sent) . await ;
1202+
1203+ // Charlie still has no contacts in the list.
1204+ let charlie_chat_contacts = chat:: get_chat_contacts ( charlie, charlie_chat_id) . await ?;
1205+ assert_eq ! ( charlie_chat_contacts. len( ) , 0 ) ;
1206+
1207+ // Alice adds Charlie to the group
1208+ let alice_charlie_contact_id = alice. add_or_lookup_contact_id ( charlie) . await ;
1209+ add_contact_to_chat ( alice, alice_chat_id, alice_charlie_contact_id) . await ?;
1210+
1211+ let sent = alice. pop_sent_msg ( ) . await ;
1212+ assert_eq ! ( charlie. recv_msg( & sent) . await . chat_id, charlie_chat_id) ;
1213+
1214+ // Charlie has two contacts in the list: Alice and self.
1215+ let charlie_chat_contacts = chat:: get_chat_contacts ( charlie, charlie_chat_id) . await ?;
1216+ assert_eq ! ( charlie_chat_contacts. len( ) , 2 ) ;
1217+
1218+ Ok ( ( ) )
1219+ }
0 commit comments