feat: key-contacts

This change introduces a new type of contacts
identified by their public key fingerprint
rather than an e-mail address.

Encrypted chats now stay encrypted
and unencrypted chats stay unencrypted.
For example, 1:1 chats with key-contacts
are encrypted and 1:1 chats with address-contacts
are unencrypted.
Groups that have a group ID are encrypted
and can only contain key-contacts
while groups that don't have a group ID ("adhoc groups")
are unencrypted and can only contain address-contacts.

JSON-RPC API `reset_contact_encryption` is removed.
Python API `Contact.reset_encryption` is removed.
"Group tracking plugin" in legacy Python API was removed because it
relied on parsing email addresses from system messages with regexps.

Co-authored-by: Hocuri <hocuri@gmx.de>
Co-authored-by: iequidoo <dgreshilov@gmail.com>
Co-authored-by: B. Petersen <r10s@b44t.com>
This commit is contained in:
link2xt
2025-06-26 14:07:39 +00:00
parent 7ac04d0204
commit 416131b4a2
84 changed files with 4735 additions and 6338 deletions

View File

@@ -153,104 +153,4 @@ mod tests {
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_out_of_order_group_name() -> Result<()> {
let t = TestContext::new_alice().await;
receive_imf(
&t,
b"From: Bob Authname <bob@example.org>\n\
To: alice@example.org\n\
Message-ID: <msg1@example.org>\n\
Chat-Version: 1.0\n\
Chat-Group-ID: abcde123456\n\
Chat-Group-Name: initial name\n\
Date: Sun, 22 Mar 2021 01:00:00 +0000\n\
\n\
first message\n",
false,
)
.await?;
let msg = t.get_last_msg().await;
let chat = Chat::load_from_db(&t, msg.chat_id).await?;
assert_eq!(chat.name, "initial name");
receive_imf(
&t,
b"From: Bob Authname <bob@example.org>\n\
To: alice@example.org\n\
Message-ID: <msg3@example.org>\n\
Chat-Version: 1.0\n\
Chat-Group-ID: abcde123456\n\
Chat-Group-Name: =?utf-8?q?another=0Aname update?=\n\
Chat-Group-Name-Changed: =?utf-8?q?a=0Aname update?=\n\
Date: Sun, 22 Mar 2021 03:00:00 +0000\n\
\n\
third message\n",
false,
)
.await?;
receive_imf(
&t,
b"From: Bob Authname <bob@example.org>\n\
To: alice@example.org\n\
Message-ID: <msg2@example.org>\n\
Chat-Version: 1.0\n\
Chat-Group-ID: abcde123456\n\
Chat-Group-Name: =?utf-8?q?a=0Aname update?=\n\
Chat-Group-Name-Changed: initial name\n\
Date: Sun, 22 Mar 2021 02:00:00 +0000\n\
\n\
second message\n",
false,
)
.await?;
let msg = t.get_last_msg().await;
let chat = Chat::load_from_db(&t, msg.chat_id).await?;
assert_eq!(chat.name, "another name update");
// Assert that the \n was correctly removed from the group name also in the system message
assert_eq!(msg.text.contains('\n'), false);
// This doesn't update the name because Date is the same and name is greater.
receive_imf(
&t,
b"From: Bob Authname <bob@example.org>\n\
To: alice@example.org\n\
Message-ID: <msg4@example.org>\n\
Chat-Version: 1.0\n\
Chat-Group-ID: abcde123456\n\
Chat-Group-Name: another name update 4\n\
Chat-Group-Name-Changed: another name update\n\
Date: Sun, 22 Mar 2021 03:00:00 +0000\n\
\n\
4th message\n",
false,
)
.await?;
let chat = Chat::load_from_db(&t, chat.id).await?;
assert_eq!(chat.name, "another name update");
// This updates the name because Date is the same and name is lower.
receive_imf(
&t,
b"From: Bob Authname <bob@example.org>\n\
To: alice@example.org\n\
Message-ID: <msg5@example.org>\n\
Chat-Version: 1.0\n\
Chat-Group-ID: abcde123456\n\
Chat-Group-Name: another name updat\n\
Chat-Group-Name-Changed: another name update\n\
Date: Sun, 22 Mar 2021 03:00:00 +0000\n\
\n\
5th message\n",
false,
)
.await?;
let chat = Chat::load_from_db(&t, chat.id).await?;
assert_eq!(chat.name, "another name updat");
Ok(())
}
}