Compare commits

..

25 Commits

Author SHA1 Message Date
link2xt
e5dbbf4cfa ci: use Ubuntu 22.04 runner to test Python 3.7 2025-01-09 12:37:58 +00:00
link2xt
7f7c76f706 test: use assert_eq! to compare chatlist length 2025-01-05 23:44:34 +00:00
link2xt
3fe9a7b17f refactor: use let..else 2025-01-05 23:44:28 +00:00
link2xt
fff4020013 chore(release): prepare for 1.153.0 2025-01-05 09:08:23 +00:00
link2xt
4ffc0ca047 refactor: don't ignore get_for_contact errors 2025-01-05 02:52:19 +00:00
link2xt
3d19996f34 test: fix test_logged_ac_process_ffi_failure flakiness
This test keeps failing on macOS CI,
capturing events like `DC_EVENT_ACCOUNTS_ITEM_CHANGED`
before FailPlugin is setup.
These CI runners likely get less resources
because there is a limited number of them,
and this triggers this race condition.

Race is fixed by setting up fail plugin
before starting to capture events.
2025-01-05 01:36:09 +00:00
link2xt
7e5cec66ba refactor: simplify self_sent condition 2025-01-05 00:36:10 +00:00
link2xt
a7eab13ad6 test: message with empty To: field should have a valid to_id 2025-01-05 00:36:10 +00:00
link2xt
d26a27484b fix: default to_id to self instead of 0
If message has empty `To` field
it is a self-sent message like a message
in Saved Messages chat or a sync message.
2025-01-05 00:36:10 +00:00
link2xt
ed2a3a76b4 test: messages without recipients are assigned to self chat
Previously such messages were assigned to trash.
2025-01-05 00:36:10 +00:00
link2xt
49f5523b67 fix: allow empty To field for self-sent messages
Currently Delta Chat puts self address in the To field
to avoid the To field being empty.
There is a plan to put empty `hidden-recipients`
group there, this fix prepares the receiver for such messages.
2025-01-05 00:36:10 +00:00
link2xt
548fadc84a fix: prioritize mailing list over self-sent messages
New Delta Chat is going to send self-sent messages
with undisclosed recipients instead of placing self into the `To` field.
To avoid assigning broadcast list messages to Saved Messages chat,
we should check the mailing list headers
before attempting to assign to Saved Messages.
2025-01-05 00:36:10 +00:00
iequidoo
2bce4466d7 fix: Prefer to encrypt if E2eeEnabled even if peers have EncryptPreference::NoPreference
First of all, chatmail servers normally forbid to send unencrypted mail, so if we know the peer's
key, we should encrypt to it. Chatmail setups have `E2eeEnabled=1` by default and this isn't
possible to change in UIs, so this change fixes the chatmail case. Additionally, for chatmail, if a
peer has `EncryptPreference::Reset`, let's handle it as `EncryptPreference::NoPreference` for the
reason above. Still, if `E2eeEnabled` is 0 for a chatmail setup somehow, e.g. the user set it via
environment, let's assume that the user knows what they do and ignore `IsChatmail` flag.

NB:
- If we don't know the peer's key, we should try to send an unencrypted message as before for a
  chatmail setup.
- This change doesn't remove the "majority rule", but now the majority with
  `EncryptPreference::NoPreference` can't disable encryption if the local preference is `Mutual`. To
  disable encryption, some peer should have a missing peerstate or, for the non-chatmail case, the
  majority should have `EncryptPreference::Reset`.
2025-01-04 20:16:38 -03:00
link2xt
f31e86d203 chore: lockfile update 2025-01-04 06:49:46 +00:00
link2xt
8ec098210e fix: update shadowsocks crate to 1.22.0 to avoid panic when parsing some QR codes
`aead-cipher` feature has become optional
and is disabled by default.
We enable it to avoid breaking compatibility.
2025-01-03 23:56:47 +00:00
dependabot[bot]
62e22286bb chore(cargo): bump testdir from 0.9.1 to 0.9.3
Bumps [testdir](https://github.com/flub/testdir) from 0.9.1 to 0.9.3.
- [Changelog](https://github.com/flub/testdir/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flub/testdir/compare/v0.9.1...v0.9.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-03 20:50:30 -03:00
iequidoo
c596bfc44e refactor: add_parts: Remove excessive is_mdn checks 2025-01-03 00:44:55 -03:00
dependabot[bot]
379b31835b Merge pull request #6395 from deltachat/dependabot/cargo/serde-1.0.217 2025-01-03 02:27:19 +00:00
dependabot[bot]
5a69d9c355 chore(cargo): bump serde from 1.0.215 to 1.0.217
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.215 to 1.0.217.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.215...v1.0.217)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-03 01:57:45 +00:00
dependabot[bot]
e689db4376 Merge pull request #6387 from deltachat/dependabot/cargo/serde_json-1.0.134 2025-01-03 01:56:37 +00:00
dependabot[bot]
2d173512af Merge pull request #6396 from deltachat/dependabot/cargo/rustls-0.23.20 2025-01-03 01:56:18 +00:00
dependabot[bot]
adddc8e4ad Merge pull request #6388 from deltachat/dependabot/cargo/tokio-1.42.0 2025-01-03 01:23:31 +00:00
dependabot[bot]
8a27c3edf0 chore(cargo): bump rustls from 0.23.19 to 0.23.20
Bumps [rustls](https://github.com/rustls/rustls) from 0.23.19 to 0.23.20.
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.19...v/0.23.20)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-03 00:04:17 +00:00
dependabot[bot]
7164786165 chore(cargo): bump tokio from 1.41.1 to 1.42.0
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.41.1 to 1.42.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.41.1...tokio-1.42.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-02 23:50:08 +00:00
dependabot[bot]
0cfd84d803 chore(cargo): bump serde_json from 1.0.133 to 1.0.134
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.133 to 1.0.134.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.133...v1.0.134)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-02 23:47:43 +00:00
25 changed files with 378 additions and 156 deletions

View File

@@ -226,7 +226,11 @@ jobs:
# Minimum Supported Python Version = 3.7
# This is the minimum version for which manylinux Python wheels are
# built. Test it with minimum supported Rust version.
- os: ubuntu-latest
#
# Running on Ubuntu 22.04
# because Ubuntu 24.04 runner does not support Python 3.7:
# https://github.com/actions/setup-python/issues/962
- os: ubuntu-22.04
python: 3.7
runs-on: ${{ matrix.os }}
@@ -238,7 +242,7 @@ jobs:
- name: Download libdeltachat.a
uses: actions/download-artifact@v4
with:
name: ${{ matrix.os }}-libdeltachat.a
name: ${{ matrix.os == 'ubuntu-22.04' && 'ubuntu-latest' || matrix.os }}-libdeltachat.a
path: target/debug
- name: Install python
@@ -278,7 +282,11 @@ jobs:
python: pypy3.10
# Minimum Supported Python Version = 3.7
- os: ubuntu-latest
#
# Running on Ubuntu 22.04
# because Ubuntu 24.04 runner does not support Python 3.7:
# https://github.com/actions/setup-python/issues/962
- os: ubuntu-22.04
python: 3.7
runs-on: ${{ matrix.os }}

View File

@@ -1,5 +1,48 @@
# Changelog
## [1.153.0] - 2025-01-05
### Features / Changes
- Remove "jobs" from imap_markseen if folder doesn't exist ([#5870](https://github.com/deltachat/deltachat-core-rust/pull/5870)).
- Delete `vg-request-with-auth` from IMAP after processing ([#6208](https://github.com/deltachat/deltachat-core-rust/pull/6208)).
### API-Changes
- Add `IncomingWebxdcNotify.chat_id` ([#6356](https://github.com/deltachat/deltachat-core-rust/pull/6356)).
- rpc-client: Add INCOMING_REACTION to const.EventType ([#6349](https://github.com/deltachat/deltachat-core-rust/pull/6349)).
### Documentation
- Viewtype::Sticker may be changed to Image and how to disable that ([#6352](https://github.com/deltachat/deltachat-core-rust/pull/6352)).
### Fixes
- Never change Viewtype::Sticker to Image if file has non-image extension ([#6352](https://github.com/deltachat/deltachat-core-rust/pull/6352)).
- Change BccSelf default to 0 for chatmail ([#6340](https://github.com/deltachat/deltachat-core-rust/pull/6340)).
- Mark holiday notice messages as bot-generated.
- Don't treat location-only and sync messages as bot ones ([#6357](https://github.com/deltachat/deltachat-core-rust/pull/6357)).
- Update shadowsocks crate to 1.22.0 to avoid panic when parsing some QR codes.
- Prefer to encrypt if E2eeEnabled even if peers have EncryptPreference::NoPreference.
- Prioritize mailing list over self-sent messages.
- Allow empty `To` field for self-sent messages.
- Default `to_id` to self instead of 0.
### Refactor
- Remove unused parameter and return value from `build_body_file(…)` ([#6369](https://github.com/deltachat/deltachat-core-rust/pull/6369)).
- Deprecate Param::ErroneousE2ee.
- Add `emit_msgs_changed_without_msg_id`.
- Add_parts: Remove excessive `is_mdn` checks.
- Simplify `self_sent` condition.
- Don't ignore get_for_contact errors.
### Tests
- Messages without recipients are assigned to self chat.
- Message with empty To: field should have a valid to_id.
- Fix `test_logged_ac_process_ffi_failure` flakiness.
## [1.152.2] - 2024-12-24
### Features / Changes
@@ -5541,3 +5584,4 @@ https://github.com/deltachat/deltachat-core-rust/pulls?q=is%3Apr+is%3Aclosed
[1.152.0]: https://github.com/deltachat/deltachat-core-rust/compare/v1.151.6..v1.152.0
[1.152.1]: https://github.com/deltachat/deltachat-core-rust/compare/v1.152.0..v1.152.1
[1.152.2]: https://github.com/deltachat/deltachat-core-rust/compare/v1.152.1..v1.152.2
[1.153.0]: https://github.com/deltachat/deltachat-core-rust/compare/v1.152.2..v1.153.0

172
Cargo.lock generated
View File

@@ -219,7 +219,7 @@ dependencies = [
"nom",
"num-traits",
"rusticata-macros",
"thiserror",
"thiserror 1.0.69",
"time 0.3.36",
]
@@ -315,7 +315,7 @@ dependencies = [
"pin-utils",
"self_cell",
"stop-token",
"thiserror",
"thiserror 1.0.69",
"tokio",
]
@@ -335,7 +335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9343dc5acf07e79ff82d0c37899f079db3534d99f189a1837c8e549c99405bec"
dependencies = [
"native-tls",
"thiserror",
"thiserror 1.0.69",
"tokio",
"url",
]
@@ -363,7 +363,7 @@ dependencies = [
"log",
"nom",
"pin-project",
"thiserror",
"thiserror 1.0.69",
"tokio",
]
@@ -388,7 +388,7 @@ dependencies = [
"crc32fast",
"futures-lite 2.5.0",
"pin-project",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tokio-util",
]
@@ -1306,7 +1306,7 @@ dependencies = [
[[package]]
name = "deltachat"
version = "1.152.2"
version = "1.153.0"
dependencies = [
"anyhow",
"async-broadcast",
@@ -1381,7 +1381,7 @@ dependencies = [
"tempfile",
"testdir",
"textwrap",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tokio-io-timeout",
"tokio-rustls",
@@ -1407,7 +1407,7 @@ dependencies = [
[[package]]
name = "deltachat-jsonrpc"
version = "1.152.2"
version = "1.153.0"
dependencies = [
"anyhow",
"async-channel 2.3.1",
@@ -1432,7 +1432,7 @@ dependencies = [
[[package]]
name = "deltachat-repl"
version = "1.152.2"
version = "1.153.0"
dependencies = [
"anyhow",
"deltachat",
@@ -1448,7 +1448,7 @@ dependencies = [
[[package]]
name = "deltachat-rpc-server"
version = "1.152.2"
version = "1.153.0"
dependencies = [
"anyhow",
"deltachat",
@@ -1477,7 +1477,7 @@ dependencies = [
[[package]]
name = "deltachat_ffi"
version = "1.152.2"
version = "1.153.0"
dependencies = [
"anyhow",
"deltachat",
@@ -1488,7 +1488,7 @@ dependencies = [
"once_cell",
"rand 0.8.5",
"serde_json",
"thiserror",
"thiserror 1.0.69",
"tokio",
"yerpc",
]
@@ -1717,6 +1717,27 @@ version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]]
name = "dynosaur"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92fac44672fabad44990176319b9e94393f3a38b960b5ca2af6cd90f5ecd1497"
dependencies = [
"dynosaur_derive",
"trait-variant",
]
[[package]]
name = "dynosaur_derive"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16c187d1e575ef546d24f0fcd7701cc04abfe6b5e7e2758aabc450b99e835ac3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.94",
]
[[package]]
name = "eax"
version = "0.5.0"
@@ -1839,7 +1860,7 @@ dependencies = [
"hex",
"lazy_static",
"regex",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@@ -2087,7 +2108,7 @@ dependencies = [
"anyhow",
"async-trait",
"log",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tokio-stream",
]
@@ -2607,7 +2628,7 @@ dependencies = [
"ipnet",
"once_cell",
"rand 0.8.5",
"thiserror",
"thiserror 1.0.69",
"time 0.3.36",
"tinyvec",
"tokio",
@@ -2631,7 +2652,7 @@ dependencies = [
"rand 0.8.5",
"resolv-conf",
"smallvec",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tracing",
]
@@ -3151,7 +3172,7 @@ dependencies = [
"rand_core 0.6.4",
"serde",
"ssh-key",
"thiserror",
"thiserror 1.0.69",
"ttl_cache",
"url",
"zeroize",
@@ -3281,7 +3302,7 @@ dependencies = [
"strum",
"stun-rs",
"surge-ping",
"thiserror",
"thiserror 1.0.69",
"time 0.3.36",
"tokio",
"tokio-rustls",
@@ -3313,7 +3334,7 @@ dependencies = [
"rustc-hash 2.0.0",
"rustls",
"socket2",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tracing",
]
@@ -3331,7 +3352,7 @@ dependencies = [
"rustls",
"rustls-platform-verifier",
"slab",
"thiserror",
"thiserror 1.0.69",
"tinyvec",
"tracing",
]
@@ -3407,7 +3428,7 @@ dependencies = [
"combine",
"jni-sys",
"log",
"thiserror",
"thiserror 1.0.69",
"walkdir",
]
@@ -3627,7 +3648,7 @@ dependencies = [
"serde_bencode",
"serde_bytes",
"sha1_smol",
"thiserror",
"thiserror 1.0.69",
"tracing",
]
@@ -3798,7 +3819,7 @@ dependencies = [
"anyhow",
"byteorder",
"paste",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@@ -3812,7 +3833,7 @@ dependencies = [
"log",
"netlink-packet-core",
"netlink-sys",
"thiserror",
"thiserror 1.0.69",
"tokio",
]
@@ -3850,7 +3871,7 @@ dependencies = [
"rtnetlink",
"serde",
"socket2",
"thiserror",
"thiserror 1.0.69",
"time 0.3.36",
"tokio",
"tracing",
@@ -4294,7 +4315,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8"
dependencies = [
"memchr",
"thiserror",
"thiserror 1.0.69",
"ucd-trie",
]
@@ -4342,7 +4363,7 @@ dependencies = [
"aes-gcm",
"aes-kw",
"argon2",
"base64 0.22.1",
"base64 0.21.7",
"bitfield",
"block-padding",
"blowfish",
@@ -4392,7 +4413,7 @@ dependencies = [
"sha3",
"signature",
"smallvec",
"thiserror",
"thiserror 1.0.69",
"twofish",
"x25519-dalek",
"x448",
@@ -4448,7 +4469,7 @@ dependencies = [
"mainline",
"self_cell",
"simple-dns",
"thiserror",
"thiserror 1.0.69",
"tracing",
"ureq",
"wasm-bindgen",
@@ -4617,7 +4638,7 @@ dependencies = [
"serde",
"smallvec",
"socket2",
"thiserror",
"thiserror 1.0.69",
"time 0.3.36",
"tokio",
"tokio-util",
@@ -4895,7 +4916,7 @@ dependencies = [
"quinn-udp",
"rustc-hash 1.1.0",
"rustls",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tracing",
]
@@ -4912,7 +4933,7 @@ dependencies = [
"rustc-hash 2.0.0",
"rustls",
"slab",
"thiserror",
"thiserror 1.0.69",
"tinyvec",
"tracing",
]
@@ -5116,7 +5137,7 @@ checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
dependencies = [
"getrandom 0.2.12",
"libredox",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@@ -5309,7 +5330,7 @@ dependencies = [
"netlink-proto",
"netlink-sys",
"nix 0.26.4",
"thiserror",
"thiserror 1.0.69",
"tokio",
]
@@ -5384,9 +5405,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.19"
version = "0.23.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1"
checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b"
dependencies = [
"log",
"once_cell",
@@ -5636,9 +5657,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.215"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
@@ -5673,9 +5694,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.215"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
@@ -5695,9 +5716,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.133"
version = "1.0.134"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
dependencies = [
"itoa",
"memchr",
@@ -5808,17 +5829,17 @@ dependencies = [
[[package]]
name = "shadowsocks"
version = "1.21.0"
version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ecb3780dfbc654de9383758015b9bb95c6e32fecace36ebded09d67e854d130"
checksum = "1678a9acd37add020f89bfe05d45b9b8a6e8ad5d09f54ac2af3e0dcf0557b481"
dependencies = [
"aes",
"async-trait",
"base64 0.22.1",
"blake3",
"byte_string",
"bytes",
"cfg-if",
"dynosaur",
"futures",
"libc",
"log",
@@ -5834,18 +5855,19 @@ dependencies = [
"shadowsocks-crypto",
"socket2",
"spin",
"thiserror",
"thiserror 2.0.9",
"tokio",
"tokio-tfo",
"trait-variant",
"url",
"windows-sys 0.59.0",
]
[[package]]
name = "shadowsocks-crypto"
version = "0.5.5"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e49ecfad8b27f3df28848af11f08aa10df0c6b74b45748131753913be23373"
checksum = "bc77ecb3a97509d22751b76665894fcffad2d10df8758f4e3f20c92ccde6bf4f"
dependencies = [
"aes",
"aes-gcm",
@@ -6136,7 +6158,7 @@ dependencies = [
"pnet_packet",
"rand 0.8.5",
"socket2",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tracing",
]
@@ -6253,12 +6275,13 @@ dependencies = [
[[package]]
name = "testdir"
version = "0.9.1"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee79e927b64d193f5abb60d20a0eb56be0ee5a242fdeb8ce3bf054177006de52"
checksum = "c9ffa013be124f7e8e648876190de818e3a87088ed97ccd414a398b403aec8c8"
dependencies = [
"anyhow",
"backtrace",
"cargo-platform",
"cargo_metadata",
"once_cell",
"sysinfo",
@@ -6282,7 +6305,16 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc"
dependencies = [
"thiserror-impl 2.0.9",
]
[[package]]
@@ -6296,6 +6328,17 @@ dependencies = [
"syn 2.0.94",
]
[[package]]
name = "thiserror-impl"
version = "2.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.94",
]
[[package]]
name = "thread_local"
version = "1.1.8"
@@ -6385,9 +6428,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.41.1"
version = "1.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"
checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
dependencies = [
"backtrace",
"bytes",
@@ -6498,7 +6541,7 @@ dependencies = [
"http 1.1.0",
"httparse",
"js-sys",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tokio-tungstenite",
"wasm-bindgen",
@@ -6645,6 +6688,17 @@ dependencies = [
"tracing-log",
]
[[package]]
name = "trait-variant"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.94",
]
[[package]]
name = "try-lock"
version = "0.2.5"
@@ -6674,7 +6728,7 @@ dependencies = [
"log",
"rand 0.8.5",
"sha1",
"thiserror",
"thiserror 1.0.69",
"url",
"utf-8",
]
@@ -7003,7 +7057,7 @@ dependencies = [
"event-listener 4.0.3",
"futures-util",
"parking_lot",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@@ -7337,7 +7391,7 @@ dependencies = [
"futures",
"log",
"serde",
"thiserror",
"thiserror 1.0.69",
"windows 0.52.0",
]
@@ -7389,7 +7443,7 @@ dependencies = [
"nom",
"oid-registry",
"rusticata-macros",
"thiserror",
"thiserror 1.0.69",
"time 0.3.36",
]

View File

@@ -1,6 +1,6 @@
[package]
name = "deltachat"
version = "1.152.2"
version = "1.153.0"
edition = "2021"
license = "MPL-2.0"
rust-version = "1.77"
@@ -86,14 +86,14 @@ regex = { workspace = true }
rusqlite = { workspace = true, features = ["sqlcipher"] }
rust-hsluv = "0.1"
rustls-pki-types = "1.10.1"
rustls = { version = "0.23.19", default-features = false }
rustls = { version = "0.23.20", default-features = false }
sanitize-filename = { workspace = true }
serde_json = { workspace = true }
serde_urlencoded = "0.7.1"
serde = { workspace = true, features = ["derive"] }
sha-1 = "0.10"
sha2 = "0.10"
shadowsocks = { version = "1.21.0", default-features = false, features = ["aead-cipher-2022"] }
shadowsocks = { version = "1.22.0", default-features = false, features = ["aead-cipher", "aead-cipher-2022"] }
smallvec = "1.13.2"
strum = "0.26"
strum_macros = "0.26"
@@ -120,7 +120,7 @@ nu-ansi-term = { workspace = true }
pretty_assertions = "1.4.1"
proptest = { version = "1", default-features = false, features = ["std"] }
tempfile = { workspace = true }
testdir = "0.9.0"
testdir = "0.9.3"
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
[workspace]

View File

@@ -1,6 +1,6 @@
[package]
name = "deltachat_ffi"
version = "1.152.2"
version = "1.153.0"
description = "Deltachat FFI"
edition = "2018"
readme = "README.md"

View File

@@ -1,6 +1,6 @@
[package]
name = "deltachat-jsonrpc"
version = "1.152.2"
version = "1.153.0"
description = "DeltaChat JSON-RPC API"
edition = "2021"
default-run = "deltachat-jsonrpc-server"

View File

@@ -58,5 +58,5 @@
},
"type": "module",
"types": "dist/deltachat.d.ts",
"version": "1.152.2"
"version": "1.153.0"
}

View File

@@ -1,6 +1,6 @@
[package]
name = "deltachat-repl"
version = "1.152.2"
version = "1.153.0"
license = "MPL-2.0"
edition = "2021"
repository = "https://github.com/deltachat/deltachat-core-rust"

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "deltachat-rpc-client"
version = "1.152.2"
version = "1.153.0"
description = "Python client for Delta Chat core JSON-RPC interface"
classifiers = [
"Development Status :: 5 - Production/Stable",

View File

@@ -1,6 +1,6 @@
[package]
name = "deltachat-rpc-server"
version = "1.152.2"
version = "1.153.0"
description = "DeltaChat JSON-RPC server"
edition = "2021"
readme = "README.md"

View File

@@ -15,5 +15,5 @@
},
"type": "module",
"types": "index.d.ts",
"version": "1.152.2"
"version": "1.153.0"
}

View File

@@ -51,6 +51,8 @@ skip = [
{ name = "regex-syntax", version = "0.6.29" },
{ name = "sync_wrapper", version = "0.1.2" },
{ name = "syn", version = "1.0.109" },
{ name = "thiserror-impl", version = "1.0.69" },
{ name = "thiserror", version = "1.0.69" },
{ name = "time", version = "<0.3" },
{ name = "wasi", version = "<0.11" },
{ name = "windows_aarch64_gnullvm", version = "<0.52" },

View File

@@ -55,5 +55,5 @@
"test:mocha": "mocha node/test/test.mjs --growl --reporter=spec --bail --exit"
},
"types": "node/dist/index.d.ts",
"version": "1.152.2"
"version": "1.153.0"
}

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "deltachat"
version = "1.152.2"
version = "1.153.0"
description = "Python bindings for the Delta Chat Core library using CFFI against the Rust-implemented libdeltachat"
readme = "README.rst"
requires-python = ">=3.7"

View File

@@ -1253,7 +1253,10 @@ def test_no_old_msg_is_fresh(acfactory, lp):
def test_prefer_encrypt(acfactory, lp):
"""Test quorum rule for encryption preference in 1:1 and group chat."""
ac1, ac2, ac3 = acfactory.get_online_accounts(3)
ac1 = acfactory.new_online_configuring_account(fix_is_chatmail=True)
ac2 = acfactory.new_online_configuring_account(fix_is_chatmail=True)
ac3 = acfactory.new_online_configuring_account(fix_is_chatmail=True)
acfactory.bring_accounts_online()
ac1.set_config("e2ee_enabled", "0")
ac2.set_config("e2ee_enabled", "1")
ac3.set_config("e2ee_enabled", "0")
@@ -1276,7 +1279,8 @@ def test_prefer_encrypt(acfactory, lp):
lp.sec("ac2: sending message to ac1")
chat2 = ac2.create_chat(ac1)
msg2 = chat2.send_text("message2")
assert not msg2.is_encrypted()
# Own preference is `Mutual` and we have the peer's key.
assert msg2.is_encrypted()
ac1._evtracker.wait_next_incoming_message()
lp.sec("ac1: sending message to group chat with ac2 and ac3")
@@ -1292,8 +1296,8 @@ def test_prefer_encrypt(acfactory, lp):
ac3.set_config("e2ee_enabled", "1")
chat3 = ac3.create_chat(ac1)
msg4 = chat3.send_text("message4")
# ac1 still does not prefer encryption
assert not msg4.is_encrypted()
# Own preference is `Mutual` and we have the peer's key.
assert msg4.is_encrypted()
ac1._evtracker.wait_next_incoming_message()
lp.sec("ac1: sending another message to group chat with ac2 and ac3")

View File

@@ -212,11 +212,16 @@ def test_logged_ac_process_ffi_failure(acfactory):
0 / 0
cap = Queue()
ac1.log = cap.put
# Make sure the next attempt to log an event fails.
ac1.add_account_plugin(FailPlugin())
# Start capturing events.
ac1.log = cap.put
# cause any event eg contact added/changed
ac1.create_contact("something@example.org")
res = cap.get(timeout=600)
res = cap.get(timeout=10)
assert "ac_process_ffi_event" in res
assert "ZeroDivisionError" in res
assert "Traceback" in res

View File

@@ -1 +1 @@
2024-12-24
2025-01-05

View File

@@ -550,7 +550,7 @@ mod tests {
let chats = Chatlist::try_load(&t, 0, Some("is:unread"), None)
.await
.unwrap();
assert!(chats.len() == 1);
assert_eq!(chats.len(), 1);
let chats = Chatlist::try_load(&t, DC_GCL_ARCHIVED_ONLY, None, None)
.await
@@ -576,7 +576,7 @@ mod tests {
.unwrap();
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
assert!(chats.len() == 3);
assert_eq!(chats.len(), 3);
assert!(!Chat::load_from_db(&t, chats.get_chat_id(0).unwrap())
.await
.unwrap()
@@ -585,7 +585,7 @@ mod tests {
let chats = Chatlist::try_load(&t, DC_GCL_FOR_FORWARDING, None, None)
.await
.unwrap();
assert!(chats.len() == 2); // device chat cannot be written and is skipped on forwarding
assert_eq!(chats.len(), 2); // device chat cannot be written and is skipped on forwarding
assert!(Chat::load_from_db(&t, chats.get_chat_id(0).unwrap())
.await
.unwrap()
@@ -597,7 +597,7 @@ mod tests {
let chats = Chatlist::try_load(&t, DC_GCL_FOR_FORWARDING, None, None)
.await
.unwrap();
assert!(chats.len() == 1);
assert_eq!(chats.len(), 1);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]

View File

@@ -40,20 +40,17 @@ impl EncryptHelper {
/// Determines if we can and should encrypt.
///
/// For encryption to be enabled, `e2ee_guaranteed` should be true, or strictly more than a half
/// of peerstates should prefer encryption. Own preference is counted equally to peer
/// preferences, even if message copy is not sent to self.
///
/// `e2ee_guaranteed` should be set to true for replies to encrypted messages (as required by
/// Autocrypt Level 1, version 1.1) and for messages sent in protected groups.
///
/// Returns an error if `e2ee_guaranteed` is true, but one or more keys are missing.
pub fn should_encrypt(
pub(crate) async fn should_encrypt(
&self,
context: &Context,
e2ee_guaranteed: bool,
peerstates: &[(Option<Peerstate>, String)],
) -> Result<bool> {
let is_chatmail = context.is_chatmail().await?;
let mut prefer_encrypt_count = if self.prefer_encrypt == EncryptPreference::Mutual {
1
} else {
@@ -64,10 +61,15 @@ impl EncryptHelper {
Some(peerstate) => {
let prefer_encrypt = peerstate.prefer_encrypt;
info!(context, "Peerstate for {addr:?} is {prefer_encrypt}.");
match peerstate.prefer_encrypt {
EncryptPreference::NoPreference | EncryptPreference::Reset => {}
EncryptPreference::Mutual => prefer_encrypt_count += 1,
};
if match peerstate.prefer_encrypt {
EncryptPreference::NoPreference | EncryptPreference::Reset => {
(peerstate.prefer_encrypt != EncryptPreference::Reset || is_chatmail)
&& self.prefer_encrypt == EncryptPreference::Mutual
}
EncryptPreference::Mutual => true,
} {
prefer_encrypt_count += 1;
}
}
None => {
let msg = format!("Peerstate for {addr:?} missing, cannot encrypt");
@@ -170,9 +172,11 @@ pub async fn ensure_secret_key_exists(context: &Context) -> Result<()> {
#[cfg(test)]
mod tests {
use super::*;
use crate::chat::send_text_msg;
use crate::key::DcKey;
use crate::message::{Message, Viewtype};
use crate::param::Param;
use crate::receive_imf::receive_imf;
use crate::test_utils::{bob_keypair, TestContext, TestContextManager};
mod ensure_secret_key_exists {
@@ -320,29 +324,109 @@ Sent with my Delta Chat Messenger: https://delta.chat";
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_should_encrypt() {
async fn test_should_encrypt() -> Result<()> {
let t = TestContext::new_alice().await;
assert!(t.get_config_bool(Config::E2eeEnabled).await?);
let encrypt_helper = EncryptHelper::new(&t).await.unwrap();
// test with EncryptPreference::NoPreference:
// if e2ee_eguaranteed is unset, there is no encryption as not more than half of peers want encryption
let ps = new_peerstates(EncryptPreference::NoPreference);
assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap());
assert!(!encrypt_helper.should_encrypt(&t, false, &ps).unwrap());
assert!(encrypt_helper.should_encrypt(&t, true, &ps).await?);
// Own preference is `Mutual` and we have the peer's key.
assert!(encrypt_helper.should_encrypt(&t, false, &ps).await?);
// test with EncryptPreference::Reset
let ps = new_peerstates(EncryptPreference::Reset);
assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap());
assert!(!encrypt_helper.should_encrypt(&t, false, &ps).unwrap());
assert!(encrypt_helper.should_encrypt(&t, true, &ps).await?);
assert!(!encrypt_helper.should_encrypt(&t, false, &ps).await?);
// test with EncryptPreference::Mutual (self is also Mutual)
let ps = new_peerstates(EncryptPreference::Mutual);
assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap());
assert!(encrypt_helper.should_encrypt(&t, false, &ps).unwrap());
assert!(encrypt_helper.should_encrypt(&t, true, &ps).await?);
assert!(encrypt_helper.should_encrypt(&t, false, &ps).await?);
// test with missing peerstate
let ps = vec![(None, "bob@foo.bar".to_string())];
assert!(encrypt_helper.should_encrypt(&t, true, &ps).is_err());
assert!(!encrypt_helper.should_encrypt(&t, false, &ps).unwrap());
assert!(encrypt_helper.should_encrypt(&t, true, &ps).await.is_err());
assert!(!encrypt_helper.should_encrypt(&t, false, &ps).await?);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_should_encrypt_e2ee_disabled() -> Result<()> {
let t = &TestContext::new_alice().await;
t.set_config_bool(Config::E2eeEnabled, false).await?;
let encrypt_helper = EncryptHelper::new(t).await.unwrap();
let ps = new_peerstates(EncryptPreference::NoPreference);
assert!(!encrypt_helper.should_encrypt(t, false, &ps).await?);
let ps = new_peerstates(EncryptPreference::Reset);
assert!(encrypt_helper.should_encrypt(t, true, &ps).await?);
let mut ps = new_peerstates(EncryptPreference::Mutual);
// Own preference is `NoPreference` and there's no majority with `Mutual`.
assert!(!encrypt_helper.should_encrypt(t, false, &ps).await?);
// Now the majority wants to encrypt. Let's encrypt, anyway there are other cases when we
// can't send unencrypted, e.g. protected groups.
ps.push(ps[0].clone());
assert!(encrypt_helper.should_encrypt(t, false, &ps).await?);
// Test with missing peerstate.
let ps = vec![(None, "bob@foo.bar".to_string())];
assert!(encrypt_helper.should_encrypt(t, true, &ps).await.is_err());
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_chatmail_prefers_to_encrypt() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
bob.set_config_bool(Config::IsChatmail, true).await?;
let bob_chat_id = tcm
.send_recv_accept(alice, bob, "Hello from DC")
.await
.chat_id;
receive_imf(
bob,
b"From: alice@example.org\n\
To: bob@example.net\n\
Message-ID: <2222@example.org>\n\
Date: Sun, 22 Mar 3000 22:37:58 +0000\n\
\n\
Hello from another MUA\n",
false,
)
.await?;
send_text_msg(bob, bob_chat_id, "hi".to_string()).await?;
let sent_msg = bob.pop_sent_msg().await;
let msg = Message::load_from_db(bob, sent_msg.sender_msg_id).await?;
assert!(msg.get_showpadlock());
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_chatmail_can_send_unencrypted() -> Result<()> {
let mut tcm = TestContextManager::new();
let bob = &tcm.bob().await;
bob.set_config_bool(Config::IsChatmail, true).await?;
let bob_chat_id = receive_imf(
bob,
b"From: alice@example.org\n\
To: bob@example.net\n\
Message-ID: <2222@example.org>\n\
Date: Sun, 22 Mar 3000 22:37:58 +0000\n\
\n\
Hello\n",
false,
)
.await?
.unwrap()
.chat_id;
bob_chat_id.accept(bob).await?;
send_text_msg(bob, bob_chat_id, "hi".to_string()).await?;
let sent_msg = bob.pop_sent_msg().await;
let msg = Message::load_from_db(bob, sent_msg.sender_msg_id).await?;
assert!(!msg.get_showpadlock());
Ok(())
}
}

View File

@@ -1452,9 +1452,7 @@ impl Session {
let is_seen = fetch_response.flags().any(|flag| flag == Flag::Seen);
let rfc724_mid = if let Some(rfc724_mid) = uid_message_ids.get(&request_uid) {
rfc724_mid
} else {
let Some(rfc724_mid) = uid_message_ids.get(&request_uid) else {
error!(
context,
"No Message-ID corresponding to UID {} passed in uid_messsage_ids.",

View File

@@ -652,7 +652,9 @@ impl MimeFactory {
let peerstates = self.peerstates_for_recipients(context).await?;
let is_encrypted = !self.should_force_plaintext()
&& encrypt_helper.should_encrypt(context, e2ee_guaranteed, &peerstates)?;
&& encrypt_helper
.should_encrypt(context, e2ee_guaranteed, &peerstates)
.await?;
let is_securejoin_message = if let Loaded::Message { msg, .. } = &self.loaded {
msg.param.get_cmd() == SystemMessage::SecurejoinMessage
} else {

View File

@@ -640,6 +640,9 @@ mod tests {
fn test_invalid_proxy_url() {
assert!(ProxyConfig::from_url("foobar://127.0.0.1:9050").is_err());
assert!(ProxyConfig::from_url("abc").is_err());
// This caused panic before shadowsocks 1.22.0.
assert!(ProxyConfig::from_url("ss://foo:bar@127.0.0.1:9999").is_err());
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]

View File

@@ -360,7 +360,7 @@ pub(crate) async fn receive_imf_inner(
let contact = Contact::get_by_id(context, from_id).await?;
mime_parser.peerstate = Peerstate::from_addr(context, contact.get_addr()).await?;
} else {
let to_id = to_ids.first().copied().unwrap_or_default();
let to_id = to_ids.first().copied().unwrap_or(ContactId::SELF);
// handshake may mark contacts as verified and must be processed before chats are created
res = observe_securejoin_on_other_device(context, &mime_parser, to_id)
.await
@@ -778,6 +778,11 @@ async fn add_parts(
}
}
if chat_id.is_none() && is_mdn {
chat_id = Some(DC_CHAT_ID_TRASH);
info!(context, "Message is an MDN (TRASH).",);
}
if mime_parser.incoming {
to_id = ContactId::SELF;
@@ -789,11 +794,6 @@ async fn add_parts(
markseen_on_imap_table(context, rfc724_mid).await.ok();
}
if chat_id.is_none() && is_mdn {
chat_id = Some(DC_CHAT_ID_TRASH);
info!(context, "Message is an MDN (TRASH).",);
}
let create_blocked_default = if is_bot {
Blocked::Not
} else {
@@ -946,14 +946,11 @@ async fn add_parts(
chat_id = Some(chat.id);
chat_id_blocked = chat.blocked;
} else if allow_creation {
if let Ok(chat) = ChatIdBlocked::get_for_contact(context, from_id, create_blocked)
let chat = ChatIdBlocked::get_for_contact(context, from_id, create_blocked)
.await
.context("Failed to get (new) chat for contact")
.log_err(context)
{
chat_id = Some(chat.id);
chat_id_blocked = chat.blocked;
}
.context("Failed to get (new) chat for contact")?;
chat_id = Some(chat.id);
chat_id_blocked = chat.blocked;
}
if let Some(chat_id) = chat_id {
@@ -977,7 +974,6 @@ async fn add_parts(
// the 1:1 chat accordingly.
let chat = match is_partial_download.is_none()
&& mime_parser.get_header(HeaderDef::SecureJoin).is_none()
&& !is_mdn
{
true => Some(Chat::load_from_db(context, chat_id).await?)
.filter(|chat| chat.typ == Chattype::Single),
@@ -1038,9 +1034,13 @@ async fn add_parts(
// the mail is on the IMAP server, probably it is also delivered.
// We cannot recreate other states (read, error).
state = MessageState::OutDelivered;
to_id = to_ids.first().copied().unwrap_or_default();
to_id = to_ids.first().copied().unwrap_or(ContactId::SELF);
let self_sent = to_ids.len() == 1 && to_ids.contains(&ContactId::SELF);
// Older Delta Chat versions with core <=1.152.2 only accepted
// self-sent messages in Saved Messages with own address in the `To` field.
// New Delta Chat versions may use empty `To` field
// with only a single `hidden-recipients` group in this case.
let self_sent = to_ids.len() <= 1 && to_id == ContactId::SELF;
if mime_parser.sync_items.is_some() && self_sent {
chat_id = Some(DC_CHAT_ID_TRASH);
@@ -1146,9 +1146,8 @@ async fn add_parts(
chat_id = Some(id);
chat_id_blocked = blocked;
}
} else if let Ok(chat) =
ChatIdBlocked::get_for_contact(context, to_id, Blocked::Not).await
{
} else {
let chat = ChatIdBlocked::get_for_contact(context, to_id, Blocked::Not).await?;
chat_id = Some(chat.id);
chat_id_blocked = chat.blocked;
}
@@ -1164,7 +1163,7 @@ async fn add_parts(
if chat_id_blocked != Blocked::Not {
if let Some(chat_id) = chat_id {
chat_id.unblock_ex(context, Nosync).await?;
chat_id_blocked = Blocked::Not;
// Not assigning `chat_id_blocked = Blocked::Not` to avoid unused_assignments warning.
}
}
}
@@ -1182,26 +1181,6 @@ async fn add_parts(
.await?;
}
if chat_id.is_none() && self_sent {
// from_id==to_id==ContactId::SELF - this is a self-sent messages,
// maybe an Autocrypt Setup Message
if let Ok(chat) = ChatIdBlocked::get_for_contact(context, ContactId::SELF, Blocked::Not)
.await
.context("Failed to get (new) chat for contact")
.log_err(context)
{
chat_id = Some(chat.id);
chat_id_blocked = chat.blocked;
}
if let Some(chat_id) = chat_id {
if Blocked::Not != chat_id_blocked {
chat_id.unblock_ex(context, Nosync).await?;
// Not assigning `chat_id_blocked = Blocked::Not` to avoid unused_assignments warning.
}
}
}
if chat_id.is_none() {
// Check if the message belongs to a broadcast list.
if let Some(mailinglist_header) = mime_parser.get_mailinglist_header() {
@@ -1217,6 +1196,21 @@ async fn add_parts(
);
}
}
if chat_id.is_none() && self_sent {
// from_id==to_id==ContactId::SELF - this is a self-sent messages,
// maybe an Autocrypt Setup Message
let chat = ChatIdBlocked::get_for_contact(context, ContactId::SELF, Blocked::Not)
.await
.context("Failed to get (new) chat for contact")?;
chat_id = Some(chat.id);
// Not assigning `chat_id_blocked = chat.blocked` to avoid unused_assignments warning.
if Blocked::Not != chat.blocked {
chat.id.unblock_ex(context, Nosync).await?;
}
}
}
if fetching_existing_messages && mime_parser.decrypting_failed {
@@ -1236,7 +1230,7 @@ async fn add_parts(
}
let orig_chat_id = chat_id;
let mut chat_id = if is_mdn || is_reaction {
let mut chat_id = if is_reaction {
DC_CHAT_ID_TRASH
} else {
chat_id.unwrap_or_else(|| {
@@ -1694,7 +1688,7 @@ RETURNING id
"Message has {icnt} parts and is assigned to chat #{chat_id}."
);
if !is_mdn {
if !chat_id.is_trash() {
let mut chat = Chat::load_from_db(context, chat_id).await?;
// In contrast to most other update-timestamps,

View File

@@ -2200,6 +2200,30 @@ Message content",
assert_ne!(msg.chat_id, t.get_self_chat().await.id);
}
/// Tests that message with hidden recipients is assigned to Saved Messages chat.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_hidden_recipients_self_chat() {
let t = TestContext::new_alice().await;
receive_imf(
&t,
b"Subject: s
Chat-Version: 1.0
Message-ID: <foobar@localhost>
To: hidden-recipients:;
From: <alice@example.org>
Message content",
false,
)
.await
.unwrap();
let msg = t.get_last_msg().await;
assert_eq!(msg.chat_id, t.get_self_chat().await.id);
assert_eq!(msg.to_id, ContactId::SELF);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_no_unencrypted_name_in_self_chat() -> Result<()> {
let mut tcm = TestContextManager::new();

View File

@@ -686,7 +686,7 @@ async fn test_break_protection_then_verify_again() -> Result<()> {
alice.create_chat(&bob).await;
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
let chats = Chatlist::try_load(&alice, DC_GCL_FOR_FORWARDING, None, None).await?;
assert!(chats.len() == 1);
assert_eq!(chats.len(), 1);
tcm.section("Bob reinstalls DC");
drop(bob);
@@ -709,7 +709,7 @@ async fn test_break_protection_then_verify_again() -> Result<()> {
assert_eq!(chat.is_protected(), false);
assert_eq!(chat.is_protection_broken(), true);
let chats = Chatlist::try_load(&alice, DC_GCL_FOR_FORWARDING, None, None).await?;
assert!(chats.len() == 1);
assert_eq!(chats.len(), 1);
{
let alice_bob_chat = alice.get_chat(&bob_new).await;