diff --git a/deltachat-rpc-client/tests/test_securejoin.py b/deltachat-rpc-client/tests/test_securejoin.py index 477eb16d93..eb435e6237 100644 --- a/deltachat-rpc-client/tests/test_securejoin.py +++ b/deltachat-rpc-client/tests/test_securejoin.py @@ -73,22 +73,25 @@ def test_qr_securejoin(acfactory, protect, tmp_path): qr_code = alice_chat.get_qr_code() bob.secure_join(qr_code) - # Check that at least some of the handshake messages are deleted. + # Alice deletes "vg-request". + while True: + event = ac.wait_for_event() + if event["kind"] == "ImapMessageDeleted": + break + alice.wait_for_securejoin_inviter_success() + # Bob deletes "vg-auth-required", Alice deletes "vg-request-with-auth". for ac in [alice, bob]: while True: event = ac.wait_for_event() if event["kind"] == "ImapMessageDeleted": break - - alice.wait_for_securejoin_inviter_success() + bob.wait_for_securejoin_joiner_success() # Test that Alice verified Bob's profile. alice_contact_bob = alice.get_contact_by_addr(bob.get_config("addr")) alice_contact_bob_snapshot = alice_contact_bob.get_snapshot() assert alice_contact_bob_snapshot.is_verified - bob.wait_for_securejoin_joiner_success() - snapshot = bob.get_message_by_id(bob.wait_for_incoming_msg_event().msg_id).get_snapshot() assert snapshot.text == "Member Me ({}) added by {}.".format(bob.get_config("addr"), alice.get_config("addr")) assert snapshot.chat.get_basic_snapshot().is_protected == protect diff --git a/src/headerdef.rs b/src/headerdef.rs index b4865dd716..61d7746d86 100644 --- a/src/headerdef.rs +++ b/src/headerdef.rs @@ -73,6 +73,7 @@ pub enum HeaderDef { /// [Autocrypt](https://autocrypt.org/) header. Autocrypt, + AutocryptGossip, AutocryptSetupMessage, SecureJoin, diff --git a/src/securejoin.rs b/src/securejoin.rs index 5779178f2b..fd72080281 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -454,6 +454,9 @@ pub(crate) async fn handle_securejoin_handshake( .await?; inviter_progress(context, contact_id, 800); inviter_progress(context, contact_id, 1000); + // IMAP-delete the message to avoid handling it by another device and adding the + // member twice. Another device will know the member's key from Autocrypt-Gossip. + Ok(HandshakeMessage::Done) } else { // Setup verified contact. secure_connection_established( @@ -468,8 +471,8 @@ pub(crate) async fn handle_securejoin_handshake( .context("failed sending vc-contact-confirm message")?; inviter_progress(context, contact_id, 1000); + Ok(HandshakeMessage::Ignore) // "Done" would delete the message and break multi-device (the key from Autocrypt-header is needed) } - Ok(HandshakeMessage::Ignore) // "Done" would delete the message and break multi-device (the key from Autocrypt-header is needed) } /*======================================================= ==== Bob - the joiner's side ==== @@ -1353,6 +1356,8 @@ mod tests { // explicit user action, the Auto-Submitted header shouldn't be present. Otherwise it would // be strange to have it in "member-added" messages of verified groups only. assert!(msg.get_header(HeaderDef::AutoSubmitted).is_none()); + // This is a two-member group, but Alice must Autocrypt-gossip to her other devices. + assert!(msg.get_header(HeaderDef::AutocryptGossip).is_some()); { // Now Alice's chat with Bob should still be hidden, the verified message should