diff --git a/src/chat.rs b/src/chat.rs index a0b0f082a..ba7f42816 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2948,7 +2948,7 @@ async fn prepare_send_msg( .get_bool(Param::ForcePlaintext) .unwrap_or_default() // V2 securejoin messages are symmetrically encrypted, no need for the public key: - || msg.securejoin_step() == Some("vb-request-with-auth") + || msg.is_vb_request_with_auth() } _ => false, }; @@ -3052,6 +3052,9 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) - if (context.get_config_bool(Config::BccSelf).await? || msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage) && (context.get_config_delete_server_after().await? != Some(0) || !recipients.is_empty()) + // `vb-request-with-auth` messages are symmetrically encrypted + // with a secret which the other device doesn't have: + && !msg.is_vb_request_with_auth() { recipients.push(from); } diff --git a/src/chat/chat_tests.rs b/src/chat/chat_tests.rs index f82d55d4f..b89cc5078 100644 --- a/src/chat/chat_tests.rs +++ b/src/chat/chat_tests.rs @@ -3130,14 +3130,19 @@ async fn test_leave_broadcast_multidevice() -> Result<()> { let qr = get_securejoin_qr(alice, Some(alice_chat_id)).await.unwrap(); join_securejoin(bob0, &qr).await.unwrap(); let request = bob0.pop_sent_msg().await; + + // Bob must send the message only to Alice, not to Self, + // because otherwise, his second device would show a device message + // "⚠️ It seems you are using Delta Chat on multiple devices that cannot decrypt each other's outgoing messages. + // To fix this, on the older device use \"Settings / Add Second Device\" and follow the instructions." + assert_eq!(request.recipients, "alice@example.org"); + alice.recv_msg_trash(&request).await; let answer = alice.pop_sent_msg().await; bob0.recv_msg(&answer).await; // Sync Bob's verification of Alice: sync(bob0, bob1).await; - // TODO uncommenting the next line creates a message "Can't decrypt outgoing messages, probably you're using DC on multiple devices without transferring your key" - // bob1.recv_msg(&request).await; bob1.recv_msg(&answer).await; // The 1:1 chat should not be visible to the user on any of the devices. diff --git a/src/message.rs b/src/message.rs index 839cfab86..a9aca8aaa 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1386,15 +1386,16 @@ impl Message { self.error.clone() } - // TODO this function could be used a lot more - /// If this is a secure-join message, - /// returns the current step, - /// which is put into the `Secure-Join` header. - pub(crate) fn securejoin_step(&self) -> Option<&str> { + /// Returns `true` if this message is a `vb-request-with-auth` SecureJoin message. + pub(crate) fn is_vb_request_with_auth(&self) -> bool { if self.param.get_cmd() == SystemMessage::SecurejoinMessage { - self.param.get(Param::Arg) + // CAVE: You can't check in the same way whether the message + // is a `v{g|b}-member-added` message, + // because for these messages, + // `param.get_cmd()` returns `SystemMessage::MemberAddedToGroup`. + self.param.get(Param::Arg) == Some("vb-request-with-auth") } else { - None + false } } } diff --git a/src/mimefactory.rs b/src/mimefactory.rs index e0e0cb30d..0d4ee7af0 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1916,8 +1916,7 @@ fn hidden_recipients() -> Address<'static> { } fn should_encrypt_with_auth_token(msg: &Message) -> bool { - msg.param.get_cmd() == SystemMessage::SecurejoinMessage - && msg.param.get(Param::Arg).unwrap_or_default() == "vb-request-with-auth" + msg.is_vb_request_with_auth() } fn should_encrypt_with_broadcast_secret(msg: &Message, chat: &Chat) -> bool {