Commit Graph

9978 Commits

Author SHA1 Message Date
Hocuri
c724e2981c feat: Securejoin v3, encrypt all securejoin messages (#7754)
Close https://github.com/chatmail/core/issues/7396. Before reviewing,
you should read the issue description of
https://github.com/chatmail/core/issues/7396.
I recommend to review with hidden whitespace changes.

TODO:
- [x] Implement the new protocol
- [x] Make Rust tests pass
- [x] Make Python tests pass
- [x] Test it manually on a phone
- [x] Print the sent messages, and check that they look how they should:
[test_secure_join_group_with_mime_printed.txt](https://github.com/user-attachments/files/24800556/test_secure_join_group.txt)
- [x] Fix bug: If Alice has a second device, then Bob's chat won't be
shown yet on that second device. Also, Bob's contact isn't shown in her
contact list. As soon as either party writes something into the chat,
the that shows up and everything is fine. All of this is still a way
better UX than in WhatsApp, where Bob always has to write first 😂
Still, I should fix that.
- This is actually caused by a larger bug: AUTH tokens aren't synced if
there is no corresponding INVITE token.
  - Fixed by 6b658a0e0
- [x] Either make a new `auth_tokens` table with a proper UNIQUE bound,
or put a UNIQUE bound on the `tokens` table
- [x] Benchmarking
- [x] TODOs in the code, maybe change naming of the new functions
- [x] Write test for interop with older DC (esp. that the original
securejoin runs if you remove the &v=3 param)
- [x] From a cryptography perspective, is it fine that vc-request is
encrypted with AUTH, rather than a separate secret (like INVITE)?
- [x] Make sure that QR codes without INVITE work, so that we can remove
it eventually
- [x] Self-review, and comment on some of my code changes to explain
what they do
- [x] ~~Maybe use a new table rather than reusing AUTH token.~~ See
https://github.com/chatmail/core/pull/7754#discussion_r2728544725
- [ ] Update documentation; I'll do that in a separate PR. All necessary
information is in the https://github.com/chatmail/core/issues/7396 issue
description
- [ ] Update tests and other code to use the new names (e.g.
`request-pubkey` rather than `request` and `pubkey` rather than
`auth-required`); I'll do that in a follow-up PR

**Backwards compatibility:**
Everything works seamlessly in my tests. If both devices are updated,
then the new protocol is used; otherwise, the old protocol is used. If
there is a not-yet-updated second device, it will correctly observe the
protocol, and mark the chat partner as verified.

Note that I removed the `Auto-Submitted: auto-replied` header from
securejoin messages. We don't need it ourselves, it's a cleartext header
that leaks too much information, and I can't see any reason to have it.

---------

Co-authored-by: iequidoo <117991069+iequidoo@users.noreply.github.com>
2026-03-02 16:37:14 +00:00
dependabot[bot]
ffd9f80f8b chore(cargo): bump syn from 2.0.114 to 2.0.117
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.114 to 2.0.117.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.114...2.0.117)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.117
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 06:30:52 -03:00
dependabot[bot]
42cb9fe890 chore(cargo): bump anyhow from 1.0.100 to 1.0.102
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.100 to 1.0.102.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.100...1.0.102)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.102
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 06:17:48 -03:00
dependabot[bot]
914486cb32 chore(cargo): bump hyper-util from 0.1.19 to 0.1.20
Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.19 to 0.1.20.
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.19...v0.1.20)

---
updated-dependencies:
- dependency-name: hyper-util
  dependency-version: 0.1.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 02:32:00 +00:00
dependabot[bot]
526b3b0271 chore(cargo): bump regex from 1.12.2 to 1.12.3
Bumps [regex](https://github.com/rust-lang/regex) from 1.12.2 to 1.12.3.
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.12.2...1.12.3)

---
updated-dependencies:
- dependency-name: regex
  dependency-version: 1.12.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 02:31:47 +00:00
dependabot[bot]
1c439b5ef4 chore(cargo): bump async-imap from 0.11.1 to 0.11.2
Bumps [async-imap](https://github.com/async-email/async-imap) from 0.11.1 to 0.11.2.
- [Changelog](https://github.com/chatmail/async-imap/blob/main/CHANGELOG.md)
- [Commits](https://github.com/async-email/async-imap/compare/v0.11.1...v0.11.2)

---
updated-dependencies:
- dependency-name: async-imap
  dependency-version: 0.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 02:11:13 +00:00
dependabot[bot]
f97c75f146 chore(cargo): bump tempfile from 3.24.0 to 3.25.0
Bumps [tempfile](https://github.com/Stebalien/tempfile) from 3.24.0 to 3.25.0.
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/commits)

---
updated-dependencies:
- dependency-name: tempfile
  dependency-version: 3.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 01:26:52 +00:00
dependabot[bot]
76a36a35bf chore(cargo): bump criterion from 0.8.1 to 0.8.2
Bumps [criterion](https://github.com/criterion-rs/criterion.rs) from 0.8.1 to 0.8.2.
- [Release notes](https://github.com/criterion-rs/criterion.rs/releases)
- [Changelog](https://github.com/criterion-rs/criterion.rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/criterion-rs/criterion.rs/compare/criterion-v0.8.1...criterion-v0.8.2)

---
updated-dependencies:
- dependency-name: criterion
  dependency-version: 0.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 00:58:02 +00:00
dependabot[bot]
dc4249a2ff chore(cargo): bump quick-xml from 0.39.0 to 0.39.2
Bumps [quick-xml](https://github.com/tafia/quick-xml) from 0.39.0 to 0.39.2.
- [Release notes](https://github.com/tafia/quick-xml/releases)
- [Changelog](https://github.com/tafia/quick-xml/blob/master/Changelog.md)
- [Commits](https://github.com/tafia/quick-xml/compare/v0.39.0...v0.39.2)

---
updated-dependencies:
- dependency-name: quick-xml
  dependency-version: 0.39.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 00:48:51 +00:00
dependabot[bot]
957c0b7c56 chore(cargo): bump futures from 0.3.31 to 0.3.32
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.31 to 0.3.32.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.31...0.3.32)

---
updated-dependencies:
- dependency-name: futures
  dependency-version: 0.3.32
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 00:48:08 +00:00
link2xt
8df9b9e4d9 refactor(pgp): do not use legacy key ID except for IssuerKeyId subpacket 2026-02-28 16:27:00 +00:00
link2xt
692e1019b0 refactor: remove KeyPair type
There is no need to store copy of public key 
next to the secret key because public key is a subset of the secret key
and can be obtained by using SignedSecretKey.public_key()
or SignedSecretKey.to_public_key().
2026-02-28 16:27:00 +00:00
link2xt
2511b03726 docs: update store_self_keypair() documentation
Since migration 107 there is no addr column in `keypairs` table.
2026-02-28 16:27:00 +00:00
link2xt
c39651a8d4 feat: do not read own public key from the database
We can always derive it from the secret key.
2026-02-28 16:27:00 +00:00
link2xt
8230336936 refactor: un-resultify KeyPair::new()
It never fails.  Clippy did not complain, likely because the function is marked as public.
2026-02-28 16:27:00 +00:00
link2xt
e1e8407905 chore: bump version to 2.44.0-dev 2026-02-27 01:16:34 +00:00
link2xt
ffce0dfc9a chore(release): prepare for 2.44.0 v2.44.0 2026-02-27 01:13:18 +00:00
dependabot[bot]
e2eec2f1f8 chore(deps): bump cachix/install-nix-action from 31.9.0 to 31.9.1
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 31.9.0 to 31.9.1.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Changelog](https://github.com/cachix/install-nix-action/blob/master/RELEASE.md)
- [Commits](4e002c8ec8...2126ae7fc5)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-version: 31.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-26 17:27:20 +00:00
link2xt
072c0061ee refactor: do not chain Autocrypt key verification to parsing
.and_then() and Ok() are unnecessary here.
2026-02-26 17:26:17 +00:00
holger krekel
cb783ffc12 feat(rpc): add startup health-check and propagate server errors
Rpc.start() now calls get_system_info() after launching the server
to verify it started successfully. If the server exits early (e.g.
due to an invalid accounts directory), the core error message from
stderr is captured and included in the raised JsonRpcError.

The reader_loop now unblocks pending RPC requests when the server
closes stdout, so callers never hang on a dead server.

Export JsonRpcError from the deltachat_rpc_client package.

Add test_early_failure verifying that Rpc.start() raises with
the actual core error message for invalid accounts directories.
2026-02-26 18:25:31 +01:00
iequidoo
af182a85a3 fix: Don't generate new timestamp for re-sent messages (#7889)
Timestamp renewal was introduced in 1dbf924c6a "feat:
chat::resend_msgs: Guarantee strictly increasing time in the Date header" so that re-sent messages
can be deduplicated on the reciver side, but the deduplication logic doesn't depend on "Date"
anymore.
2026-02-25 12:43:45 -03:00
Hocuri
7d8989a068 fix: If importing a backup fails, delete the partially-imported profile (#7885)
fix https://github.com/chatmail/core/issues/7863

`test_import_encrypted_bak_into_encrypted_acct` CFFI test fails because
it tests that trying to import an encrypted account with a wrong
passphrase into an already-encrypted database will fail, but leave the
already-encrypted database (esp, leave it with the same password).

But in order to reset the database after a failed login attempt, I'm
using this code:

```rust
        context.sql.close().await;
        fs::remove_file(context.sql.dbfile.as_path())
            .await
            .log_err(context)
            .ok();
        context
            .sql
            .open(context, "".to_string()) // <-- NOTE THIS LINE
            .await
            .log_err(context)
            .ok();
```

We're not remembering the password, so, we can't just pass the correct
password there.

Since password-protected databases are not really supported anyways, we
decided to just skip the test.

I also tried two tricks for deleting everything [found on
Stackoverflow](https://stackoverflow.com/questions/525512/drop-all-tables-command),
but neither of them managed to actually reset the database (i.e. they
led to a failed Rust test, because asserting
`!context2.is_configured().await?` failed):

```rust
        context
            .sql
            .call_write(|conn| {
                let mut stmt = conn.prepare(
                    "select 'drop table ' || name || ';' from sqlite_master where type = 'table';",
                )?;
                let mut iter = stmt.query(())?;
                while iter.next()?.is_some() {}
                Ok(())
            })
            .await
            .log_err(context)
            .ok();
        context
            .sql
            .run_migrations(context)
            .await
            .log_err(context)
            .ok();
```

```rust
        context
            .sql
            .transaction(|t| {
                t.execute_batch(
                    "
PRAGMA writable_schema = 1;
delete from sqlite_master where type in ('table', 'index', 'trigger');
PRAGMA writable_schema = 0",
                )?;
                Ok(())
            })
            .await
            .log_err(context)
            .ok();
        context
            .sql
            .run_migrations(context)
            .await
            .log_err(context)
            .ok();
```

---------

Co-authored-by: l <link2xt@testrun.org>
2026-02-25 16:25:33 +01:00
Hocuri
d7bf10d7a4 refactor: Move migrations to the end of the file (#7895)
I sometimes find it hard to find the most recent migration.

This PR moves the migrations::run() function to the end of the file, so
that it's easy to find the most recent migration - it's at the end of
the file.

There are no changes except for switching the ordering of the functions.
2026-02-25 13:13:41 +01:00
holger krekel
f1e90c73cd chore: add dev-version bump instructions to RELEASE.md (bumping to 2.44.0-dev) 2026-02-25 10:30:42 +01:00
holger krekel
c39d2f42ef fix: tolerate empty existing directory in Accounts::new() (#7886) 2026-02-24 09:22:19 +01:00
link2xt
e60f4ff70a docs(RELEASE.md): add section about dealing with antivirus false positives 2026-02-23 23:21:14 +00:00
iequidoo
ba64d8d19b feat: Send webxdc name instead of raw file name in pre-messages. Display it in summary (#7790)
The webxdc file name itself isn't informative for users. Still, send and display it if the webxdc
manifest can't be parsed, it's better than sending "Mini App" and this isn't a normal case anyway.
2026-02-23 15:20:53 -03:00
iequidoo
4041d9a54e feat: Add 📱 to all webxdc summaries (#7790)
This can be done now as Desktop doesn't prepend icons from webxdc archives to summaries anymore.
2026-02-23 15:20:53 -03:00
link2xt
bbf9a86bce perf: batched event reception 2026-02-23 15:58:06 +00:00
Hocuri
cdb0e0ce29 fix: Make clicking on broadcast member-added messages work always (#7882)
fix #7876
2026-02-23 15:44:52 +01:00
link2xt
0e7f3c8238 test: fail fast when CHATMAIL_DOMAIN is unset
This code does not expect the variable to be unset,
so use indexing to fail with KeyError instead.
Otherwise getenv() returns None which is then converted to "none" string by formatting
and the test only fails because of connection attempts to "none" domain.
2026-02-23 14:44:16 +00:00
link2xt
16c85a9585 chore(cargo): update async-native-tls from 0.5.0 to 0.6.0 2026-02-23 14:44:16 +00:00
Hocuri
ff7023580f fix: If there was no chat description, and it's set to be an empty string, don't send out a "chat description changed" message (#7879)
fix #7877

The bug was: If there is no chat description, and the chat description
is set to an empty string, the INSERT statement inserted a row with an
empty chat description, and therefore from the view of the INSERT
statement, something changed.

This PR fixes this by simply loading the chat description first, and
comparing it.
2026-02-23 12:37:48 +01:00
B. Petersen
58d457140e fix: add cffi type for "Description changed" info message 2026-02-21 23:11:30 +01:00
biörn
b531a3c012 fix: chat-description-changed text in old clients (#7870)
instead of Alice saying to Bob "You changed the chat description",
we now say "[Chat description changed, please update ...]

i was also considering to say "[Chat description changed to:\n\n...]"
but then there is no incentive for ppl to update, and chat descriptions
for chat creation would still be missing. and this is probably far more
often used.

successor of https://github.com/chatmail/core/pull/7829
2026-02-21 21:07:41 +00:00
link2xt
f055f6226c feat: add context to message loading failures 2026-02-21 11:48:38 +00:00
link2xt
e95dca87bd feat: add backup versions to the importing error message
This would have helped debugging the problem reported at
<https://support.delta.chat/t/backup-too-new-please-update-delta-chat-message/4761>
2026-02-19 15:28:41 +00:00
B. Petersen
0d9442458a fix: add missing group description strings to cffi 2026-02-18 20:28:47 +01:00
link2xt
60cf483270 refactor(http): saturating addition to calculate cache expiration timestamp 2026-02-17 16:01:16 +00:00
link2xt
598d759b8d refactor(imex): check for overflow when adding blob size
Cannot happen without custom filesystem or sparse files,
but removes clippy lint.
2026-02-17 16:01:16 +00:00
link2xt
10b93b3943 refactor: enable clippy::arithmetic_side_effects lint 2026-02-17 16:01:16 +00:00
link2xt
5a06d08613 fix(imex): do not call set_config before running SQL migrations (#7851)
`set_config` expects that migrations have already been run and fails
if backup is old and e.g. does not have `transports` table.
2026-02-17 15:39:42 +00:00
link2xt
85de4bf678 build(git-cliff): do not capitalize the first letter of commit message
Some commit messages start with the function names
for additional context and these should not be capitalized.
2026-02-17 15:21:08 +00:00
link2xt
624fc394d9 feat: improve logging of connection failures
Previously it was not always clear whether IMAP or SMTP connection
failed and what was the endpoint used.
2026-02-17 15:14:36 +00:00
link2xt
9deba0cf2a chore(release): prepare for 2.43.0 v2.43.0 2026-02-17 13:28:19 +00:00
dependabot[bot]
b95d28b2d9 chore(deps): bump astral-sh/setup-uv from 7.1.6 to 7.3.0
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.1.6 to 7.3.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](681c641aba...eac588ad8d)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 7.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-17 04:11:37 +00:00
link2xt
2131f5e9c0 fix: assign iroh gossip topic to pre-message when post-message is received
Iroh-Gossip-Topic is sent in a post-message. Post-message goes to trash,
so topic should be associated with the existing pre-message that is
updated rather than with the post-message.
2026-02-17 02:54:39 +00:00
Hocuri
a63f695b85 test: Fix flaky test_transport_synchronization (#7850)
Fix https://github.com/chatmail/core/issues/7835.

The problem was most probably:
- `ac1_clone` receives the sync message, sends `TRANSPORTS_MODIFIED`
event, and launches a task that will restart IO
- After IO was stopped, but before it is started again,
`ac1_clone.add_transport_from_qr(qr)` is called
- this check fails:
  ```rust
        ensure!(
            !self.scheduler.is_running().await,
            "cannot configure, already running"
        );
  ```
2026-02-14 09:24:58 +00:00
link2xt
de25eb90ff chore(cargo): update keccak from 0.1.5 to 0.1.6
0.1.5 is yanked and cargo-deny complains
2026-02-14 07:20:42 +00:00
Hocuri
3fdda6f3b8 feat: Group and broadcast channel descriptions (#7829)
fix https://github.com/chatmail/core/issues/7766

Implementation notes:

- Descriptions are only sent with member additions, when the description
is changed, and when promoting a previously-unpromoted group, in order
not to waste bandwith.
- Descriptions are not loaded everytime a chat object is loaded, because
they are only needed for the profile. Instead, they are in their own
table, and can be loaded with their own JsonRPC call.

---------

Co-authored-by: iequidoo <117991069+iequidoo@users.noreply.github.com>
2026-02-10 21:28:12 +00:00