Compare commits

..
Author SHA1 Message Date
Hocuri 4b65ab2ead fix: Clear draft when leaving a group or when Self is removed.
Fix #6175.

This is not a very bad bug (even WhatsApp has the same bug, and WhatsApp
rarely has any bugs at all!), so I think it's fine not to add regression
tests.

I did test that it works on an Android phone. Clearing the draft when a
different device leaves the group or when Self is removed from the group
works.

What doesn't work is clearing the draft when leaving a group from this
device, because after leaving, the UI still has the draft in the
now-hidden input bar, and calls set_draft() when the user leaves the
activity, re-adding the draft. We could fix this by loading the chat in
do_set_draft(), calling, `is_self_in_chat()`, and not setting the draft
if self isn't in the chat. This is two extra database calls everytime
the user leaves a group and goes back to the chat list - not a big
deal, but I'm nonetheless not sure it's worth it for this super arcane
bug. What do you think?
2024-11-05 20:41:22 +01:00
link2xt d2324a8fc4 chore: fix nightly clippy warnings 2024-11-05 15:05:42 +00:00
link2xt 10a05fa6d9 chore(release): prepare for 1.149.0 2024-11-05 12:08:00 +00:00
link2xt 97d2119028 chore(cargo): update iroh to 0.28.1 2024-11-04 21:01:40 +00:00
link2xt a510d5f3c2 build: nix flake update android 2024-11-04 20:10:43 +00:00
link2xt 678f1b305c build: update tokio to 1.41 and Android NDK to r27
Delta Chat for Android does not support Android 4 anymore,
so there is no reason to keep using unsupported NDK.

r27 is the latest LTS version of Android NDK.

Tested:
- `nix build .#deltachat-rpc-server-arm64-v8a-android`
- `nix build .#deltachat-rpc-server-armv6l-linux`

`nix build .#deltachat-rpc-server-x86_64-android`
and
`nix build .#deltachat-rpc-server-x86-android`
still fail, but we do not build it in CI.
2024-11-04 20:10:43 +00:00
link2xt dface33699 chore(release): prepare for 1.148.7 2024-11-03 21:50:59 +00:00
link2xt 92c6dd483c api: add API to reset contact encryption 2024-11-03 02:04:41 +00:00
link2xt c627d2fcc8 refactor: remove has_decrypted_pgp_armor()
Explicit check for `-----BEGIN PGP MESSAGE-----` is unnecessary
and not sufficient to ensure that the message is valid.
We have already checked the MIME type,
so ASCII-armored OpenPGP message should be inside.
If it's not, decryption will fail anyway.
2024-11-03 01:16:17 +00:00
dependabot[bot] 429c14ae0b Merge pull request #6157 from deltachat/dependabot/cargo/libc-0.2.161 2024-11-02 17:29:07 +00:00
dependabot[bot] ce40c04e63 Merge pull request #6156 from deltachat/dependabot/cargo/brotli-7.0.0 2024-11-02 17:09:32 +00:00
dependabot[bot] 7175ee8587 chore(cargo): bump libc from 0.2.159 to 0.2.161
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.159 to 0.2.161.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.161/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.159...0.2.161)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-02 16:38:04 +00:00
dependabot[bot] c12a972abd chore(cargo): bump brotli from 6.0.0 to 7.0.0
Bumps [brotli](https://github.com/dropbox/rust-brotli) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/dropbox/rust-brotli/releases)
- [Commits](https://github.com/dropbox/rust-brotli/commits)

---
updated-dependencies:
- dependency-name: brotli
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-02 16:37:58 +00:00
28 changed files with 480 additions and 227 deletions
+40
View File
@@ -1,5 +1,43 @@
# Changelog
## [1.149.0] - 2024-11-05
### Build system
- Update tokio to 1.41 and Android NDK to r27.
- `nix flake update android`.
### Fixes
- cargo: Update iroh to 0.28.1.
This fixes the problem with iroh not sending the `Host:` header and not being able to connect to relays behind nginx reverse proxy.
## [1.148.7] - 2024-11-03
### API-Changes
- Add API to reset contact encryption.
### Features / Changes
- Emit chatlist events only if message still exists.
### Fixes
- send_msg_to_smtp: Do not fail if the message does not exist anymore.
- Do not percent-encode dot when passing to autoconfig server.
- Save contact name from SecureJoin QR to `authname`, not to `name` ([#6115](https://github.com/deltachat/deltachat-core-rust/pull/6115)).
- Always exit fake IDLE after at most 60 seconds.
- Concat NDNs ([#6129](https://github.com/deltachat/deltachat-core-rust/pull/6129)).
### Refactor
- Remove `has_decrypted_pgp_armor()`.
### Miscellaneous Tasks
- Update dependencies.
## [1.148.6] - 2024-10-31
### API-Changes
@@ -5193,3 +5231,5 @@ https://github.com/deltachat/deltachat-core-rust/pulls?q=is%3Apr+is%3Aclosed
[1.148.4]: https://github.com/deltachat/deltachat-core-rust/compare/v1.148.3..v1.148.4
[1.148.5]: https://github.com/deltachat/deltachat-core-rust/compare/v1.148.4..v1.148.5
[1.148.6]: https://github.com/deltachat/deltachat-core-rust/compare/v1.148.5..v1.148.6
[1.148.7]: https://github.com/deltachat/deltachat-core-rust/compare/v1.148.6..v1.148.7
[1.149.0]: https://github.com/deltachat/deltachat-core-rust/compare/v1.148.7..v1.149.0
Generated
+264 -91
View File
@@ -384,6 +384,12 @@ dependencies = [
"tokio-util",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "attohttpc"
version = "0.24.1"
@@ -413,9 +419,9 @@ dependencies = [
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"http-body-util",
"hyper 1.5.0",
"hyper",
"hyper-util",
"itoa",
"matchit",
@@ -448,7 +454,7 @@ dependencies = [
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
@@ -615,9 +621,9 @@ checksum = "78a6932c88f1d2c29533a3b8a5f5a2f84cc19c3339b431677c3160c5c2e6ca85"
[[package]]
name = "brotli"
version = "6.0.0"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@@ -1303,7 +1309,7 @@ dependencies = [
[[package]]
name = "deltachat"
version = "1.148.6"
version = "1.149.0"
dependencies = [
"anyhow",
"async-broadcast",
@@ -1332,7 +1338,7 @@ dependencies = [
"hickory-resolver",
"http-body-util",
"humansize",
"hyper 1.5.0",
"hyper",
"hyper-util",
"image",
"iroh-gossip",
@@ -1403,7 +1409,7 @@ dependencies = [
[[package]]
name = "deltachat-jsonrpc"
version = "1.148.6"
version = "1.149.0"
dependencies = [
"anyhow",
"async-channel 2.3.1",
@@ -1428,7 +1434,7 @@ dependencies = [
[[package]]
name = "deltachat-repl"
version = "1.148.6"
version = "1.149.0"
dependencies = [
"anyhow",
"deltachat",
@@ -1444,7 +1450,7 @@ dependencies = [
[[package]]
name = "deltachat-rpc-server"
version = "1.148.6"
version = "1.149.0"
dependencies = [
"anyhow",
"deltachat",
@@ -1473,7 +1479,7 @@ dependencies = [
[[package]]
name = "deltachat_ffi"
version = "1.148.6"
version = "1.149.0"
dependencies = [
"anyhow",
"deltachat",
@@ -2361,6 +2367,37 @@ dependencies = [
"slab",
]
[[package]]
name = "genawaiter"
version = "0.99.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0"
dependencies = [
"futures-core",
"genawaiter-macro",
"genawaiter-proc-macro",
"proc-macro-hack",
]
[[package]]
name = "genawaiter-macro"
version = "0.99.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc"
[[package]]
name = "genawaiter-proc-macro"
version = "0.99.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738"
dependencies = [
"proc-macro-error",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "generator"
version = "0.7.5"
@@ -2474,16 +2511,16 @@ dependencies = [
[[package]]
name = "h2"
version = "0.3.26"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205"
dependencies = [
"atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.12",
"http 1.1.0",
"indexmap",
"slab",
"tokio",
@@ -2666,17 +2703,6 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.12",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.0"
@@ -2696,7 +2722,7 @@ dependencies = [
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"pin-project-lite",
]
@@ -2741,30 +2767,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
version = "0.14.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper"
version = "1.5.0"
@@ -2774,8 +2776,9 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"httparse",
"httpdate",
"itoa",
@@ -2793,7 +2796,7 @@ checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
dependencies = [
"futures-util",
"http 1.1.0",
"hyper 1.5.0",
"hyper",
"hyper-util",
"rustls",
"rustls-pki-types",
@@ -2813,8 +2816,8 @@ dependencies = [
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.5.0",
"http-body",
"hyper",
"pin-project-lite",
"socket2",
"tokio",
@@ -2872,16 +2875,18 @@ dependencies = [
[[package]]
name = "igd-next"
version = "0.14.3"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4"
checksum = "76b0d7d4541def58a37bf8efc559683f21edce7c82f0d866c93ac21f7e098f93"
dependencies = [
"async-trait",
"attohttpc",
"bytes",
"futures",
"http 0.2.12",
"hyper 0.14.28",
"http 1.1.0",
"http-body-util",
"hyper",
"hyper-util",
"log",
"rand 0.8.5",
"tokio",
@@ -2973,9 +2978,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "iroh-base"
version = "0.26.0"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "973c0b3c7851fa2e8e6cf4cb81c9f4cab1373848828fafa43dfe25b123a89ff2"
checksum = "1c21fd8eb71f166a172a9779c2244db992218e9a9bd929b9df6fc355d2b630c9"
dependencies = [
"aead",
"anyhow",
@@ -2991,7 +2996,6 @@ dependencies = [
"rand 0.8.5",
"rand_core 0.6.4",
"serde",
"serde-error",
"ssh-key",
"thiserror",
"ttl_cache",
@@ -3014,9 +3018,9 @@ dependencies = [
[[package]]
name = "iroh-gossip"
version = "0.26.0"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b44749f361aca7cddcb357b62ef84cad1023771aee03d427c8922991fc4a9561"
checksum = "c078057037f0e741c5ef285c67fd9cfdb928163dd046fb547089898bdb02990e"
dependencies = [
"anyhow",
"async-channel 2.3.1",
@@ -3031,10 +3035,12 @@ dependencies = [
"iroh-blake3",
"iroh-metrics",
"iroh-net",
"iroh-router",
"postcard",
"rand 0.8.5",
"rand_core 0.6.4",
"serde",
"serde-error",
"tokio",
"tokio-util",
"tracing",
@@ -3042,14 +3048,14 @@ dependencies = [
[[package]]
name = "iroh-metrics"
version = "0.26.0"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02edfa7ca1aa89b0b9793d94671e32b79c97d61e9022f082c5eb2b95b64e90c0"
checksum = "e0d40f2ee3997489d47403d204a06514ed65373d224b5b43a8ea133f543e5db1"
dependencies = [
"anyhow",
"erased_set",
"http-body-util",
"hyper 1.5.0",
"hyper",
"hyper-util",
"once_cell",
"prometheus-client",
@@ -3063,9 +3069,9 @@ dependencies = [
[[package]]
name = "iroh-net"
version = "0.26.0"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "329553be056a92eec7802e1c087eed951eec6e60f0f0740491ef16a295be4ca2"
checksum = "b40e1f1f9029e198c6d05bd232d3239814b0a66ac4668978729b709aeb6a44e2"
dependencies = [
"anyhow",
"backoff",
@@ -3079,6 +3085,7 @@ dependencies = [
"futures-lite 2.4.0",
"futures-sink",
"futures-util",
"genawaiter",
"governor",
"hex",
"hickory-proto",
@@ -3086,7 +3093,7 @@ dependencies = [
"hostname",
"http 1.1.0",
"http-body-util",
"hyper 1.5.0",
"hyper",
"hyper-util",
"igd-next",
"iroh-base",
@@ -3099,11 +3106,13 @@ dependencies = [
"netlink-packet-core",
"netlink-packet-route",
"netlink-sys",
"netwatch",
"num_enum",
"once_cell",
"parking_lot",
"pin-project",
"pkarr",
"portmapper",
"postcard",
"rand 0.8.5",
"rcgen",
@@ -3139,9 +3148,9 @@ dependencies = [
[[package]]
name = "iroh-quinn"
version = "0.11.3"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fd590a39a14cfc168efa4d894de5039d65641e62d8da4a80733018ababe3c33"
checksum = "35ba75a5c57cff299d2d7ca1ddee053f66339d1756bd79ec637bcad5aa61100e"
dependencies = [
"bytes",
"iroh-quinn-proto",
@@ -3157,9 +3166,9 @@ dependencies = [
[[package]]
name = "iroh-quinn-proto"
version = "0.11.6"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fd0538ff12efe3d61ea1deda2d7913f4270873a519d43e6995c6e87a1558538"
checksum = "e2c869ba52683d3d067c83ab4c00a2fda18eaf13b1434d4c1352f428674d4a5d"
dependencies = [
"bytes",
"rand 0.8.5",
@@ -3175,9 +3184,9 @@ dependencies = [
[[package]]
name = "iroh-quinn-udp"
version = "0.5.4"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0619b59471fdd393ac8a6c047f640171119c1c8b41f7d2927db91776dcdbc5f"
checksum = "bfcfc0abc2fdf8cf18a6c72893b7cbebeac2274a3b1306c1760c48c0e10ac5e0"
dependencies = [
"libc",
"once_cell",
@@ -3186,6 +3195,22 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "iroh-router"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fd18ec6325dd3f01625f12c01acff50a4374ee1ab708e7b2078885fd63ad30"
dependencies = [
"anyhow",
"futures-buffered",
"futures-lite 2.4.0",
"futures-util",
"iroh-net",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "is-terminal"
version = "0.4.12"
@@ -3314,9 +3339,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.159"
version = "0.2.161"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
[[package]]
name = "libm"
@@ -3426,6 +3451,26 @@ dependencies = [
"quoted_printable",
]
[[package]]
name = "mainline"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b751ffb57303217bcae8f490eee6044a5b40eadf6ca05ff476cad37e7b7970d"
dependencies = [
"bytes",
"crc",
"ed25519-dalek",
"flume",
"lru",
"rand 0.8.5",
"serde",
"serde_bencode",
"serde_bytes",
"sha1_smol",
"thiserror",
"tracing",
]
[[package]]
name = "match_cfg"
version = "0.1.0"
@@ -3499,13 +3544,14 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.11"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
dependencies = [
"hermit-abi",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -3623,6 +3669,35 @@ dependencies = [
"tokio",
]
[[package]]
name = "netwatch"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a639d52c0996ac640e2a7052a5265c8f71efdbdadc83188435ffc358b7ca931"
dependencies = [
"anyhow",
"bytes",
"derive_more",
"futures-lite 2.4.0",
"futures-sink",
"futures-util",
"libc",
"netdev",
"netlink-packet-core",
"netlink-packet-route",
"netlink-sys",
"once_cell",
"rtnetlink",
"serde",
"socket2",
"thiserror",
"time 0.3.36",
"tokio",
"tracing",
"windows 0.51.1",
"wmi",
]
[[package]]
name = "nibble_vec"
version = "0.1.0"
@@ -4201,11 +4276,13 @@ checksum = "89f9e12544b00f5561253bbd3cb72a85ff3bc398483dc1bf82bdf095c774136b"
dependencies = [
"bytes",
"document-features",
"dyn-clone",
"ed25519-dalek",
"flume",
"futures",
"js-sys",
"lru",
"mainline",
"self_cell",
"simple-dns",
"thiserror",
@@ -4356,6 +4433,35 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
[[package]]
name = "portmapper"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d60045fdcfe8ff6b781cf1027fdbb08ed319d93aff7da4bedc018e3bc92226"
dependencies = [
"anyhow",
"base64 0.22.1",
"bytes",
"derive_more",
"futures-lite 2.4.0",
"futures-util",
"igd-next",
"iroh-metrics",
"libc",
"netwatch",
"num_enum",
"rand 0.8.5",
"serde",
"smallvec",
"socket2",
"thiserror",
"time 0.3.36",
"tokio",
"tokio-util",
"tracing",
"url",
]
[[package]]
name = "postcard"
version = "1.0.8"
@@ -4454,6 +4560,32 @@ dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro-error"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn 1.0.109",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn-mid",
"version_check",
]
[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
@@ -4476,6 +4608,12 @@ dependencies = [
"syn 2.0.86",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.20+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
version = "1.0.86"
@@ -4885,9 +5023,9 @@ dependencies = [
"futures-core",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"http-body",
"http-body-util",
"hyper 1.5.0",
"hyper",
"hyper-rustls",
"hyper-util",
"ipnet",
@@ -5350,9 +5488,28 @@ dependencies = [
[[package]]
name = "serde-error"
version = "0.1.2"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e988182713aeed6a619a88bca186f6d6407483485ffe44c869ee264f8eabd13f"
checksum = "342110fb7a5d801060c885da03bf91bfa7c7ca936deafcc64bb6706375605d47"
dependencies = [
"serde",
]
[[package]]
name = "serde_bencode"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a70dfc7b7438b99896e7f8992363ab8e2c4ba26aa5ec675d32d1c3c2c33d413e"
dependencies = [
"serde",
"serde_bytes",
]
[[package]]
name = "serde_bytes"
version = "0.11.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a"
dependencies = [
"serde",
]
@@ -5464,6 +5621,12 @@ dependencies = [
"sha1",
]
[[package]]
name = "sha1_smol"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
[[package]]
name = "sha2"
version = "0.10.8"
@@ -5836,6 +5999,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "syn-mid"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
@@ -6043,21 +6217,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.38.1"
version = "1.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df"
checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -6072,9 +6245,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "2.3.0"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
+5 -12
View File
@@ -1,6 +1,6 @@
[package]
name = "deltachat"
version = "1.148.6"
version = "1.149.0"
edition = "2021"
license = "MPL-2.0"
rust-version = "1.77"
@@ -46,7 +46,7 @@ async-native-tls = { version = "0.5", default-features = false, features = ["run
async-smtp = { version = "0.9", default-features = false, features = ["runtime-tokio"] }
async_zip = { version = "0.0.17", default-features = false, features = ["deflate", "tokio-fs"] }
base64 = { workspace = true }
brotli = { version = "6", default-features=false, features = ["std"] }
brotli = { version = "7", default-features=false, features = ["std"] }
bytes = "1"
chrono = { workspace = true, features = ["alloc", "clock", "std"] }
email = { git = "https://github.com/deltachat/rust-email", branch = "master" }
@@ -63,8 +63,8 @@ humansize = "2"
hyper = "1"
hyper-util = "0.1.10"
image = { version = "0.25.4", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] }
iroh-gossip = { version = "0.26.0", default-features = false, features = ["net"] }
iroh-net = { version = "0.26.0", default-features = false }
iroh-gossip = { version = "0.28.1", default-features = false, features = ["net"] }
iroh-net = { version = "0.28.1", default-features = false }
kamadak-exif = "0.6.0"
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" }
libc = { workspace = true }
@@ -186,14 +186,7 @@ serde = "1.0"
serde_json = "1"
tempfile = "3.13.0"
thiserror = "1"
# 1.38 is the latest version before `mio` dependency update
# that broke compilation with Android NDK r23c and r24.
# Version 1.39.0 cannot be compiled using these NDKs,
# see issue <https://github.com/tokio-rs/tokio/issues/6748>
# for details.
tokio = "~1.38.1"
tokio = "1"
tokio-util = "0.7.11"
tracing-subscriber = "0.3"
yerpc = "0.6.2"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "deltachat_ffi"
version = "1.148.6"
version = "1.149.0"
description = "Deltachat FFI"
edition = "2018"
readme = "README.md"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "deltachat-jsonrpc"
version = "1.148.6"
version = "1.149.0"
description = "DeltaChat JSON-RPC API"
edition = "2021"
default-run = "deltachat-jsonrpc-server"
+9
View File
@@ -1419,6 +1419,15 @@ impl CommandApi {
Ok(())
}
/// Resets contact encryption.
async fn reset_contact_encryption(&self, account_id: u32, contact_id: u32) -> Result<()> {
let ctx = self.get_context(account_id).await?;
let contact_id = ContactId::new(contact_id);
contact_id.reset_encryption(&ctx).await?;
Ok(())
}
async fn change_contact_name(
&self,
account_id: u32,
+1 -1
View File
@@ -58,5 +58,5 @@
},
"type": "module",
"types": "dist/deltachat.d.ts",
"version": "1.148.6"
"version": "1.149.0"
}
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "deltachat-repl"
version = "1.148.6"
version = "1.149.0"
license = "MPL-2.0"
edition = "2021"
repository = "https://github.com/deltachat/deltachat-core-rust"
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "deltachat-rpc-client"
version = "1.148.6"
version = "1.149.0"
description = "Python client for Delta Chat core JSON-RPC interface"
classifiers = [
"Development Status :: 5 - Production/Stable",
@@ -36,6 +36,10 @@ class Contact:
"""Delete contact."""
self._rpc.delete_contact(self.account.id, self.id)
def reset_encryption(self) -> None:
"""Reset contact encryption."""
self._rpc.reset_contact_encryption(self.account.id, self.id)
def set_name(self, name: str) -> None:
"""Change the name of this contact."""
self._rpc.change_contact_name(self.account.id, self.id, name)
@@ -246,6 +246,7 @@ def test_contact(acfactory) -> None:
assert repr(alice_contact_bob)
alice_contact_bob.block()
alice_contact_bob.unblock()
alice_contact_bob.reset_encryption()
alice_contact_bob.set_name("new name")
alice_contact_bob.get_encryption_info()
snapshot = alice_contact_bob.get_snapshot()
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "deltachat-rpc-server"
version = "1.148.6"
version = "1.149.0"
description = "DeltaChat JSON-RPC server"
edition = "2021"
readme = "README.md"
@@ -15,5 +15,5 @@
},
"type": "module",
"types": "index.d.ts",
"version": "1.148.6"
"version": "1.149.0"
}
+4 -3
View File
@@ -11,6 +11,10 @@ ignore = [
# Unmaintained encoding
"RUSTSEC-2021-0153",
# Unmaintained proc-macro-error
# <https://rustsec.org/advisories/RUSTSEC-2024-0370>
"RUSTSEC-2024-0370",
]
[bans]
@@ -28,10 +32,7 @@ skip = [
{ name = "fastrand", version = "1.9.0" },
{ name = "futures-lite", version = "1.13.0" },
{ name = "getrandom", version = "<0.2" },
{ name = "h2", version = "0.3.26" },
{ name = "http-body", version = "0.4.6" },
{ name = "http", version = "0.2.12" },
{ name = "hyper", version = "0.14.28" },
{ name = "nix", version = "0.26.4" },
{ name = "quick-error", version = "<2.0" },
{ name = "rand_chacha", version = "<0.3" },
Generated
+14 -48
View File
@@ -3,15 +3,15 @@
"android": {
"inputs": {
"devshell": "devshell",
"flake-utils": "flake-utils_2",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1712088936,
"narHash": "sha256-mVjeSWQiR/t4UZ9fUawY9OEPAhY1R3meYG+0oh8DUBs=",
"lastModified": 1729628358,
"narHash": "sha256-2HDSc6BL+bE3S1l3Gn0Z8wWvvfBEUEjvXkNIQ11Aifk=",
"owner": "tadfisher",
"repo": "android-nixpkgs",
"rev": "2d8181caef279f19c4a33dc694723f89ffc195d4",
"rev": "52b9e0c0f9cff887d2bb4932f8be4e062ba0802d",
"type": "github"
},
"original": {
@@ -22,18 +22,17 @@
},
"devshell": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"android",
"nixpkgs"
]
},
"locked": {
"lastModified": 1711099426,
"narHash": "sha256-HzpgM/wc3aqpnHJJ2oDqPBkNsqWbW0WfWUO8lKu8nGk=",
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "2d45b54ca4a183f2fdcf4b19c895b64fbf620ee8",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
@@ -66,11 +65,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
@@ -97,24 +96,6 @@
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"naersk": {
"inputs": {
"nixpkgs": "nixpkgs_3"
@@ -150,11 +131,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1711703276,
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
"lastModified": 1729413321,
"narHash": "sha256-I4tuhRpZFa6Fu6dcH9Dlo5LlH17peT79vx1y1SpeKt0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
"rev": "1997e4aa514312c1af7e2bda7fad1644e778ff26",
"type": "github"
},
"original": {
@@ -213,7 +194,7 @@
"inputs": {
"android": "android",
"fenix": "fenix",
"flake-utils": "flake-utils_3",
"flake-utils": "flake-utils_2",
"naersk": "naersk",
"nix-filter": "nix-filter",
"nixpkgs": "nixpkgs_4"
@@ -265,21 +246,6 @@
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
+11 -3
View File
@@ -18,9 +18,9 @@
manifest = (pkgs.lib.importTOML ./Cargo.toml).package;
androidSdk = android.sdk.${system} (sdkPkgs:
builtins.attrValues {
inherit (sdkPkgs) ndk-24-0-8215888 cmdline-tools-latest;
inherit (sdkPkgs) ndk-27-0-11902837 cmdline-tools-latest;
});
androidNdkRoot = "${androidSdk}/share/android-sdk/ndk/24.0.8215888";
androidNdkRoot = "${androidSdk}/share/android-sdk/ndk/27.0.11902837";
rustSrc = nix-filter.lib {
root = ./.;
@@ -257,13 +257,21 @@
androidAttrs = {
armeabi-v7a = {
cc = "armv7a-linux-androideabi19-clang";
cc = "armv7a-linux-androideabi21-clang";
rustTarget = "armv7-linux-androideabi";
};
arm64-v8a = {
cc = "aarch64-linux-android21-clang";
rustTarget = "aarch64-linux-android";
};
x86 = {
cc = "i686-linux-android21-clang";
rustTarget = "i686-linux-android";
};
x86_64 = {
cc = "x86_64-linux-android21-clang";
rustTarget = "x86_64-linux-android";
};
};
mkAndroidRustPackage = arch: packageName:
+1 -1
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.148.6"
"version": "1.149.0"
}
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "deltachat"
version = "1.148.6"
version = "1.149.0"
description = "Python bindings for the Delta Chat Core library using CFFI against the Rust-implemented libdeltachat"
readme = "README.rst"
requires-python = ">=3.7"
+1 -1
View File
@@ -1 +1 @@
2024-10-31
2024-11-05
+10
View File
@@ -3921,6 +3921,11 @@ pub async fn remove_contact_from_chat(
let mut msg = Message::default();
let chat = Chat::load_from_db(context, chat_id).await?;
if chat.typ == Chattype::Group && contact_id == ContactId::SELF {
chat_id.set_draft(context, None).await?; // Clear draft since the user left the group.
}
if chat.typ == Chattype::Group || chat.typ == Chattype::Broadcast {
if !chat.is_self_in_chat(context).await? {
let err_msg = format!(
@@ -4611,6 +4616,11 @@ async fn set_contacts_by_addrs(context: &Context, id: ChatId, addrs: &[String])
if contacts == contacts_old {
return Ok(());
}
if chat.typ == Chattype::Group && !contacts.contains(&ContactId::SELF) {
id.set_draft(context, None).await?; // Clear draft since the user left the group.
}
update_chat_contacts_table(context, id, &contacts).await?;
context.emit_event(EventType::ChatModified(id));
Ok(())
+92
View File
@@ -143,6 +143,43 @@ impl ContactId {
.await?;
Ok(())
}
/// Returns contact adress.
pub async fn addr(&self, context: &Context) -> Result<String> {
let addr = context
.sql
.query_row("SELECT addr FROM contacts WHERE id=?", (self,), |row| {
let addr: String = row.get(0)?;
Ok(addr)
})
.await?;
Ok(addr)
}
/// Resets encryption with the contact.
///
/// Effect is similar to receiving a message without Autocrypt header
/// from the contact, but this action is triggered manually by the user.
///
/// For example, this will result in sending the next message
/// to 1:1 chat unencrypted, but will not remove existing verified keys.
pub async fn reset_encryption(self, context: &Context) -> Result<()> {
let now = time();
let addr = self.addr(context).await?;
if let Some(mut peerstate) = Peerstate::from_addr(context, &addr).await? {
peerstate.degrade_encryption(now);
peerstate.save_to_db(&context.sql).await?;
}
// Reset 1:1 chat protection.
if let Some(chat_id) = ChatId::lookup_by_contact(context, self).await? {
chat_id
.set_protection(context, ProtectionStatus::Unprotected, now, Some(self))
.await?;
}
Ok(())
}
}
impl fmt::Display for ContactId {
@@ -3152,4 +3189,59 @@ Until the false-positive is fixed:
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_reset_encryption() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let msg = tcm.send_recv_accept(alice, bob, "Hello!").await;
assert_eq!(msg.get_showpadlock(), false);
let msg = tcm.send_recv(bob, alice, "Hi!").await;
assert_eq!(msg.get_showpadlock(), true);
let alice_bob_contact_id = msg.from_id;
alice_bob_contact_id.reset_encryption(alice).await?;
let msg = tcm.send_recv(alice, bob, "Unencrypted").await;
assert_eq!(msg.get_showpadlock(), false);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_reset_verified_encryption() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
tcm.execute_securejoin(bob, alice).await;
let msg = tcm.send_recv(bob, alice, "Encrypted").await;
assert_eq!(msg.get_showpadlock(), true);
let alice_bob_chat_id = msg.chat_id;
let alice_bob_contact_id = msg.from_id;
alice_bob_contact_id.reset_encryption(alice).await?;
// Check that the contact is still verified after resetting encryption.
let alice_bob_contact = Contact::get_by_id(alice, alice_bob_contact_id).await?;
assert_eq!(alice_bob_contact.is_verified(alice).await?, true);
// 1:1 chat and profile is no longer verified.
assert_eq!(alice_bob_contact.is_profile_verified(alice).await?, false);
let info_msg = alice.get_last_msg_in(alice_bob_chat_id).await;
assert_eq!(
info_msg.text,
"bob@example.net sent a message from another device."
);
let msg = tcm.send_recv(alice, bob, "Unencrypted").await;
assert_eq!(msg.get_showpadlock(), false);
Ok(())
}
}
+5 -54
View File
@@ -31,11 +31,11 @@ pub fn try_decrypt(
return Ok(None);
};
decrypt_part(
encrypted_data_part,
private_keyring,
public_keyring_for_validate,
)
let data = encrypted_data_part.get_body_raw()?;
let (plain, ret_valid_signatures) =
pgp::pk_decrypt(data, private_keyring, public_keyring_for_validate)?;
Ok(Some((plain, ret_valid_signatures)))
}
pub(crate) async fn prepare_decryption(
@@ -204,37 +204,6 @@ fn get_autocrypt_mime<'a, 'b>(mail: &'a ParsedMail<'b>) -> Option<&'a ParsedMail
}
}
/// Returns Ok(None) if nothing encrypted was found.
fn decrypt_part(
mail: &ParsedMail<'_>,
private_keyring: &[SignedSecretKey],
public_keyring_for_validate: &[SignedPublicKey],
) -> Result<Option<(Vec<u8>, HashSet<Fingerprint>)>> {
let data = mail.get_body_raw()?;
if has_decrypted_pgp_armor(&data) {
let (plain, ret_valid_signatures) =
pgp::pk_decrypt(data, private_keyring, public_keyring_for_validate)?;
return Ok(Some((plain, ret_valid_signatures)));
}
Ok(None)
}
#[allow(clippy::indexing_slicing)]
fn has_decrypted_pgp_armor(input: &[u8]) -> bool {
if let Some(index) = input.iter().position(|b| *b > b' ') {
if input.len() - index > 26 {
let start = index;
let end = start + 27;
return &input[start..end] == b"-----BEGIN PGP MESSAGE-----";
}
}
false
}
/// Validates signatures of Multipart/Signed message part, as defined in RFC 1847.
///
/// Returns the signed part and the set of key
@@ -346,24 +315,6 @@ mod tests {
use crate::receive_imf::receive_imf;
use crate::test_utils::TestContext;
#[test]
fn test_has_decrypted_pgp_armor() {
let data = b" -----BEGIN PGP MESSAGE-----";
assert_eq!(has_decrypted_pgp_armor(data), true);
let data = b" \n-----BEGIN PGP MESSAGE-----";
assert_eq!(has_decrypted_pgp_armor(data), true);
let data = b" -----BEGIN PGP MESSAGE---";
assert_eq!(has_decrypted_pgp_armor(data), false);
let data = b" -----BEGIN PGP MESSAGE-----";
assert_eq!(has_decrypted_pgp_armor(data), true);
let data = b"blas";
assert_eq!(has_decrypted_pgp_armor(data), false);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_mixed_up_mime() -> Result<()> {
// "Mixed Up" mail as received when sending an encrypted
+2 -2
View File
@@ -144,12 +144,12 @@ impl HtmlMsgParser {
self.plain = Some(PlainText {
text: decoded_data,
flowed: if let Some(format) = mail.ctype.params.get("format") {
format.as_str().to_ascii_lowercase() == "flowed"
format.as_str().eq_ignore_ascii_case("flowed")
} else {
false
},
delsp: if let Some(delsp) = mail.ctype.params.get("delsp") {
delsp.as_str().to_ascii_lowercase() == "yes"
delsp.as_str().eq_ignore_ascii_case("yes")
} else {
false
},
+1 -1
View File
@@ -1913,7 +1913,7 @@ async fn needs_move_to_mvbox(
&& has_chat_version
&& headers
.get_header_value(HeaderDef::AutoSubmitted)
.filter(|val| val.to_ascii_lowercase() == "auto-generated")
.filter(|val| val.eq_ignore_ascii_case("auto-generated"))
.is_some()
{
if let Some(from) = mimeparser::get_from(headers) {
+2
View File
@@ -743,6 +743,8 @@ impl MimeFactory {
hidden_headers.push(header);
} else if header_name == "chat-user-avatar" {
hidden_headers.push(header);
} else if header_name == "autocrypt" {
unprotected_headers.push(header.clone());
} else if header_name == "from" {
// Unencrypted securejoin messages should _not_ include the display name:
if is_encrypted || !is_securejoin_message {
+2 -2
View File
@@ -1158,7 +1158,7 @@ impl MimeMessage {
let is_format_flowed = if let Some(format) = mail.ctype.params.get("format")
{
format.as_str().to_ascii_lowercase() == "flowed"
format.as_str().eq_ignore_ascii_case("flowed")
} else {
false
};
@@ -1168,7 +1168,7 @@ impl MimeMessage {
&& is_format_flowed
{
let delsp = if let Some(delsp) = mail.ctype.params.get("delsp") {
delsp.as_str().to_ascii_lowercase() == "yes"
delsp.as_str().eq_ignore_ascii_case("yes")
} else {
false
};
+3
View File
@@ -2317,6 +2317,9 @@ async fn apply_group_changes(
}
if new_members != chat_contacts {
if !new_members.contains(&ContactId::SELF) {
chat_id.set_draft(context, None).await?; // Clear draft since Self was removed from the group.
}
chat::update_chat_contacts_table(context, chat_id, &new_members).await?;
chat_contacts = new_members;
send_event_chat_modified = true;
+1 -1
View File
@@ -135,7 +135,7 @@ impl SchedulerState {
/// If in the meantime [`SchedulerState::start`] or [`SchedulerState::stop`] is called
/// resume will do the right thing and restore the scheduler to the state requested by
/// the last call.
pub(crate) async fn pause<'a>(&'_ self, context: Context) -> Result<IoPausedGuard> {
pub(crate) async fn pause(&'_ self, context: Context) -> Result<IoPausedGuard> {
{
let mut inner = self.inner.write().await;
match *inner {