From e456be4e21ab7ebb328d78a27dc814aa7c840459 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Sat, 10 Jan 2026 19:46:08 -0300 Subject: [PATCH] fix: Send bcc-self messages to all own relays (#7656) This fixes the bug when a new transport doesn't become primary on the 2nd device because INBOX from the new transport isn't fully fetched. Now the `Transports` sync message is received from the old transport, but as it has updated "From", it updates the primary transport correspondingly. NB: I/O for the new primary transport isn't immediately started however, this needs a separate fix. --- .../tests/test_multitransport.py | 23 +++++++++++++++++++ src/chat.rs | 8 +++++++ src/config.rs | 2 +- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/deltachat-rpc-client/tests/test_multitransport.py b/deltachat-rpc-client/tests/test_multitransport.py index 47f951824..bd7875c87 100644 --- a/deltachat-rpc-client/tests/test_multitransport.py +++ b/deltachat-rpc-client/tests/test_multitransport.py @@ -207,6 +207,29 @@ def test_transport_synchronization(acfactory, log) -> None: assert ac1_clone.wait_for_incoming_msg().get_snapshot().text == "Hello!" +def test_transport_sync_new_as_primary(acfactory, log) -> None: + """Test synchronization of new transport as primary between devices.""" + ac1 = acfactory.get_online_account() + ac1_clone = ac1.clone() + ac1_clone.bring_online() + + qr = acfactory.get_account_qr() + + ac1.add_transport_from_qr(qr) + ac1_transports = ac1.list_transports() + assert len(ac1_transports) == 2 + [transport1, transport2] = ac1_transports + ac1_clone.wait_for_event(EventType.TRANSPORTS_MODIFIED) + assert len(ac1_clone.list_transports()) == 2 + assert ac1_clone.get_config("configured_addr") == transport1["addr"] + + log.section("ac1 changes the primary transport") + ac1.set_config("configured_addr", transport2["addr"]) + + ac1_clone.wait_for_event(EventType.TRANSPORTS_MODIFIED) + assert ac1_clone.get_config("configured_addr") == transport2["addr"] + + def test_recognize_self_address(acfactory) -> None: alice, bob = acfactory.get_online_accounts(2) diff --git a/src/chat.rs b/src/chat.rs index 0b6444a16..418bf5f5d 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2855,6 +2855,14 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) - || msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage) && (context.get_config_delete_server_after().await? != Some(0) || !recipients.is_empty()) { + // Avoid sending unencrypted messages to all transports, chatmail relays won't accept + // them. Normally the user should have a non-chatmail primary transport to send unencrypted + // messages. + if needs_encryption { + for addr in context.get_secondary_self_addrs().await? { + recipients.push(addr); + } + } recipients.push(from); } diff --git a/src/config.rs b/src/config.rs index 3e374d502..8c41445bc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -967,7 +967,7 @@ impl Context { Ok(()) } - /// Returns all primary and secondary self addresses. + /// Returns the primary self address followed by all secondary ones. pub(crate) async fn get_all_self_addrs(&self) -> Result> { let primary_addrs = self.get_config(Config::ConfiguredAddr).await?.into_iter(); let secondary_addrs = self.get_secondary_self_addrs().await?.into_iter();