fix: make keycontacts more generally discoverable, both when they send a message to us, and when they add other key contacts. Also add a discoverability test because we don't seem an explicit one. Some LLM was initially used for navigating/finding places, and drafting the test; every line is hand-edited/manually reviewed.

This commit is contained in:
holger krekel
2026-04-08 01:35:51 +02:00
parent 60bc4011f7
commit aec4c111c4
3 changed files with 59 additions and 9 deletions

View File

@@ -5056,9 +5056,10 @@ async fn set_contacts_by_fingerprints(
);
let mut contacts = BTreeSet::new();
for (fingerprint, addr) in fingerprint_addrs {
let contact = Contact::add_or_lookup_ex(context, "", addr, fingerprint, Origin::Hidden)
.await?
.0;
let contact =
Contact::add_or_lookup_ex(context, "", addr, fingerprint, Origin::IncomingReplyTo)
.await?
.0;
contacts.insert(contact);
}
let contacts_old = BTreeSet::<ContactId>::from_iter(get_chat_contacts(context, id).await?);

View File

@@ -264,7 +264,7 @@ async fn get_to_and_past_contact_ids(
&mime_parser.recipients,
&mime_parser.gossiped_keys,
to_member_fingerprints,
Origin::Hidden,
Origin::IncomingReplyTo,
)
.await?;
@@ -282,7 +282,7 @@ async fn get_to_and_past_contact_ids(
&mime_parser.past_members,
&mime_parser.gossiped_keys,
past_member_fingerprints,
Origin::Hidden,
Origin::IncomingReplyTo,
)
.await?;
}
@@ -299,7 +299,7 @@ async fn get_to_and_past_contact_ids(
&mime_parser.recipients,
&mime_parser.gossiped_keys,
to_member_fingerprints,
Origin::Hidden,
Origin::IncomingReplyTo,
)
.await?;
past_ids = lookup_key_contacts_fallback_to_chat(
@@ -361,7 +361,7 @@ async fn get_to_and_past_contact_ids(
&mime_parser.recipients,
&mime_parser.gossiped_keys,
to_member_fingerprints,
Origin::Hidden,
Origin::IncomingReplyTo,
)
.await?;
if pgp_to_ids
@@ -392,7 +392,7 @@ async fn get_to_and_past_contact_ids(
&mime_parser.recipients,
&mime_parser.gossiped_keys,
&recipient_fps,
Origin::Hidden,
Origin::IncomingReplyTo,
)
.await?
}
@@ -651,6 +651,16 @@ pub(crate) async fn receive_imf_inner(
)
.await?;
// If an incoming message is authenticated and encrypted,
// mark the sender as discoverable.
if mime_parser.incoming
&& mime_parser.signature.is_some()
&& !from_id.is_special()
&& get_secure_join_step(&mime_parser).is_none()
{
ContactId::scaleup_origin(context, &[from_id], Origin::IncomingReplyTo).await?;
}
let received_msg;
if let Some(_step) = get_secure_join_step(&mime_parser) {
let res = if mime_parser.incoming {

View File

@@ -3363,6 +3363,9 @@ async fn test_thunderbird_autocrypt() -> Result<()> {
let from_contact = Contact::get_by_id(&t, from_id).await?;
assert!(from_contact.is_key_contact());
let looked_up =
Contact::lookup_id_by_addr(&t, from_contact.get_addr(), Origin::IncomingReplyTo).await?;
assert_eq!(looked_up, Some(from_id));
Ok(())
}
@@ -3854,6 +3857,42 @@ async fn test_sync_member_list_on_rejoin() -> Result<()> {
Ok(())
}
/// When a 3rd party adds someone to an encrypted group,
/// the new member's key-contact should be discoverable
/// in search results and the contact list.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_encrypted_group_members_are_discoverable() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
alice.set_config(Config::Displayname, Some("Alice")).await?;
let alice_chat_id = alice.create_group_with_members("Grp", &[bob, fiona]).await;
let sent = alice.send_text(alice_chat_id, "hi").await;
bob.recv_msg(&sent).await;
let found_alice_by_name = Contact::get_all(bob, 0, Some("alice")).await?;
assert_eq!(found_alice_by_name.len(), 1);
let found_alice_by_addr = Contact::get_all(bob, 0, Some("alice@example.org")).await?;
assert_eq!(found_alice_by_addr.len(), 1);
assert_eq!(found_alice_by_name[0], found_alice_by_addr[0]);
// Gossip headers don't carry display names,
// so name search won't find Fiona.
let found = Contact::get_all(bob, 0, Some("fiona")).await?;
assert_eq!(found.len(), 0);
let found = Contact::get_all(bob, 0, Some("fiona@example.net")).await?;
assert_eq!(found.len(), 1);
let all = Contact::get_all(bob, 0, None).await?;
assert!(all.contains(&found[0]));
assert_eq!(all.len(), 2);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_group_contacts_goto_bottom() -> Result<()> {
let mut tcm = TestContextManager::new();
@@ -3872,7 +3911,7 @@ async fn test_group_contacts_goto_bottom() -> Result<()> {
bob.recv_msg(&alice.pop_sent_msg().await).await;
let bob_chat_id = bob.get_last_msg().await.chat_id;
assert_eq!(get_chat_contacts(bob, bob_chat_id).await?.len(), 3);
assert_eq!(Contact::get_all(bob, 0, None).await?.len(), 0);
assert_eq!(Contact::get_all(bob, 0, None).await?.len(), 2);
bob_chat_id.accept(bob).await?;
let contacts = Contact::get_all(bob, 0, None).await?;
assert_eq!(contacts.len(), 2);