Commit Graph

5563 Commits

Author SHA1 Message Date
link2xt
942172a31a feat: remove MvboxMove and OnlyFetchMvbox 2026-04-16 16:42:40 +00:00
link2xt
04c0e7da16 feat: do not unconditionally watch mvbox for non-chatmail
Since commit 25750de4e1
released in 2.36.0 we do not move messages to mvbox without explicit
mvbox_move setting, so do not need to watch it as well
as long as other devices are updated to the same change.
2026-04-16 16:42:40 +00:00
iequidoo
4178671839 fix: Scale up contacts messaged in groups to IncomingTo
This makes such contacts appear in the contact list. `IncomingTo` is used because
`ChatId::accept_ex()` does so for groups, so sending a group message is effectively accepting the
group again in regards to contact searchability.

This fixes up b549e7633d which made it impossible to find contacts
from groups even if we've written there.
2026-04-16 12:56:41 -03:00
Hocuri
1c24ad91eb feat: Remove the largely-unused ability to send multiple reactions to one message (#8131)
After talking with r10s:

For spring cleaning, remove the largely-unused things that can be done a
bit.

Most private messengers (WhatsApp/Signal/...) do not have this feature,
and we do not want to become Matrix where every client has different,
partly-incompatible features.
2026-04-16 14:30:05 +00:00
iequidoo
a70924a1d6 fix: fetch_single_msg(): Lock fetch_msgs_mutex before fetching
This is to avoid race conditions in `receive_imf` which also happened previously when
multi-transport was added.
2026-04-16 10:40:16 -03:00
iequidoo
8e91eecb3d feat: decide_chat_assignment: Log correct post_msg_exists value
rfc724_mid_exists() returns the message id not only when the message is fully downloaded, so we need
to check this additionally. Also improve test_receive_pre_message to check that receiving the
pre-message again doesn't affect the existing message.
2026-04-16 10:40:16 -03:00
iequidoo
89f948028d fix: Set Param::GuaranteeE2ee before preparing message blob (#8090)
Otherwise `Param::GuaranteeE2ee` is set only after rendering the message
and some UIs, e.g. DC Android, display the message as unencrypted while
preparing the blob and rendering and encrypting the message. NB: DC
Desktop doesn't display the message until `send_msg()` returns.

---------
Co-authored-by: Hocuri <hocuri@gmx.de>
2026-04-15 11:28:53 -03:00
72374
9adb71bf8f feat: Change multiplier to 7/8 when scaling down avatars
The resolution-limits for avatar-images are currently 512x512 or 256x256.
Reducing the resolution further, to 2/3 each step, can reduce the quality
much more than is necessary to fit within the file-size-limits,
which are currently 60 kB or 20 kB.

An image made entirely of noise (which results in unusually
large file-sizes), encoded with jpeg-quality 75,
and 4:2:2-colour-subsampling (the format currently used
for encoding images), can be below 60 kB at 227x227.
For the lower file-size-limit of 20 kB,
such images can be too large at 170x170, but fit at 149x149.
More normal images will have a lower file-size at the same resolution.

Before this change, the target-resolutions for resampling were:
512x512 ->                       341x341 ->                       227x227.

And for the lower file-size-limit:
256x256 ->                       170x170 ->                       113x113.

After this change, the target-resolutions for resampling will be:
512x512 -> 448x448 -> 392x392 -> 343x343 -> 300x300 -> 262x262 -> 229x229.

And for the lower file-size-limit, those will be:
256x256 -> 224x224 -> 196x196 -> 171x171 -> 149x149 -> 130x130 -> 113x113.

This does add 2 steps between the previous target-resolutions,
while still reaching target-resolutions close to the previous ones,
to reduce situations in which the quality will be lower than before.
2026-04-15 13:57:41 +02:00
72374
fe2ba05804 feat: Increase the resolution-limit WORSE_AVATAR_SIZE from 128 to 256
The file-size of many images will already be smaller than 20 kB,
when encoded at 256x256, and it can be a large improvement in quality.
2026-04-15 13:57:41 +02:00
link2xt
072fc34c77 fix: trash no-op messages about self being added to groups 2026-04-15 07:02:15 +00:00
link2xt
cb00bd7043 refactor: replace HashSet with BTreeSet
This is needed to avoid golden tests being flaky
because of info message order being different
between runs.
2026-04-15 07:02:15 +00:00
link2xt
f766c11075 perf: enable clippy::large_futures lint
Large size of Mimefactor.render() futures
increases the size of all callers
down to set_config() and background_fetch().
I also had to Box::pin one call to fetch_new_msg_batch
and one call to fetch_single_msg.
2026-04-15 05:33:52 +00:00
link2xt
89e450894d refactor: make HTML parser non-async 2026-04-14 12:43:46 +00:00
DarkCat09
6ef1f7d52b fix: restart io on transport deletion
Fixes #8038
2026-04-14 13:11:28 +02:00
iequidoo
ad7f873c68 fix: Ensure that message being sent is added to the bottom (#8027)
Before, if the user fixed their clock incorrectly set to the future, they needed to delete
previously sent messages or wait until this future comes again so that new sent messages are added
to the bottom. Strictly speaking, the problem isn't fixable because we don't know if messages were
incorrectly timestamped into the future or they are timestamped correctly and the clock is now
incorrectly set to the past. Anyway, adding messages to the middle of the chat isn't a good way to
inform the user about the problem.
2026-04-13 08:49:58 -03:00
WofWca
5d5deedec3 refactor: less nested remove_contact_from_chat 2026-04-11 12:23:16 +04:00
link2xt
f33e21ccb9 fix: trash message about group name change from non-member 2026-04-11 01:26:51 +00:00
link2xt
00c06c490b test: use TestContextManager in test_keep_member_list_if_possibly_nomember 2026-04-11 01:26:51 +00:00
Hocuri
8b58b16cb5 fix: For bots, wait with emitting IncomingMsg until the Post-Msg arrived (#8104)
I used some AI to draft a first version of this, and then reworked it.

This is one of multiple possibilities to fix
https://github.com/chatmail/core/issues/8041: For bots, the IncomingMsg
event is not emitted when the pre-message arrives, only when the
post-message arrives. Also, post-messages are downloaded immediately,
not after all the small messages are downloaded.

The `get_next_msgs()` API is deprecated. Instead, bots need to listen to
the IncomingMsg event in order to be notified about new events. Is this
acceptable for bots?

THE PROBLEM THAT WAS SOLVED BY THIS:

With pre-messages, it's hard for bots to wait for the message to be fully downloaded and then process it.

Up until now, bots used get_next_msgs() to query the unprocessed messages, then set last_msg_id after processing a message to that they won't process it again.

But this will now also return messages that were not fully downloaded.

ALTERNATIVES:

In the following, I will explain
the alternatives, and for why it's not so easy to just make the
`get_next_msgs()` API work. If it's not understandable, I'm happy to
elaborate more.

Core can't just completely ignore the pre-message for two reasons:
- If a post-message containing a Webxdc arrives later, and some webxdc updates arrive in the meantime, then these updates will be lost.
- The post-message doesn't contain the text (reasoning was to avoid duplicate text for people who didn't upgrade yet during the 2.43.0 rollout)

There are multiple solutions:
- Add the message as hidden in the database when the pre-message arrives.
  - When the post-message arrives and we want to make it available for bots, we need to update the msg_id because of how the `get_next_msgs()` API works. This means that we need to update all webxdc updates that reference this msg_id.
  - Alternatively, we could make webxdc's reference the rfc724_mid instead of the msg_id, so that we don't need stable msg_ids anymore
  - Alternatively, we could deprecate `get_next_msgs()`, and ask bots to use plain events for message processing again. It's not that bad; worst case, the bot crashes and then forgets to react to some messages, but the user will just try again. And if some message makes the bot crash, then it might actually be good not to try and process it again.
- Store the pre-message text and `PostMsgMetadata` (or alternatively, the whole mime) in a new database table. Wait with processing it until the post-message arrives.

Additionally, the logic that small messages are downloaded before post-messages should be disabled for bots, in order to prevent reordering.
2026-04-10 21:10:46 +02:00
link2xt
d6971ee4ac fix: make start messages stick to the top of the chat
We already set sort_timestamp to 0 for "Messages are end-to-end encrypted."
since 8f1bf963b4.
Do this for "Others will only see this group after you sent a first message."
and "Messages in this chat use classic email and are not encrypted." as well
so no messages can be added on top.
2026-04-10 03:16:12 +00:00
holger krekel
60bc4011f7 fix: let search also return hidden contacts if search value is an email address 2026-04-07 22:39:13 +02:00
link2xt
f552cf93b4 fix: assign webxdc updates from post-message to webxdc instance 2026-04-07 19:14:44 +00:00
link2xt
f75a7986b5 refactor: ignore ForcePlaintext in saved messages chat
ForcePlaintext was used for Autocrypt Setup Message,
there is no need to support it in saved messages chat anymore.
2026-04-07 17:00:47 +00:00
link2xt
3b8f1934f3 api!: remove dc_msg_force_plaintext
Message.force_plaintext() is still used in legacy SecureJoin steps
internally, so cannot be removed, but there is no need for public API.
2026-04-07 17:00:47 +00:00
link2xt
d2097d3523 fix: do not URL-encode proxy hostnames 2026-04-06 13:16:28 +00:00
link2xt
1219cbe1a3 fix: do not create 1:1 chat on second device when scanning a QR code
This avoids creating 1:1 chat on a second device when joining a channel.
Now when joining a channel there may be no 1:1 chat with the inviter
when the channel is created. In this case we still create the channel
as unblocked even if 1:1 chat would be a contact request
because joining the channel is an explicit action
and it is not possible to add someone who did not scan a QR
to the channel manually.
2026-04-06 00:42:14 +00:00
Hocuri
7233b4b811 test: Test that messages are only marked as delivered after being fully sent out (#8077)
Test for https://github.com/chatmail/core/pull/8062. I checked that the
test fails without #8062.
2026-04-05 20:37:32 +00:00
iequidoo
d1e0088201 feat: Flipped Exif orientations (#8057)
Before, sending of images flipped in Exif led to images having wrong orientation.
2026-04-05 17:04:17 -03:00
iequidoo
2f76fd98dd test: Add test for tweak_sort_timestamp()
The part of logic there adjusting the sort timestamp forward if the parent message has a greater
sort timestamp wasn't tested explicitly by any test. I only saw one unrelated "golden test" failure
when commented it out.
(Related to #8027)
2026-04-05 11:16:15 -03:00
Hocuri
626ac8161a fix: Mark a message as delivered only after it has been fully sent out (#8062)
Fix https://github.com/chatmail/core/issues/8042

The problem was that after receiving the bcc_self'ed pre-message in
`receive_imf`, the logic there only looked for a pending
`smtp`-table-entry that matches the rfc724_mid, and if there was none
then it thought "Great, apparently the message is fully sent out, we can
mark it as delivered!".

But with pre-messages, the same message can have two `smtp` entries (one
for the pre-message and one for the post-message), and the message
should only be marked as delivered once both of them are sent out.

Now, I changed the logic to look for all entries with the same msg_id.
This is actually the same SQL query used in smtp.rs, so, I extracted it
into a new function; feel free to suggest a better name for it.

I tested on Android that it now works fine.

I'll add a test in a follow-up PR.

There are a lot of other problems with sending large files, though:
- The pre-message is sent before the post-message, so that for the
receiver it looks as if the message arrived, but stays in
"downloading..." forever
- There is quite a time delay between clicking on "Send" and the
outgoing message appearing in the chat
- The message shortly gets a letter icon right after it is sent
- I'm wondering if there is a way to give feedback to the user
immediately if the message is too big
- It's unclear when exactly we want to send read receipts

I'll open a follow-up issue for these.
2026-04-02 15:12:17 +02:00
holger krekel
28cce5e31d fix: determine whether a message is an own message by looking at signature. multiple devices can temporarly have different sets of self addresses, and still need to properly recognize incoming versus outgoing messages. Disclaimer: some LLM tooling was initially involved but i went over everything by hand, and also addressed review comments. 2026-04-01 14:51:48 +02:00
link2xt
eb666d4cc3 test: the message is sorted correctly in the chat even if it arrives late 2026-03-30 08:52:19 +00:00
link2xt
ef265689dd fix: do not sort received messages below the last seen one 2026-03-30 08:52:19 +00:00
link2xt
49223792f9 fix: never sort the message before chat joining timestamp
This is to avoid sorting incoming messages that
are slightly in the past above system messages
about SecureJoin. SecureJoin messages are
timed according to smeared timestamp,
so even in the local tests they are in the future
by a few seconds.
2026-03-30 08:52:19 +00:00
Hocuri
920da083d1 fix: Manipulate sort_timestamp to not be 0 2026-03-30 08:52:19 +00:00
link2xt
8f1bf963b4 fix: always sort "Messages are end-to-end encrypted" notice to the beginning
We set timestamp of this info message to 0
to make it always appear in the beginning of the chat.
To avoid new chats being sorted to the end of the chatlist,
we ignore such 0 and use chat creation timestamp
when sorting the chatlist.
2026-03-30 08:52:19 +00:00
link2xt
e33d50b4e0 test: use load_imf_email() more 2026-03-30 08:52:19 +00:00
link2xt
f1dc03a4ee test: do not rely on loading newest chat in load_imf_email()
We know which message was added from the return value
of receive_imf(). It may be that the first chat
in the chatlist is not the one where the message was received
if there is a pinned chat or if
just received message is old.
2026-03-30 08:52:19 +00:00
link2xt
5d90cc7a2a test: remove test_old_message_5
It is not clear now what this is testing.
Golden test shows messages ordered
incorrectly according to the timestamps,
they should be ordered the other way round.

Comment talks about fetching from mvbox and inbox
in paralell which is a rare case that
could have happened if one message is left in the inbox
and the other message is a chat message moved to mvbox.
We never download anything that is not moved to the target folder.

The test also resides in "verified chats" tests
which are all legacy tests we kept after
replacing the concept of verified/protected chats
with key contacts in 2.x.
2026-03-30 08:52:19 +00:00
link2xt
68e630eb82 fix: remove migration 108
This removes migration added in 625887d249
2026-03-30 08:38:28 +00:00
iequidoo
ef718bb869 fix: When receiving MDN, mark all preceding messages as noticed, even having same timestamp (#7928)
This fixes flaky JSON-RPC `test_multidevice_sync_seen`.
2026-03-29 11:50:50 -03:00
iequidoo
f1860f90d4 feat: Log received message sort timestamp
This way it's easier to debug issues like `MsgsNoticed` not emitted for a chat.
2026-03-29 11:50:50 -03:00
link2xt
a947f4296f refactor(securejoin): do not check for self address in forwarding protection
If our key is gossiped, the message is intended for us.
The check for address is redundant for incoming messages as
if we received the message then it was addressed to us.

This whole protection code can eventually be removed
as we have intended recipient fingerprints already,
it only protects against forwarding of messages
sent by old clients.
2026-03-28 16:20:39 +00:00
link2xt
8c3139f7a2 feat: add decryption error to the device message about outgoing message decryption failure 2026-03-28 13:27:15 +00:00
link2xt
b87805ab24 fix: cleanup imap and imap_sync records without transport in housekeeping
Previously transports deleted via sync messages left unused `imap` entries.
2026-03-26 16:24:11 +00:00
link2xt
c8716ad85a fix: delete imap_markseen entries not corresponding to any imap rows 2026-03-26 16:24:11 +00:00
link2xt
4dd0ba2c72 fix: move sorting outside of SQL query in store_seen_flags_on_imap
With `ORDER BY` statement SQLite searches
the `imap` table by `transport_id` and for each found row
scans the whole `imap_markseen` table.
Number of `imap` entries for each `transport_id`
is usually large as we need to know
which UIDs to delete on IMAP server
when deleting a message.

```
sqlite> EXPLAIN QUERY PLAN
SELECT imap.id, uid, folder FROM imap, imap_markseen
WHERE imap.id = imap_markseen.id
AND imap.transport_id=?
AND target = folder
ORDER BY folder, uid;
QUERY PLAN
|--SEARCH imap USING INDEX sqlite_autoindex_imap_1 (transport_id=?)
`--SCAN imap_markseen
```

Without `ORDER BY` statement SQLite scans `imap_markseen`
table which is expected to be small,
and then searches `imap` table by `rowid` for each found result.

```
sqlite> EXPLAIN QUERY PLAN
SELECT imap.id, uid, folder FROM imap, imap_markseen
WHERE imap.id = imap_markseen.id
AND imap.transport_id=?
AND target = folder;
QUERY PLAN
|--SCAN imap_markseen
`--SEARCH imap USING INTEGER PRIMARY KEY (rowid=?)
```

Query planning was tested with SQLite 3.52.0.
It is possible to explictly make
query planner move sorting to the last step
with `ORDER +folder, +uid`, but this is not recommended
in SQLite documentation
(see <https://www.sqlite.org/optoverview.html#uplus>).

It is also possible to add indexes,
but indexes use space,
adding them requires an SQL migration,
and each index needs to be updated so it will slow down writes.
2026-03-26 16:24:11 +00:00
iequidoo
af16fc9038 fix: Make Message-ID of pre-messages stable across resends (#8007) 2026-03-25 23:32:33 -03:00
link2xt
c99b8a4482 feat: improve IMAP loop logs
Only inbox loop is changed because non-inbox loop is going to be removed
together with `mvbox_move`.

Added transport IDs to the log and logging around quota updates.
Removed some logs that add noise,
like logging that IDLE is supported each time right before using it.
2026-03-25 20:31:53 +00:00
link2xt
76e2c36d85 refactor: cleanup remaining Autocrypt Setup Message processing in mimeparser 2026-03-25 19:54:19 +00:00