Commit Graph

5811 Commits

Author SHA1 Message Date
link2xt
77dd9075ca chore(cargo): bump mail-builder from 0.4.4 to 0.5.0 2026-09-02 21:35:13 +00:00
link2xt
0b0398561d fix: do not emit events in set_profile_image() if contact avatar is unchanged
Previously `changed` variable was always set to `true`.
2026-09-02 20:51:51 +00:00
link2xt
3ff8011676 refactor: remove the code to set own avatar in set_profile_image()
This code remains from the time when we have synchronized the avatar
between devices by looking at outgoing messages.
2026-09-02 20:51:51 +00:00
link2xt
38d6cf2bcd feat: import Autocrypt-Gossip keys without checking the addresses
It is safe to import any keys into the keychain.
Keys can anyway be imported from vCards
and Autocrypt headers without any checks.

These checks are from the time before we had key-contacts
and maintained Autocrypt `peerstates` table.
2026-09-02 20:51:15 +00:00
link2xt
46d45faf7e refactor: remove unused functions from the tools module
Also marked functions that are not used outside as pub(crate).
Some functions like get_filesuffix_lc() are still used
by deltachat-repl, so the whole module cannot be made private.
2026-09-01 17:12:38 +00:00
holger krekel
70a01a6813 feat!: remove a relay immediately instead of unpublishing it
Removing a relay now takes effect immediately:

- the profile stops fetching and advertising it,

- secondary devices immediately apply the removal through the transport sync,

Upgrading removes unpublished relays and triggers keyupdates.

BREAKING CHANGE: set_transport_unpublished() is removed: UIs call delete_transport() when the user removes a relay.

BREAKING CHANGE: list_transports_ex() and the TransportListEntry type are removed: use list_transports().

BREAKING CHANGE: delete_transport() no longer refuses to remove the primary transport: it refuses only to remove the last one and re-elects the sending transport as needed.

BREAKING CHANGE: TransportsModified is now also emitted on the device modifying the transports, not only on devices applying the synced change.

Deprecated: DC_STR_PHASING_OUT
2026-09-01 14:15:26 +02:00
holger krekel
3d61e0f349 fix: return no relay address for key-contacts without an address
`relay_addrs()` fell back to the contact address even when it is empty,
which happens for key-contacts created from a sync message or for the
self-contact, putting an empty string into the SMTP recipient list.
2026-08-29 23:11:05 +02:00
holger krekel
f162749dfe feat: introduce keyupdate messages informing contacts about relay changes
When the published relay list changes, key-contacts are informed with an
unsigned message carrying the re-signed key, encrypted to a chunk of contacts
at a time. It is shaped like a receipt notification naming no message, so that
cores which know nothing about keyupdates trash it as well.

See the src/keyupdate.rs module docs for the design.
2026-08-29 23:11:05 +02:00
holger krekel
370cc5c1fd fix: trash early MDNs that reference no message
A report referencing no message can never be applied to one,
so it must not create a contact, a chat or a `last_seen` update
on its way to the trash.
2026-08-29 23:11:05 +02:00
holger krekel
08b2374fcf feat: allow to not sign asymmetrically encrypted multi-recipient messages
An unsigned message carries no intended recipient fingerprints,
so recipients of an encrypted unsigned message
learn nothing about other recipients from the PGP packets.
2026-08-29 23:11:05 +02:00
holger krekel
5176a9c633 refactor: extract shared pieces for non-chat messages
No functional changes:
Add a relay_addrs helper, share the protected headers and self-key rendering
of non-chat messages, and move insert_into_smtp from securejoin to smtp.
2026-08-29 23:11:05 +02:00
link2xt
4d5ebe9ff4 feat: delete avatars referred to by parameters of special contacts
It is not clear if old versions stored SELF avatar in parameters
or if it happened due to a bug, but if it happens,
we can safely delete the avatar.

get_profile_image_ext() is refactored to make it
not try to load avatars for any special contacts.
2026-08-29 16:50:50 +00:00
WofWca
0517beef61 fix: don't notify of missed call from blocked user
Closes https://github.com/chatmail/core/issues/8576.

The diff might look big, but it's only two things:
- move `can_call_me` one scope up
- replace `emit_incoming_msg` with `emit_msg_event`
  with `important = can_call_me`

I decided not to completely unify the `important` logic
with the other occurrence of `emit_msg_event()`
as I suggested in the issue yet.
That IMO should still be considered, but let's start simple.

Note that there is #7840 which may be closed by #7955,
which will basically supersede this MR.
I think, however, that it's OK to merge this one,
and then that one can just revert this one, including tests,
and rebase on top of the revert.
2026-08-28 09:11:09 +00:00
link2xt
693c404266 fix: do not try to load profile image from param for self
I have an old profile which has ProfileImage param
set on the reserved SELF contact.  When I deleted
an avatar from the profile, very old profile image
showed up in the settings in Delta Chat Desktop instead,
which can be "deleted" again without any result.

This fix is to return `None` early from get_profile_image_ext
for self contact without trying to load the parameter.
Fallthrough to loading params was likely there
since keycontacts and grey avatars for address contacts
introduction in 416131b4a2
2026-08-27 21:44:45 +00:00
holger krekel
a344cab046 refactor: rename automatic_relay_management to autorelay
"automatic_relay_management" is a long unwiedly name with no UI using the mode yet,
so let's rename it to something more succinct: autorelay
2026-08-27 16:52:38 +02:00
link2xt
3af45c306a fix: make create_send_msg_jobs actually return row IDs
.execute() was returning the number of rows, so usually 1.
.insert() is returning the row ID.

In most cases it does not matter because the result is checked with .is_empty(),
but send_msg_sync() actually uses the row IDs.
2026-08-26 20:22:57 +00:00
link2xt
709c56a889 refactor: make create_send_msg_jobs() private
It is not called from outside the "chat" module.
2026-08-26 20:22:57 +00:00
link2xt
7421e67ab6 feat: do not create device messages for IMAP authentication errors
Authentication failures may happen because of internal server errors.
Device message saying "Please check if the email address and the password are correct"
was written for classic email setups when the user knows the password.
For users of chatmail relays this message is not actionable,
but still appears when relay fails to check the password.
2026-08-26 13:53:02 +00:00
j-g00da
49496756e4 refactor: Don't include email addresses in export filenames (#8626)
Changes filenames used in the db backups and key exports,
preferring fingerprint over the email address.

Part of: #8572

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-08-26 13:44:06 +02:00
holger krekel
ea3ca3a213 fix: reliably complete configuration with progress=1000 or progress=0
this is meant to help configuration event consumers (Python, UIs)
to not hang waiting for configuration outcomes.
One test case is added that fails on main.
2026-08-24 19:09:34 +02:00
link2xt
6c47e86380 refactor: turn DC_MSG_ID_* into MsgId::* associated constants 2026-08-22 20:21:20 +00:00
link2xt
fe25e93d6c refactor: turn DC_CHAT_ID_* into ChatId::* associated constants
We already have it done for ContactId.
2026-08-22 20:21:20 +00:00
link2xt
0b2ff5d0e2 fix: take timestamp_rcvd into account in estimate_deletion_cnt
This did not affect actual message deletion,
because select_expired_messages already takes timestamp_rcvd
into account and does not delete system messages
that say "Messages are end-to-end encrypted" too early.

So it is a minor bug as estimate_deletion_cnt
is meant to only roughly estimate the number of messages
to be deleted. Still, there were no tests before,
so now estimate_deletion_cnt is tested.
2026-08-22 20:21:20 +00:00
j-g00da
589a628cda refactor: Don't store email address in location KML. (#8615)
Address inside the KML is not used anywhere,
and we are moving away from "primary" relay notation (and thus also
identifying contacts by email address).

Part of: #8572

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-08-21 13:46:29 +02:00
link2xt
3df1e3712a fix: send legacy securejoin key requests as multipart/mixed
chatmail relays (filtermail) expect {vc,vg}-request
messages to be multipart/mixed with a single part.
Messages had this structure
before commit e0494b0b37
so we need to keep it for compatibility.
2026-08-20 20:31:27 +00:00
j-g00da
484d56f24d feat: Use display name for contacts in encryption info (#8609)
Email address is already present in the list of relays,
a display name is more useful.

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-08-20 08:00:30 +02:00
holger krekel
8f3337d971 refactor: move pgp tests to submodule 2026-08-19 02:00:14 +02:00
j-g00da
1283b986df feat: carry all published relay addresses in securejoin links (#8591)
Carry all published "secondary" addresses in `r` param of the securejoin URL.

Closes: #8590
Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-08-18 19:19:54 +00:00
biørn
07e18c64af sanitize version_string we got from the wire (#8582)
`version_string` is meant to be displayed by UI, and comes from the
wire.

therefore, as a general precaution, ensure a string that is
regarded as a typical version string. all versions in scope are
currently v123.456.789-shortsuffix, where suffix is a-z and mostly
unused in production. that is the base. we can adapt if there is really
a need, but not for theoretical version strings. as we do not stop
processing, things are not bad even if we missed a valid usecase herr.

moreover, if `version_string` is empty, we skip the candidate - as we
cannot display something useful to the user. that little bit of care is
expected from relays :)
2026-08-14 12:01:15 +00:00
link2xt
3dce06b02b refactor(mimefactory): add Encryption enum
This replaces independent data structures
which allowed invalid state of having both the public keys
and the shared secret, or having a shared secret
but not encrypting the message because encryption_pubkeys
was None instead of Some(Vec::new()).
2026-08-14 11:32:33 +00:00
link2xt
40faf829d3 feat: stop creating info messages for old broadcast lists
Creating QR code or sending a message will still fail
with a shorter error, but no info message will be created anymore.
Most users should have migrated the channels by recreating them by now.

This change is needed for moving loading of the shared secret
to earlier stages of message preparation,
otherwise mimefactory will have to create these info messages
when loading the message into memory.
2026-08-14 11:32:33 +00:00
WofWca
fbbe56c8ff refactor: rename _ex() -> _ext()
"ex" means "used to be, but no longer is".
"ext" means "extended", which is the intended meaning.
"Ext" is more common not only in the Rust ecosystem but in general.
We already had several people (myself included) asking
what "ex" is supposed to mean.

To reproduce this commit, search and replace `_ex(?!\w)` -> `_ext`.
But don't change `list_transports_ex` because it's public API.
2026-08-14 14:40:43 +04:00
holger krekel
ce7c8dbca1 fix: send http requests in origin not absolute form
Absolute form is meant for proxies and for example
nginx rejects it with 400 if the host contains an underscore, breaking autoconfig discovery.
2026-08-14 12:09:24 +02:00
link2xt
e0494b0b37 feat: remove hidden headers
Unencrypted messages are no longer sent as multipart/mixed
with Message-ID header duplicated inside.
This was useful as non-standard protection
against servers that rewrite the Message-ID,
but now most messages are sent encrypted
and for them standard RFC 9788 header protection
works the same way.
2026-08-14 07:09:49 +00:00
biørn
c1e961d37f feat: client version information (#8557)
> we aim to inform about updates for installations outside of any
appstore soon.
>
> there is already a PR on android at
https://github.com/deltachat/deltachat-android/pull/4582, however, the
information about "update available" is a mockup there.
>
> in general, there are 3 ideas around about how to gather the "update
available" infomation - (1) checking a central url, (2) let contacts
provide information, (3) let relay provide information. on various
one-to-one discussions, outcome is that (3) is the most reasonable way
to go.

this PR is about reading update information via IMAP metadata from the
relay.

it is up to the UI to call `get_app_version()` at a reasonable time and
frequency, see comment in the code. when called, `get_app_version()`
iterates over all known profiles and relays and checks for version
information, returning the newest for the given scope.

we do not use an event, as that is tricky wrt changes - we do not know
if other relays report later a newer version. we also do not cache
anything, to prevent bad relays avoiding us to update permanently. also
it is easier :)

<details>
<summary>outdated notes and questions</summary>

- ~~it is up to the clients to get the needed information, we could let
core filter, but it seems easy enough the other way round, and may have
debug advantages, one can iterate etc.~~ EDIT: we now filter in core,
this also makes the jsonrpc part easier, see review comments

- when is IMAP METADATA actually read? when are they ready? is that
really the correct place? i am up to change that, but beware, this is
not really my expertise, so someone else may need to take over :)
EDIT: see below, IMAP METADATA is read on connection, before fetching
starts, usually fast enough

- relay part is missing. once the format is settled and discussed
shortly here, that should be done soon as well. but this is definitely
not my expertise and needed to be done by someone else :)

- key for IMAP METADATA is `/shared/vendor/deltachat/appversions` -
shall we continue use `deltachat` for compatibility or so? `chatmail`
seems to be more correct
EDIT: we stay with the current
</details>

relay counterpart issue: https://github.com/chatmail/relay/issues/1037

cc @link2xt @Hocuri @hpk42

---------

Co-authored-by: holger krekel <holger@merlinux.eu>
2026-08-13 16:45:58 +02:00
Jagoda Estera Ślązak
1edbfa1024 refactor: Merge msg_group_left_local into msg_del_member_local (#8575)
Follow-up to #8562

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-08-13 14:08:27 +02:00
link2xt
ec4d195814 fix: send MDNs to self even if MDNs are disabled
MDNs to self are used for seen status synhronization between devices.
2026-08-13 11:36:50 +00:00
link2xt
e2b0eb1fb9 chore: fix nightly clippy warnings 2026-08-12 20:56:33 +00:00
link2xt
998892395a docs: do not refer to is_chat_protected()
is_chat_protected() does not exist anymore.
2026-08-12 19:28:32 +00:00
link2xt
d89a972a2c refactor: stop setting chats.protected column explicitly
It is not used anymore and has a default value of 0.
2026-08-12 19:28:32 +00:00
link2xt
ae5b27fb69 refactor: remove MessengerMessage
This value is not used for any logic
except the disappearing messages timer rollback prevention.
It is unlikely that non-chat clients
participate in chats with disappearing messages,
and the case was not tested anyway.
2026-08-12 07:44:38 +00:00
B. Petersen
c680432c23 fix: filtered reactions are info, not error in device chat
bail!() bubbles up the error until it lands in the device chat,
which is way over the top for a reaction that is filtered out by channel owner.

currently this happens, as arcance chat uses different default reactions.
in the future, this may happen even more often when we allow custom filters,
that may change over time.
2026-08-11 21:49:38 +02:00
Jagoda Estera Ślązak
4623d89528 feat: Add stock strings for being added/removed from group (#8562)
Adds following stock strings:
- You were removed by %1$s.
- You were added by %1$s.

and implicit equivalents:
- You were removed.
- You were added.

Closes: #8419

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-08-11 18:47:30 +00:00
holger krekel
5ec1d65294 test: move iroh tests into separate module 2026-08-11 18:08:58 +02:00
biørn
68ce93c420 feat: resend pinned state in broadcast channels (#8549)
this PR adds the "message pinned state" to the "reaction state" that is
already sent together with resent channel messages since #8496.
this change is done in the first commit, and in fact only changes few
lines (one can consider to rename "broadcast_reactions.rs" and related
stuff to "broadcast_state.rs" in another PR: i did not to that in this
PR to keep diff and review simple).

moreover, in the second commit ,the "selection of messages to resent" is
changed to keep an additional focus on the pinned messages, so that the
most recent pinned messages are resent as well.

successor of #8496 and #8546
2026-08-10 17:22:29 +00:00
Jagoda Estera Ślązak
fd8c56894a test: Assert log warnings and errors (#8457)
Adds `assert_warn`, `assert_error` and `assert_warns_or_errors`
methods to `TestContext`, that let us assert that
a certain warning or error is logged during the test.
Also asserts test logs should not contain any other
errors or warnings.

Adjusts tests accordingly.

Signed-off-by: Jagoda Ślązak <jslazak@jslazak.com>
2026-08-10 13:36:09 +00:00
WofWca
97932fda07 fix: improve connectivity HTML if quota info error
Currently if there is an error fetching quota
then the HTML displays something like

```
example.com: Connected
Failed to parse
```

It's not clear that "Failed to parse" only refers to quota info.
2026-08-10 12:55:08 +00:00
holger krekel
cd42efb36d fix!: keep primary transport device-local
Devices no longer implicitely use the From address of sync messages
to determine their primary transport. Receivers have no concept of it and own devices
may disagree on which relay is reachable because of VPN or different networks:

1. Make setting a primary transport (`configured_addr`) a per-device non-synced operation.

2. Transport rows (add/remove/unpublish) keep syncing like before.

3. A device reelects a primary if a sync message unpublished/removed the current primary
   if there is a better candidate.

4. `TransportsModified` event is emitted at most once on an incoming transport sync message.

Users will notice the change in that changing primary transport in settings/advanced/relays
will not synchronize to other devices anymore.
2026-08-10 14:43:28 +02:00
holger krekel
2cacdbfd4b fix: prevent transport de-synchronization because of early fetch cancellation
Came across this while investigating more test_transport_synchronization flakiness,
sometimes missing TransportsModified events or getting a missing configured_addr.
The underlying problem was that stopping IO was triggered immediately during
receiving sync messages, potentially *canceling* the processing of the sync message,
effectively de-syncing the device's view on transports.
2026-08-10 14:20:59 +02:00
holger krekel
6934aa26ae fix: invalidate configured_addr cache before sending transport sync message
Uncaching only after send_sync_transports() could send the sync message
from the old primary address, so other devices never switched.
2026-08-10 14:20:59 +02:00