Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions deltachat-rpc-client/tests/test_securejoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,3 +704,21 @@ def test_withdraw_securejoin_qr(acfactory):
and "Ignoring RequestWithAuth message because of invalid auth code." in event.msg
):
break


def test_qr_scan_updates_new_relay_address(acfactory):
alice, bob = acfactory.get_online_accounts(2)

bob.secure_join(alice.get_qr_code())
alice.wait_for_securejoin_inviter_success()
bob.wait_for_securejoin_joiner_success()

for ac in [alice, bob]:
old_addr = ac.get_config("configured_addr")
ac.add_transport_from_qr(acfactory.get_account_qr())
ac.set_config("configured_addr", ac.list_transports()[1]["addr"])
ac.delete_transport(old_addr)

bob.secure_join(alice.get_qr_code())
alice.wait_for_securejoin_inviter_success()
bob.wait_for_securejoin_joiner_success()
4 changes: 3 additions & 1 deletion src/contact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,9 @@ impl Contact {
|| row_authname.is_empty());

row_id = id;
if origin >= row_origin && addr != row_addr {
let qr_with_fingerprint = !fingerprint.is_empty()
&& origin == Origin::UnhandledSecurejoinQrScan;
if (origin >= row_origin || qr_with_fingerprint) && addr != row_addr {
update_addr = true;
}
if update_name || update_authname || update_addr || origin > row_origin {
Expand Down
28 changes: 17 additions & 11 deletions src/mimefactory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,7 @@ impl MimeFactory {

let public_key = SignedPublicKey::from_slice(&public_key_bytes)?;

let relays =
addresses_from_public_key(&public_key).unwrap_or_else(|| vec![addr.clone()]);
recipients.extend(relays);
recipients.extend(relay_addrs(&public_key, &addr));

@link2xt link2xt Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently when the addresses are known from the public key we only send to these addresses. The idea is that it is possible to send from any address and not receive any messages there as a result, e.g. for "sealed sender".

With this change we now send not only to the addresses from the public key, but to the From address (or even the address from a random QR code that can be modified).

to.push((authname, addr.clone()));

encryption_pubkeys = Some(vec![(addr, public_key)]);
Expand Down Expand Up @@ -353,18 +351,18 @@ impl MimeFactory {
};
if add_timestamp >= remove_timestamp {
let relays = if let Some(public_key) = public_key_opt {
let addrs = addresses_from_public_key(&public_key);
let addrs = relay_addrs(&public_key, &addr);
keys.push((addr.clone(), public_key));
addrs
} else if id != ContactId::SELF && !should_encrypt_symmetrically(&msg, &chat) {
missing_key_addresses.insert(addr.clone());
if is_encrypted {
warn!(context, "Missing key for {addr}");
}
None
vec![addr.clone()]
} else {
None
}.unwrap_or_else(|| vec![addr.clone()]);
vec![addr.clone()]
};

if !recipients_contain_addr(&to, &addr) {
if id != ContactId::SELF {
Expand Down Expand Up @@ -393,18 +391,18 @@ impl MimeFactory {
if let Some(email_to_remove) = email_to_remove
&& email_to_remove == addr {
let relays = if let Some(public_key) = public_key_opt {
let addrs = addresses_from_public_key(&public_key);
let addrs = relay_addrs(&public_key, &addr);
keys.push((addr.clone(), public_key));
addrs
} else if id != ContactId::SELF && !should_encrypt_symmetrically(&msg, &chat) {
missing_key_addresses.insert(addr.clone());
if is_encrypted {
warn!(context, "Missing key for {addr}");
}
None
vec![addr.clone()]
} else {
None
}.unwrap_or_else(|| vec![addr.clone()]);
vec![addr.clone()]
};

// This is a "member removed" message,
// we need to notify removed member
Expand Down Expand Up @@ -2203,6 +2201,14 @@ async fn build_avatar_file(context: &Context, path: &str) -> Result<String> {
Ok(encoded_body)
}

fn relay_addrs(public_key: &SignedPublicKey, addr: &str) -> Vec<String> {
let mut addrs = addresses_from_public_key(public_key).unwrap_or_default();
if !addrs.iter().any(|r| r == addr) {
addrs.push(addr.to_string());
}
addrs
}

fn recipients_contain_addr(recipients: &[(String, String)], addr: &str) -> bool {
let addr_lc = addr.to_lowercase();
recipients
Expand Down