mirror of
https://github.com/chatmail/core.git
synced 2026-07-13 14:33:09 +03:00
Compare commits
1 Commits
v1.142.6
...
link2xt/up
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7136a6311c |
7
.github/dependabot.yml
vendored
7
.github/dependabot.yml
vendored
@@ -7,10 +7,3 @@ updates:
|
||||
commit-message:
|
||||
prefix: "chore(cargo)"
|
||||
open-pull-requests-limit: 50
|
||||
|
||||
# Keep GitHub Actions up to date.
|
||||
# <https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot>
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
name: Lint Rust
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RUSTUP_TOOLCHAIN: 1.80.1
|
||||
RUSTUP_TOOLCHAIN: 1.80.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
show-progress: false
|
||||
- uses: EmbarkStudios/cargo-deny-action@v2
|
||||
- uses: EmbarkStudios/cargo-deny-action@v1
|
||||
with:
|
||||
arguments: --all-features --workspace
|
||||
command: check
|
||||
@@ -95,11 +95,11 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
rust: 1.80.1
|
||||
rust: 1.80.0
|
||||
- os: windows-latest
|
||||
rust: 1.80.1
|
||||
rust: 1.80.0
|
||||
- os: macos-latest
|
||||
rust: 1.80.1
|
||||
rust: 1.80.0
|
||||
|
||||
# Minimum Supported Rust Version = 1.77.0
|
||||
- os: ubuntu-latest
|
||||
|
||||
2
.github/workflows/dependabot.yml
vendored
2
.github/workflows/dependabot.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
- name: Dependabot metadata
|
||||
id: metadata
|
||||
uses: dependabot/fetch-metadata@v2.2.0
|
||||
uses: dependabot/fetch-metadata@v1.1.1
|
||||
with:
|
||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Approve a PR
|
||||
|
||||
2
.github/workflows/node-docs.yml
vendored
2
.github/workflows/node-docs.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
mv docs js
|
||||
|
||||
- name: Upload
|
||||
uses: horochx/deploy-via-scp@1.1.0
|
||||
uses: horochx/deploy-via-scp@v1.0.1
|
||||
with:
|
||||
user: ${{ secrets.USERNAME }}
|
||||
key: ${{ secrets.KEY }}
|
||||
|
||||
2
.github/workflows/upload-docs.yml
vendored
2
.github/workflows/upload-docs.yml
vendored
@@ -74,7 +74,7 @@ jobs:
|
||||
show-progress: false
|
||||
fetch-depth: 0 # Fetch history to calculate VCS version number.
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '18'
|
||||
- name: npm install
|
||||
|
||||
87
CHANGELOG.md
87
CHANGELOG.md
@@ -1,88 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [1.142.6] - 2024-08-15
|
||||
|
||||
### Fixes
|
||||
|
||||
- Default to strict TLS checks if not configured.
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- deltachat-rpc-client: Fix ruff 0.6.0 warnings.
|
||||
|
||||
## [1.142.5] - 2024-08-14
|
||||
|
||||
### Fixes
|
||||
|
||||
- Still try to create "INBOX.DeltaChat" if couldn't create "DeltaChat" ([#5870](https://github.com/deltachat/deltachat-core-rust/pull/5870)).
|
||||
- `store_seen_flags_on_imap`: Skip to next messages if couldn't select folder ([#5870](https://github.com/deltachat/deltachat-core-rust/pull/5870)).
|
||||
- Increase timeout for QR generation to 60s ([#5882](https://github.com/deltachat/deltachat-core-rust/pull/5882)).
|
||||
|
||||
### Documentation
|
||||
|
||||
- Document new `mdns_enabled` behavior (bots do not send MDNs by default).
|
||||
|
||||
### CI
|
||||
|
||||
- Configure Dependabot to update GitHub Actions.
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- cargo: Bump regex from 1.10.5 to 1.10.6.
|
||||
- cargo: Bump serde from 1.0.204 to 1.0.205.
|
||||
- deps: Bump horochx/deploy-via-scp from 1.0.1 to 1.1.0.
|
||||
- deps: Bump dependabot/fetch-metadata from 1.1.1 to 2.2.0.
|
||||
- deps: Bump actions/setup-node from 2 to 4.
|
||||
- Update provider database.
|
||||
|
||||
## [1.142.4] - 2024-08-09
|
||||
|
||||
### Build system
|
||||
|
||||
- Downgrade Tokio to 1.38 to fix Android compilation.
|
||||
- Use `--locked` with `cargo install`.
|
||||
|
||||
### Features / Changes
|
||||
|
||||
- Add Config::FixIsChatmail.
|
||||
- Always move outgoing auto-generated messages to the mvbox.
|
||||
- Disable requesting MDNs for bots by default.
|
||||
- Allow using OAuth 2 with SOCKS5.
|
||||
- Allow autoconfig when SOCKS5 is enabled.
|
||||
- Update provider database.
|
||||
- cargo: Update iroh from 0.21 to 0.22 ([#5860](https://github.com/deltachat/deltachat-core-rust/pull/5860)).
|
||||
|
||||
### CI
|
||||
|
||||
- Update Rust to 1.80.1.
|
||||
- Update EmbarkStudios/cargo-deny-action.
|
||||
|
||||
### Documentation
|
||||
|
||||
- Point to active Header Protection draft
|
||||
|
||||
### Refactor
|
||||
|
||||
- Derive `Default` for `CertificateChecks`.
|
||||
- Merge imap_certificate_checks and smtp_certificate_checks.
|
||||
- Remove param_addr_urlencoded argument from get_autoconfig().
|
||||
- Pass address to moz_autoconfigure() instead of LoginParam.
|
||||
|
||||
## [1.142.3] - 2024-08-04
|
||||
|
||||
### Build system
|
||||
|
||||
- cargo: Update rusqlite and libsqlite3-sys.
|
||||
- Fix cargo warnings about default-features
|
||||
- Do not disable "vendored" feature in the workspace.
|
||||
- cargo: Bump quick-xml from 0.35.0 to 0.36.1.
|
||||
- cargo: Bump uuid from 1.9.1 to 1.10.0.
|
||||
- cargo: Bump tokio from 1.38.0 to 1.39.2.
|
||||
- cargo: Bump env_logger from 0.11.3 to 0.11.5.
|
||||
- Remove sha2 dependency.
|
||||
- Remove `backtrace` dependency.
|
||||
- Remove direct "quinn" dependency.
|
||||
|
||||
## [1.142.2] - 2024-08-02
|
||||
|
||||
### Features / Changes
|
||||
@@ -4745,7 +4662,3 @@ https://github.com/deltachat/deltachat-core-rust/pulls?q=is%3Apr+is%3Aclosed
|
||||
[1.142.0]: https://github.com/deltachat/deltachat-core-rust/compare/v1.141.2...v1.142.0
|
||||
[1.142.1]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.0...v1.142.1
|
||||
[1.142.2]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.1...v1.142.2
|
||||
[1.142.3]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.2...v1.142.3
|
||||
[1.142.4]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.3...v1.142.4
|
||||
[1.142.5]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.4...v1.142.5
|
||||
[1.142.6]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.5...v1.142.6
|
||||
|
||||
410
Cargo.lock
generated
410
Cargo.lock
generated
@@ -225,8 +225,24 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0"
|
||||
dependencies = [
|
||||
"asn1-rs-derive",
|
||||
"asn1-rs-impl",
|
||||
"asn1-rs-derive 0.4.0",
|
||||
"asn1-rs-impl 0.1.0",
|
||||
"displaydoc",
|
||||
"nom",
|
||||
"num-traits",
|
||||
"rusticata-macros",
|
||||
"thiserror",
|
||||
"time 0.3.36",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asn1-rs"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d"
|
||||
dependencies = [
|
||||
"asn1-rs-derive 0.5.0",
|
||||
"asn1-rs-impl 0.2.0",
|
||||
"displaydoc",
|
||||
"nom",
|
||||
"num-traits",
|
||||
@@ -244,7 +260,19 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"synstructure",
|
||||
"synstructure 0.12.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asn1-rs-derive"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
"synstructure 0.13.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -258,6 +286,17 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asn1-rs-impl"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-broadcast"
|
||||
version = "0.7.1"
|
||||
@@ -569,9 +608,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
version = "2.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
@@ -781,9 +820,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.7"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
|
||||
checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
|
||||
|
||||
[[package]]
|
||||
name = "cfb-mode"
|
||||
@@ -887,6 +926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -895,8 +935,22 @@ version = "4.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1313,7 +1367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.3",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
@@ -1353,7 +1407,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
@@ -1402,11 +1456,12 @@ dependencies = [
|
||||
"proptest",
|
||||
"qrcodegen",
|
||||
"quick-xml",
|
||||
"quinn 0.10.2",
|
||||
"quoted_printable",
|
||||
"rand 0.8.5",
|
||||
"ratelimit",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"reqwest 0.12.5",
|
||||
"rusqlite",
|
||||
"rust-hsluv",
|
||||
"sanitize-filename",
|
||||
@@ -1444,7 +1499,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-jsonrpc"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel 2.3.1",
|
||||
@@ -1469,7 +1524,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-repl"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
@@ -1484,7 +1539,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-rpc-server"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deltachat",
|
||||
@@ -1513,7 +1568,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat_ffi"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deltachat",
|
||||
@@ -1559,7 +1614,21 @@ version = "8.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e"
|
||||
dependencies = [
|
||||
"asn1-rs",
|
||||
"asn1-rs 0.5.2",
|
||||
"displaydoc",
|
||||
"nom",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"rusticata-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der-parser"
|
||||
version = "9.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553"
|
||||
dependencies = [
|
||||
"asn1-rs 0.6.1",
|
||||
"displaydoc",
|
||||
"nom",
|
||||
"num-bigint",
|
||||
@@ -2464,12 +2533,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-concurrency"
|
||||
version = "7.6.1"
|
||||
version = "7.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b14ac911e85d57c5ea6eef76d7b4d4a3177ecd15f4bea2e61927e9e3823e19f"
|
||||
checksum = "51ee14e256b9143bfafbf2fddeede6f396650bacf95d06fc1b3f2b503df129a0"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"futures-buffered",
|
||||
"futures-core",
|
||||
"futures-lite 1.13.0",
|
||||
"pin-project",
|
||||
@@ -2575,6 +2643,22 @@ 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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "genawaiter-macro"
|
||||
version = "0.99.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
@@ -2696,7 +2780,7 @@ dependencies = [
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"indexmap",
|
||||
"indexmap 2.2.5",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@@ -2715,7 +2799,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.1.0",
|
||||
"indexmap",
|
||||
"indexmap 2.2.5",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@@ -2732,6 +2816,12 @@ dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
@@ -2747,7 +2837,7 @@ version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3015,6 +3105,20 @@ dependencies = [
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"hyper 0.14.28",
|
||||
"rustls 0.21.11",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.27.2"
|
||||
@@ -3182,6 +3286,17 @@ dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.5"
|
||||
@@ -3189,7 +3304,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
"hashbrown 0.14.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3274,9 +3390,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iroh-base"
|
||||
version = "0.22.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24ddb47e8160fb1d563a6f541c813c2f185423a0ad1c9260a6c76891a2300c26"
|
||||
checksum = "f31f493beda1c4f8c7be999eff8a80cd1e2428da4c61f5cdd14990af8122342e"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"anyhow",
|
||||
@@ -3315,19 +3431,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iroh-gossip"
|
||||
version = "0.22.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c13f9a1da4e901f4d7e78b13139b372b361ed41fa9521a13432783880035a19a"
|
||||
checksum = "60a25bef4066809009d90cb5ff885c0d1adf77690805431f45577e624af0b4c6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel 2.3.1",
|
||||
"bytes",
|
||||
"derive_more 1.0.0-beta.7",
|
||||
"ed25519-dalek 2.1.1",
|
||||
"futures-concurrency",
|
||||
"futures-lite 2.3.0",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"genawaiter",
|
||||
"indexmap 2.2.5",
|
||||
"iroh-base",
|
||||
"iroh-blake3",
|
||||
"iroh-metrics",
|
||||
@@ -3343,9 +3457,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iroh-metrics"
|
||||
version = "0.22.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ab017d2786c0b77583371cef016d3e76bdbc7d13b66532023cb7e854f65d15a"
|
||||
checksum = "472ec21d59b34c8fbebbd8fcecfdc0f4b00a7af2d6453b303a1e9c9499674f67"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"erased_set",
|
||||
@@ -3354,7 +3468,7 @@ dependencies = [
|
||||
"hyper-util",
|
||||
"once_cell",
|
||||
"prometheus-client",
|
||||
"reqwest",
|
||||
"reqwest 0.12.5",
|
||||
"serde",
|
||||
"struct_iterable",
|
||||
"time 0.3.36",
|
||||
@@ -3364,18 +3478,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iroh-net"
|
||||
version = "0.22.0"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "372fbf01dc303be5427b6ea33b80411b3cfb6443d6389ce1ffc43231f244a51c"
|
||||
checksum = "7a3e2e9b2a555736a82cb53d16037b0ba0233034ac5042efce129b1460b0a50a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel 2.3.1",
|
||||
"axum",
|
||||
"backoff",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"clap",
|
||||
"der 0.7.8",
|
||||
"derive_more 1.0.0-beta.7",
|
||||
"duct",
|
||||
"flume",
|
||||
"futures-buffered",
|
||||
"futures-concurrency",
|
||||
"futures-lite 2.3.0",
|
||||
@@ -3410,12 +3526,15 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"rcgen 0.12.1",
|
||||
"reqwest",
|
||||
"regex",
|
||||
"reqwest 0.12.5",
|
||||
"ring 0.17.8",
|
||||
"rtnetlink",
|
||||
"rustls 0.21.11",
|
||||
"rustls-pemfile 1.0.4",
|
||||
"rustls-webpki 0.101.7",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"smallvec",
|
||||
"socket2",
|
||||
"strum",
|
||||
@@ -3425,10 +3544,13 @@ dependencies = [
|
||||
"time 0.3.36",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
"tokio-rustls-acme",
|
||||
"tokio-tungstenite",
|
||||
"tokio-tungstenite-wasm",
|
||||
"tokio-util",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tungstenite",
|
||||
"url",
|
||||
"watchable",
|
||||
@@ -3611,16 +3733,16 @@ version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"libc",
|
||||
"redox_syscall 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
|
||||
checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"openssl-sys",
|
||||
@@ -3761,13 +3883,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3937,7 +4060,7 @@ version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
@@ -4124,7 +4247,16 @@ version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff"
|
||||
dependencies = [
|
||||
"asn1-rs",
|
||||
"asn1-rs 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oid-registry"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d"
|
||||
dependencies = [
|
||||
"asn1-rs 0.6.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4151,7 +4283,7 @@ version = "0.10.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
@@ -4867,7 +4999,7 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
@@ -5158,7 +5290,7 @@ version = "11.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5236,9 +5368,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.6"
|
||||
version = "1.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -5284,6 +5416,47 @@ version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.3.26",
|
||||
"http 0.2.12",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.28",
|
||||
"hyper-rustls 0.24.2",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls 0.21.11",
|
||||
"rustls-pemfile 1.0.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper 0.1.2",
|
||||
"system-configuration 0.5.1",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots 0.25.4",
|
||||
"winreg 0.50.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.5"
|
||||
@@ -5300,7 +5473,7 @@ dependencies = [
|
||||
"http-body 1.0.0",
|
||||
"http-body-util",
|
||||
"hyper 1.2.0",
|
||||
"hyper-rustls",
|
||||
"hyper-rustls 0.27.2",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"ipnet",
|
||||
@@ -5464,11 +5637,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.32.1"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
|
||||
checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
@@ -5518,7 +5691,7 @@ version = "0.38.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
@@ -5622,7 +5795,7 @@ version = "14.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"cfg-if",
|
||||
"clipboard-win",
|
||||
"fd-lock",
|
||||
@@ -5789,9 +5962,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.205"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@@ -5816,9 +5989,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.205"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5879,6 +6052,36 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.2.5",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serde_with_macros",
|
||||
"time 0.3.36",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350"
|
||||
dependencies = [
|
||||
"darling 0.20.9",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serdect"
|
||||
version = "0.2.0"
|
||||
@@ -6015,7 +6218,7 @@ version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01607fe2e61894468c6dc0b26103abb073fb08b79a3d9e4b6d76a1a341549958"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6331,6 +6534,17 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.26.9"
|
||||
@@ -6362,7 +6576,7 @@ version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.4.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys 0.6.0",
|
||||
]
|
||||
@@ -6535,21 +6749,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.38.1"
|
||||
version = "1.39.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df"
|
||||
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
|
||||
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]]
|
||||
@@ -6564,9 +6777,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",
|
||||
@@ -6604,6 +6817,34 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls-acme"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ebc06d846f8367f24c3a8882328707d1a5e507ef4f40943723ddbe2c17b9f24"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.21.7",
|
||||
"chrono",
|
||||
"futures",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"pem 3.0.4",
|
||||
"proc-macro2",
|
||||
"rcgen 0.12.1",
|
||||
"reqwest 0.11.27",
|
||||
"ring 0.17.8",
|
||||
"rustls 0.21.11",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
"url",
|
||||
"webpki-roots 0.25.4",
|
||||
"x509-parser 0.16.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-serde"
|
||||
version = "0.8.0"
|
||||
@@ -6715,7 +6956,7 @@ version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 2.2.5",
|
||||
"toml_datetime",
|
||||
"winnow 0.5.40",
|
||||
]
|
||||
@@ -6726,7 +6967,7 @@ version = "0.22.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"indexmap 2.2.5",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@@ -7590,13 +7831,13 @@ version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8"
|
||||
dependencies = [
|
||||
"asn1-rs",
|
||||
"asn1-rs 0.5.2",
|
||||
"base64 0.13.1",
|
||||
"data-encoding",
|
||||
"der-parser",
|
||||
"der-parser 8.2.0",
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"oid-registry",
|
||||
"oid-registry 0.6.1",
|
||||
"rusticata-macros",
|
||||
"thiserror",
|
||||
"time 0.3.36",
|
||||
@@ -7608,12 +7849,29 @@ version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da"
|
||||
dependencies = [
|
||||
"asn1-rs",
|
||||
"asn1-rs 0.5.2",
|
||||
"data-encoding",
|
||||
"der-parser",
|
||||
"der-parser 8.2.0",
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"oid-registry",
|
||||
"oid-registry 0.6.1",
|
||||
"rusticata-macros",
|
||||
"thiserror",
|
||||
"time 0.3.36",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x509-parser"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69"
|
||||
dependencies = [
|
||||
"asn1-rs 0.6.1",
|
||||
"data-encoding",
|
||||
"der-parser 9.0.0",
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"oid-registry 0.7.0",
|
||||
"rusticata-macros",
|
||||
"thiserror",
|
||||
"time 0.3.36",
|
||||
|
||||
22
Cargo.toml
22
Cargo.toml
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
rust-version = "1.77"
|
||||
@@ -60,8 +60,9 @@ hickory-resolver = "0.24"
|
||||
humansize = "2"
|
||||
image = { version = "0.25.1", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] }
|
||||
iroh_old = { version = "0.4.2", default-features = false, package = "iroh"}
|
||||
iroh-net = { version = "0.22.0", default-features = false }
|
||||
iroh-gossip = { version = "0.22.0", default-features = false, features = ["net"] }
|
||||
iroh-net = { version = "0.21.0", default-features = false }
|
||||
iroh-gossip = { version = "0.21.0", default-features = false, features = ["net"] }
|
||||
quinn = "0.10.0"
|
||||
kamadak-exif = "0.5.3"
|
||||
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" }
|
||||
libc = { workspace = true }
|
||||
@@ -161,8 +162,8 @@ async-channel = "2.3.1"
|
||||
base64 = "0.22"
|
||||
chrono = { version = "0.4.38", default-features = false }
|
||||
deltachat-contact-tools = { path = "deltachat-contact-tools" }
|
||||
deltachat-jsonrpc = { path = "deltachat-jsonrpc" }
|
||||
deltachat = { path = "." }
|
||||
deltachat-jsonrpc = { path = "deltachat-jsonrpc", default-features = false }
|
||||
deltachat = { path = ".", default-features = false }
|
||||
futures = "0.3.30"
|
||||
futures-lite = "2.3.0"
|
||||
libc = "0.2"
|
||||
@@ -171,20 +172,13 @@ num-traits = "0.2"
|
||||
once_cell = "1.18.0"
|
||||
rand = "0.8"
|
||||
regex = "1.10"
|
||||
rusqlite = "0.32"
|
||||
rusqlite = "0.31"
|
||||
sanitize-filename = "0.5"
|
||||
serde_json = "1"
|
||||
serde = "1.0"
|
||||
tempfile = "3.10.1"
|
||||
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.39.2"
|
||||
tokio-util = "0.7.11"
|
||||
tracing-subscriber = "0.3"
|
||||
yerpc = "0.6.2"
|
||||
|
||||
@@ -30,13 +30,13 @@ $ curl https://sh.rustup.rs -sSf | sh
|
||||
Compile and run Delta Chat Core command line utility, using `cargo`:
|
||||
|
||||
```
|
||||
$ cargo run --locked -p deltachat-repl -- ~/deltachat-db
|
||||
$ cargo run -p deltachat-repl -- ~/deltachat-db
|
||||
```
|
||||
where ~/deltachat-db is the database file. Delta Chat will create it if it does not exist.
|
||||
|
||||
Optionally, install `deltachat-repl` binary with
|
||||
```
|
||||
$ cargo install --locked --path deltachat-repl/
|
||||
$ cargo install --path deltachat-repl/
|
||||
```
|
||||
and run as
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat_ffi"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
description = "Deltachat FFI"
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
|
||||
@@ -409,7 +409,7 @@ char* dc_get_blobdir (const dc_context_t* context);
|
||||
* - `socks5_user` = SOCKS5 proxy username
|
||||
* - `socks5_password` = SOCKS5 proxy password
|
||||
* - `imap_certificate_checks` = how to check IMAP certificates, one of the @ref DC_CERTCK flags, defaults to #DC_CERTCK_AUTO (0)
|
||||
* - `smtp_certificate_checks` = deprecated option, should be set to the same value as `imap_certificate_checks` but ignored by the new core
|
||||
* - `smtp_certificate_checks` = how to check SMTP certificates, one of the @ref DC_CERTCK flags, defaults to #DC_CERTCK_AUTO (0)
|
||||
* - `displayname` = Own name to use when sending messages. MUAs are allowed to spread this way e.g. using CC, defaults to empty
|
||||
* - `selfstatus` = Own status to display, e.g. in e-mail footers, defaults to empty
|
||||
* - `selfavatar` = File containing avatar. Will immediately be copied to the
|
||||
@@ -420,8 +420,7 @@ char* dc_get_blobdir (const dc_context_t* context);
|
||||
* and also recoded to a reasonable size.
|
||||
* - `e2ee_enabled` = 0=no end-to-end-encryption, 1=prefer end-to-end-encryption (default)
|
||||
* - `mdns_enabled` = 0=do not send or request read receipts,
|
||||
* 1=send and request read receipts
|
||||
* default=send and request read receipts, only send but not reuqest if `bot` is set
|
||||
* 1=send and request read receipts (default)
|
||||
* - `bcc_self` = 0=do not send a copy of outgoing messages to self (default),
|
||||
* 1=send a copy of outgoing messages to self.
|
||||
* Sending messages to self is needed for a proper multi-account setup,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-jsonrpc"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
description = "DeltaChat JSON-RPC API"
|
||||
edition = "2021"
|
||||
default-run = "deltachat-jsonrpc-server"
|
||||
|
||||
@@ -1672,10 +1672,10 @@ impl CommandApi {
|
||||
///
|
||||
/// This call will block until the QR code is ready,
|
||||
/// even if there is no concurrent call to [`CommandApi::provide_backup`],
|
||||
/// but will fail after 60 seconds to avoid deadlocks.
|
||||
/// but will fail after 10 seconds to avoid deadlocks.
|
||||
async fn get_backup_qr(&self, account_id: u32) -> Result<String> {
|
||||
let qr = tokio::time::timeout(
|
||||
Duration::from_secs(60),
|
||||
Duration::from_secs(10),
|
||||
self.inner_get_backup_qr(account_id),
|
||||
)
|
||||
.await
|
||||
@@ -1691,13 +1691,13 @@ impl CommandApi {
|
||||
///
|
||||
/// This call will block until the QR code is ready,
|
||||
/// even if there is no concurrent call to [`CommandApi::provide_backup`],
|
||||
/// but will fail after 60 seconds to avoid deadlocks.
|
||||
/// but will fail after 10 seconds to avoid deadlocks.
|
||||
///
|
||||
/// Returns the QR code rendered as an SVG image.
|
||||
async fn get_backup_qr_svg(&self, account_id: u32) -> Result<String> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
let qr = tokio::time::timeout(
|
||||
Duration::from_secs(60),
|
||||
Duration::from_secs(10),
|
||||
self.inner_get_backup_qr(account_id),
|
||||
)
|
||||
.await
|
||||
|
||||
@@ -58,5 +58,5 @@
|
||||
},
|
||||
"type": "module",
|
||||
"types": "dist/deltachat.d.ts",
|
||||
"version": "1.142.6"
|
||||
"version": "1.142.2"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-repl"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/deltachat/deltachat-core-rust"
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "deltachat-rpc-client"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
description = "Python client for Delta Chat core JSON-RPC interface"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
|
||||
@@ -114,13 +114,13 @@ class ACFactory:
|
||||
return to_client.run_until(lambda e: e.kind == EventType.INCOMING_MSG)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def rpc(tmp_path) -> AsyncGenerator:
|
||||
rpc_server = Rpc(accounts_dir=str(tmp_path / "accounts"))
|
||||
with rpc_server:
|
||||
yield rpc_server
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def acfactory(rpc) -> AsyncGenerator:
|
||||
return ACFactory(DeltaChat(rpc))
|
||||
|
||||
@@ -12,11 +12,10 @@ import threading
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
from deltachat_rpc_client import EventType
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture()
|
||||
def path_to_webxdc(request):
|
||||
p = request.path.parent.parent.parent.joinpath("test-data/webxdc/chess.xdc")
|
||||
assert p.exists()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
from deltachat_rpc_client import Chat, EventType, SpecialContactId
|
||||
|
||||
|
||||
|
||||
@@ -3,13 +3,11 @@ import concurrent.futures
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import subprocess
|
||||
import time
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from deltachat_rpc_client import Contact, EventType, Message, events
|
||||
from deltachat_rpc_client.const import DownloadState, MessageState
|
||||
from deltachat_rpc_client.direct_imap import DirectImap
|
||||
@@ -71,18 +69,6 @@ def test_configure_starttls(acfactory) -> None:
|
||||
assert account.is_configured()
|
||||
|
||||
|
||||
def test_configure_ip(acfactory) -> None:
|
||||
account = acfactory.new_preconfigured_account()
|
||||
|
||||
domain = account.get_config("addr").rsplit("@")[-1]
|
||||
ip_address = socket.gethostbyname(domain)
|
||||
|
||||
# This should fail TLS check.
|
||||
account.set_config("mail_server", ip_address)
|
||||
with pytest.raises(JsonRpcError):
|
||||
account.configure()
|
||||
|
||||
|
||||
def test_account(acfactory) -> None:
|
||||
alice, bob = acfactory.get_online_accounts(2)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-rpc-server"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
description = "DeltaChat JSON-RPC server"
|
||||
edition = "2021"
|
||||
readme = "README.md"
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
},
|
||||
"type": "module",
|
||||
"types": "index.d.ts",
|
||||
"version": "1.142.6"
|
||||
"version": "1.142.2"
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ skip = [
|
||||
{ name = "h2", version = "0.3.26" },
|
||||
{ name = "http-body", version = "0.4.6" },
|
||||
{ name = "http", version = "0.2.12" },
|
||||
{ name = "hyper-rustls", version = "0.24.2" },
|
||||
{ name = "hyper", version = "0.14.28" },
|
||||
{ name = "idna", version = "0.4.0" },
|
||||
{ name = "netlink-packet-core", version = "0.5.0" },
|
||||
@@ -74,6 +75,7 @@ skip = [
|
||||
{ name = "redox_syscall", version = "0.3.5" },
|
||||
{ name = "regex-automata", version = "0.1.10" },
|
||||
{ name = "regex-syntax", version = "0.6.29" },
|
||||
{ name = "reqwest", version = "0.11.27" },
|
||||
{ name = "ring", version = "0.16.20" },
|
||||
{ name = "rustls-pemfile", version = "1.0.4" },
|
||||
{ name = "rustls", version = "0.21.11" },
|
||||
|
||||
@@ -55,5 +55,5 @@
|
||||
"test:mocha": "mocha node/test/test.mjs --growl --reporter=spec --bail --exit"
|
||||
},
|
||||
"types": "node/dist/index.d.ts",
|
||||
"version": "1.142.6"
|
||||
"version": "1.142.2"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "deltachat"
|
||||
version = "1.142.6"
|
||||
version = "1.142.2"
|
||||
description = "Python bindings for the Delta Chat Core library using CFFI against the Rust-implemented libdeltachat"
|
||||
readme = "README.rst"
|
||||
requires-python = ">=3.7"
|
||||
|
||||
@@ -484,16 +484,6 @@ def test_move_works_on_self_sent(acfactory):
|
||||
ac1._evtracker.get_matching("DC_EVENT_IMAP_MESSAGE_MOVED")
|
||||
|
||||
|
||||
def test_move_sync_msgs(acfactory):
|
||||
ac1 = acfactory.new_online_configuring_account(bcc_self=True, sync_msgs=True, fix_is_chatmail=True)
|
||||
acfactory.bring_accounts_online()
|
||||
|
||||
ac1.set_config("displayname", "Alice")
|
||||
ac1._evtracker.get_matching("DC_EVENT_IMAP_MESSAGE_MOVED")
|
||||
ac1.set_config("displayname", "Bob")
|
||||
ac1._evtracker.get_matching("DC_EVENT_IMAP_MESSAGE_MOVED")
|
||||
|
||||
|
||||
def test_forward_messages(acfactory, lp):
|
||||
ac1, ac2 = acfactory.get_online_accounts(2)
|
||||
chat = ac1.create_chat(ac2)
|
||||
|
||||
@@ -1 +1 @@
|
||||
2024-08-15
|
||||
2024-08-02
|
||||
@@ -7,7 +7,7 @@ set -euo pipefail
|
||||
#
|
||||
# Avoid using rustup here as it depends on reading /proc/self/exe and
|
||||
# has problems running under QEMU.
|
||||
RUST_VERSION=1.80.1
|
||||
RUST_VERSION=1.80.0
|
||||
|
||||
ARCH="$(uname -m)"
|
||||
test -f "/lib/libc.musl-$ARCH.so.1" && LIBC=musl || LIBC=gnu
|
||||
|
||||
@@ -3,4 +3,4 @@ set -euo pipefail
|
||||
|
||||
tox -c deltachat-rpc-client -e py --devenv venv
|
||||
venv/bin/pip install --upgrade pip
|
||||
cargo install --locked --path deltachat-rpc-server/ --root "$PWD/venv" --debug
|
||||
cargo install --path deltachat-rpc-server/ --root "$PWD/venv" --debug
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cargo install --locked --path deltachat-rpc-server/ --root "$PWD/venv" --debug
|
||||
cargo install --path deltachat-rpc-server/ --root "$PWD/venv" --debug
|
||||
PATH="$PWD/venv/bin:$PATH" tox -c deltachat-rpc-client
|
||||
|
||||
@@ -6,7 +6,7 @@ set -euo pipefail
|
||||
export TZ=UTC
|
||||
|
||||
# Provider database revision.
|
||||
REV=05c1b2029da74718e4bdc3799a46e29c4f794dc7
|
||||
REV=828e5ddc7e6609b582fbd7f063cc3f60b580ce96
|
||||
|
||||
CORE_ROOT="$PWD"
|
||||
TMP="$(mktemp -d)"
|
||||
|
||||
@@ -13,7 +13,7 @@ use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
|
||||
use tokio::fs;
|
||||
|
||||
use crate::blob::BlobObject;
|
||||
use crate::constants;
|
||||
use crate::constants::{self, DC_VERSION_STR};
|
||||
use crate::context::Context;
|
||||
use crate::events::EventType;
|
||||
use crate::log::LogExt;
|
||||
@@ -59,10 +59,7 @@ pub enum Config {
|
||||
/// IMAP server security (e.g. TLS, STARTTLS).
|
||||
MailSecurity,
|
||||
|
||||
/// How to check TLS certificates.
|
||||
///
|
||||
/// "IMAP" in the name is for compatibility,
|
||||
/// this actually applies to both IMAP and SMTP connections.
|
||||
/// How to check IMAP server TLS certificates.
|
||||
ImapCertificateChecks,
|
||||
|
||||
/// SMTP server hostname.
|
||||
@@ -80,9 +77,7 @@ pub enum Config {
|
||||
/// SMTP server security (e.g. TLS, STARTTLS).
|
||||
SendSecurity,
|
||||
|
||||
/// Deprecated option for backwards compatibilty.
|
||||
///
|
||||
/// Certificate checks for SMTP are actually controlled by `imap_certificate_checks` config.
|
||||
/// How to check SMTP server TLS certificates.
|
||||
SmtpCertificateChecks,
|
||||
|
||||
/// Whether to use OAuth 2.
|
||||
@@ -129,14 +124,14 @@ pub enum Config {
|
||||
|
||||
/// True if Message Delivery Notifications (read receipts) should
|
||||
/// be sent and requested.
|
||||
#[strum(props(default = "1"))]
|
||||
MdnsEnabled,
|
||||
|
||||
/// True if "Sent" folder should be watched for changes.
|
||||
#[strum(props(default = "0"))]
|
||||
SentboxWatch,
|
||||
|
||||
/// True if chat messages should be moved to a separate folder. Auto-sent messages like sync
|
||||
/// ones are moved there anyway.
|
||||
/// True if chat messages should be moved to a separate folder.
|
||||
#[strum(props(default = "1"))]
|
||||
MvboxMove,
|
||||
|
||||
@@ -214,12 +209,7 @@ pub enum Config {
|
||||
/// Configured IMAP server security (e.g. TLS, STARTTLS).
|
||||
ConfiguredMailSecurity,
|
||||
|
||||
/// Configured TLS certificate checks.
|
||||
/// This option is saved on successful configuration
|
||||
/// and should not be modified manually.
|
||||
///
|
||||
/// This actually applies to both IMAP and SMTP connections,
|
||||
/// but has "IMAP" in the name for backwards compatibility.
|
||||
/// How to check IMAP server TLS certificates.
|
||||
ConfiguredImapCertificateChecks,
|
||||
|
||||
/// Configured SMTP server hostname.
|
||||
@@ -234,9 +224,7 @@ pub enum Config {
|
||||
/// Configured SMTP server port.
|
||||
ConfiguredSendPort,
|
||||
|
||||
/// Deprecated, stored for backwards compatibility.
|
||||
///
|
||||
/// ConfiguredImapCertificateChecks is actually used.
|
||||
/// How to check SMTP server TLS certificates.
|
||||
ConfiguredSmtpCertificateChecks,
|
||||
|
||||
/// Whether OAuth 2 is used with configured provider.
|
||||
@@ -269,9 +257,6 @@ pub enum Config {
|
||||
/// True if account is a chatmail account.
|
||||
IsChatmail,
|
||||
|
||||
/// True if `IsChatmail` mustn't be autoconfigured. For tests.
|
||||
FixIsChatmail,
|
||||
|
||||
/// True if account is muted.
|
||||
IsMuted,
|
||||
|
||||
@@ -397,6 +382,9 @@ impl Config {
|
||||
/// multiple users are sharing an account. Another example is `Self::SyncMsgs` itself which
|
||||
/// mustn't be controlled by other devices.
|
||||
pub(crate) fn is_synced(&self) -> bool {
|
||||
// NB: We don't restart IO from the synchronisation code, so `MvboxMove` isn't effective
|
||||
// immediately if `ConfiguredMvboxFolder` is unset, but only after a reconnect (see
|
||||
// `Imap::prepare()`).
|
||||
matches!(
|
||||
self,
|
||||
Self::Displayname
|
||||
@@ -410,7 +398,10 @@ impl Config {
|
||||
|
||||
/// Whether the config option needs an IO scheduler restart to take effect.
|
||||
pub(crate) fn needs_io_restart(&self) -> bool {
|
||||
matches!(self, Config::OnlyFetchMvbox | Config::SentboxWatch)
|
||||
matches!(
|
||||
self,
|
||||
Config::MvboxMove | Config::OnlyFetchMvbox | Config::SentboxWatch
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +427,7 @@ impl Context {
|
||||
.into_owned()
|
||||
})
|
||||
}
|
||||
Config::SysVersion => Some((*constants::DC_VERSION_STR).clone()),
|
||||
Config::SysVersion => Some((*DC_VERSION_STR).clone()),
|
||||
Config::SysMsgsizeMaxRecommended => Some(format!("{RECOMMENDED_FILE_SIZE}")),
|
||||
Config::SysConfigKeys => Some(get_config_keys_string()),
|
||||
_ => self.sql.get_raw_config(key.as_ref()).await?,
|
||||
@@ -494,8 +485,7 @@ impl Context {
|
||||
/// Returns true if movebox ("DeltaChat" folder) should be watched.
|
||||
pub(crate) async fn should_watch_mvbox(&self) -> Result<bool> {
|
||||
Ok(self.get_config_bool(Config::MvboxMove).await?
|
||||
|| self.get_config_bool(Config::OnlyFetchMvbox).await?
|
||||
|| !self.get_config_bool(Config::IsChatmail).await?)
|
||||
|| self.get_config_bool(Config::OnlyFetchMvbox).await?)
|
||||
}
|
||||
|
||||
/// Returns true if sentbox ("Sent" folder) should be watched.
|
||||
@@ -514,22 +504,6 @@ impl Context {
|
||||
&& !self.get_config_bool(Config::Bot).await?)
|
||||
}
|
||||
|
||||
/// Returns whether MDNs should be requested.
|
||||
pub(crate) async fn should_request_mdns(&self) -> Result<bool> {
|
||||
match self.get_config_bool_opt(Config::MdnsEnabled).await? {
|
||||
Some(val) => Ok(val),
|
||||
None => Ok(!self.get_config_bool(Config::Bot).await?),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether MDNs should be sent.
|
||||
pub(crate) async fn should_send_mdns(&self) -> Result<bool> {
|
||||
Ok(self
|
||||
.get_config_bool_opt(Config::MdnsEnabled)
|
||||
.await?
|
||||
.unwrap_or(true))
|
||||
}
|
||||
|
||||
/// Gets configured "delete_server_after" value.
|
||||
///
|
||||
/// `None` means never delete the message, `Some(0)` means delete
|
||||
@@ -979,17 +953,6 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_mdns_default_behaviour() -> Result<()> {
|
||||
let t = &TestContext::new_alice().await;
|
||||
assert!(t.should_request_mdns().await?);
|
||||
assert!(t.should_send_mdns().await?);
|
||||
t.set_config_bool(Config::Bot, true).await?;
|
||||
assert!(!t.should_request_mdns().await?);
|
||||
assert!(t.should_send_mdns().await?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_sync() -> Result<()> {
|
||||
let alice0 = TestContext::new_alice().await;
|
||||
@@ -1016,6 +979,7 @@ mod tests {
|
||||
// Reset to default. Test that it's not synced because defaults may differ across client
|
||||
// versions.
|
||||
alice0.set_config(Config::MdnsEnabled, None).await?;
|
||||
assert_eq!(alice0.get_config_bool(Config::MdnsEnabled).await?, true);
|
||||
alice0.set_config_bool(Config::MdnsEnabled, false).await?;
|
||||
sync(&alice0, &alice1).await;
|
||||
assert_eq!(alice1.get_config_bool(Config::MdnsEnabled).await?, false);
|
||||
|
||||
102
src/configure.rs
102
src/configure.rs
@@ -27,7 +27,7 @@ use crate::config::{self, Config};
|
||||
use crate::context::Context;
|
||||
use crate::imap::{session::Session as ImapSession, Imap};
|
||||
use crate::log::LogExt;
|
||||
use crate::login_param::{LoginParam, ServerLoginParam};
|
||||
use crate::login_param::{CertificateChecks, LoginParam, ServerLoginParam};
|
||||
use crate::message::{Message, Viewtype};
|
||||
use crate::oauth2::get_oauth2_addr;
|
||||
use crate::provider::{Protocol, Socket, UsernamePattern};
|
||||
@@ -189,8 +189,10 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
|
||||
// Step 1: Load the parameters and check email-address and password
|
||||
|
||||
// OAuth is always set either for both IMAP and SMTP or not at all.
|
||||
if param.imap.oauth2 {
|
||||
// Do oauth2 only if socks5 is disabled. As soon as we have a http library that can do
|
||||
// socks5 requests, this can work with socks5 too. OAuth is always set either for both
|
||||
// IMAP and SMTP or not at all.
|
||||
if param.imap.oauth2 && !socks5_enabled {
|
||||
// the used oauth2 addr may differ, check this.
|
||||
// if get_oauth2_addr() is not available in the oauth2 implementation, just use the given one.
|
||||
progress!(ctx, 10);
|
||||
@@ -210,6 +212,7 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
|
||||
let parsed = EmailAddress::new(¶m.addr).context("Bad email-address")?;
|
||||
let param_domain = parsed.domain;
|
||||
let param_addr_urlencoded = utf8_percent_encode(¶m.addr, NON_ALPHANUMERIC).to_string();
|
||||
|
||||
// Step 2: Autoconfig
|
||||
progress!(ctx, 200);
|
||||
@@ -260,6 +263,7 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
}
|
||||
}
|
||||
},
|
||||
strict_tls: Some(provider.opt.strict_tls),
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -274,14 +278,19 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
} else {
|
||||
// Try receiving autoconfig
|
||||
info!(ctx, "no offline autoconfig found");
|
||||
param_autoconfig = get_autoconfig(ctx, param, ¶m_domain).await;
|
||||
param_autoconfig = if socks5_enabled {
|
||||
// Currently we can't do http requests through socks5, to not leak
|
||||
// the ip, just don't do online autoconfig
|
||||
info!(ctx, "socks5 enabled, skipping autoconfig");
|
||||
None
|
||||
} else {
|
||||
get_autoconfig(ctx, param, ¶m_domain, ¶m_addr_urlencoded).await
|
||||
}
|
||||
}
|
||||
} else {
|
||||
param_autoconfig = None;
|
||||
}
|
||||
|
||||
let strict_tls = param.strict_tls();
|
||||
|
||||
progress!(ctx, 500);
|
||||
|
||||
let mut servers = param_autoconfig.unwrap_or_default();
|
||||
@@ -295,6 +304,7 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
port: param.imap.port,
|
||||
socket: param.imap.security,
|
||||
username: param.imap.user.clone(),
|
||||
strict_tls: None,
|
||||
})
|
||||
}
|
||||
if !servers
|
||||
@@ -307,9 +317,24 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
port: param.smtp.port,
|
||||
socket: param.smtp.security,
|
||||
username: param.smtp.user.clone(),
|
||||
strict_tls: None,
|
||||
})
|
||||
}
|
||||
|
||||
// respect certificate setting from function parameters
|
||||
for server in &mut servers {
|
||||
let certificate_checks = match server.protocol {
|
||||
Protocol::Imap => param.imap.certificate_checks,
|
||||
Protocol::Smtp => param.smtp.certificate_checks,
|
||||
};
|
||||
server.strict_tls = match certificate_checks {
|
||||
CertificateChecks::AcceptInvalidCertificates
|
||||
| CertificateChecks::AcceptInvalidCertificates2 => Some(false),
|
||||
CertificateChecks::Strict => Some(true),
|
||||
CertificateChecks::Automatic => server.strict_tls,
|
||||
};
|
||||
}
|
||||
|
||||
let servers = expand_param_vector(servers, ¶m.addr, ¶m_domain);
|
||||
|
||||
progress!(ctx, 550);
|
||||
@@ -325,6 +350,9 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
.filter(|params| params.protocol == Protocol::Smtp)
|
||||
.cloned()
|
||||
.collect();
|
||||
let provider_strict_tls = param
|
||||
.provider
|
||||
.map_or(socks5_config.is_some(), |provider| provider.opt.strict_tls);
|
||||
|
||||
let smtp_config_task = task::spawn(async move {
|
||||
let mut smtp_configured = false;
|
||||
@@ -334,13 +362,18 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
smtp_param.server.clone_from(&smtp_server.hostname);
|
||||
smtp_param.port = smtp_server.port;
|
||||
smtp_param.security = smtp_server.socket;
|
||||
smtp_param.certificate_checks = match smtp_server.strict_tls {
|
||||
Some(true) => CertificateChecks::Strict,
|
||||
Some(false) => CertificateChecks::AcceptInvalidCertificates,
|
||||
None => CertificateChecks::Automatic,
|
||||
};
|
||||
|
||||
match try_smtp_one_param(
|
||||
&context_smtp,
|
||||
&smtp_param,
|
||||
&socks5_config,
|
||||
&smtp_addr,
|
||||
strict_tls,
|
||||
provider_strict_tls,
|
||||
&mut smtp,
|
||||
)
|
||||
.await
|
||||
@@ -376,13 +409,18 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
param.imap.server.clone_from(&imap_server.hostname);
|
||||
param.imap.port = imap_server.port;
|
||||
param.imap.security = imap_server.socket;
|
||||
param.imap.certificate_checks = match imap_server.strict_tls {
|
||||
Some(true) => CertificateChecks::Strict,
|
||||
Some(false) => CertificateChecks::AcceptInvalidCertificates,
|
||||
None => CertificateChecks::Automatic,
|
||||
};
|
||||
|
||||
match try_imap_one_param(
|
||||
ctx,
|
||||
¶m.imap,
|
||||
¶m.socks5_config,
|
||||
¶m.addr,
|
||||
strict_tls,
|
||||
provider_strict_tls,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -416,30 +454,19 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
|
||||
progress!(ctx, 900);
|
||||
|
||||
let is_chatmail = match ctx.get_config_bool(Config::FixIsChatmail).await? {
|
||||
false => {
|
||||
let is_chatmail = imap_session.is_chatmail();
|
||||
ctx.set_config(
|
||||
Config::IsChatmail,
|
||||
Some(match is_chatmail {
|
||||
false => "0",
|
||||
true => "1",
|
||||
}),
|
||||
)
|
||||
.await?;
|
||||
is_chatmail
|
||||
}
|
||||
true => ctx.get_config_bool(Config::IsChatmail).await?,
|
||||
};
|
||||
if is_chatmail {
|
||||
if imap_session.is_chatmail() {
|
||||
ctx.set_config(Config::IsChatmail, Some("1")).await?;
|
||||
ctx.set_config(Config::SentboxWatch, None).await?;
|
||||
ctx.set_config(Config::MvboxMove, Some("0")).await?;
|
||||
ctx.set_config(Config::OnlyFetchMvbox, None).await?;
|
||||
ctx.set_config(Config::ShowEmails, None).await?;
|
||||
ctx.set_config(Config::E2eeEnabled, Some("1")).await?;
|
||||
} else {
|
||||
ctx.set_config(Config::IsChatmail, Some("0")).await?;
|
||||
}
|
||||
|
||||
let create_mvbox = !is_chatmail;
|
||||
let create_mvbox = ctx.should_watch_mvbox().await?;
|
||||
|
||||
imap.configure_folders(ctx, &mut imap_session, create_mvbox)
|
||||
.await?;
|
||||
|
||||
@@ -490,15 +517,14 @@ async fn get_autoconfig(
|
||||
ctx: &Context,
|
||||
param: &LoginParam,
|
||||
param_domain: &str,
|
||||
param_addr_urlencoded: &str,
|
||||
) -> Option<Vec<ServerParams>> {
|
||||
let param_addr_urlencoded = utf8_percent_encode(¶m.addr, NON_ALPHANUMERIC).to_string();
|
||||
|
||||
if let Ok(res) = moz_autoconfigure(
|
||||
ctx,
|
||||
&format!(
|
||||
"https://autoconfig.{param_domain}/mail/config-v1.1.xml?emailaddress={param_addr_urlencoded}"
|
||||
),
|
||||
¶m.addr,
|
||||
param,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -513,7 +539,7 @@ async fn get_autoconfig(
|
||||
"https://{}/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress={}",
|
||||
¶m_domain, ¶m_addr_urlencoded
|
||||
),
|
||||
¶m.addr,
|
||||
param,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -549,7 +575,7 @@ async fn get_autoconfig(
|
||||
if let Ok(res) = moz_autoconfigure(
|
||||
ctx,
|
||||
&format!("https://autoconfig.thunderbird.net/v1.1/{}", ¶m_domain),
|
||||
¶m.addr,
|
||||
param,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -564,15 +590,15 @@ async fn try_imap_one_param(
|
||||
param: &ServerLoginParam,
|
||||
socks5_config: &Option<Socks5Config>,
|
||||
addr: &str,
|
||||
strict_tls: bool,
|
||||
provider_strict_tls: bool,
|
||||
) -> Result<(Imap, ImapSession), ConfigurationError> {
|
||||
let inf = format!(
|
||||
"imap: {}@{}:{} security={} strict_tls={} oauth2={} socks5_config={}",
|
||||
"imap: {}@{}:{} security={} certificate_checks={} oauth2={} socks5_config={}",
|
||||
param.user,
|
||||
param.server,
|
||||
param.port,
|
||||
param.security,
|
||||
strict_tls,
|
||||
param.certificate_checks,
|
||||
param.oauth2,
|
||||
if let Some(socks5_config) = socks5_config {
|
||||
socks5_config.to_string()
|
||||
@@ -584,7 +610,7 @@ async fn try_imap_one_param(
|
||||
|
||||
let (_s, r) = async_channel::bounded(1);
|
||||
|
||||
let mut imap = match Imap::new(param, socks5_config.clone(), addr, strict_tls, r) {
|
||||
let mut imap = match Imap::new(param, socks5_config.clone(), addr, provider_strict_tls, r) {
|
||||
Err(err) => {
|
||||
info!(context, "failure: {:#}", err);
|
||||
return Err(ConfigurationError {
|
||||
@@ -615,16 +641,16 @@ async fn try_smtp_one_param(
|
||||
param: &ServerLoginParam,
|
||||
socks5_config: &Option<Socks5Config>,
|
||||
addr: &str,
|
||||
strict_tls: bool,
|
||||
provider_strict_tls: bool,
|
||||
smtp: &mut Smtp,
|
||||
) -> Result<(), ConfigurationError> {
|
||||
let inf = format!(
|
||||
"smtp: {}@{}:{} security={} strict_tls={} oauth2={} socks5_config={}",
|
||||
"smtp: {}@{}:{} security={} certificate_checks={} oauth2={} socks5_config={}",
|
||||
param.user,
|
||||
param.server,
|
||||
param.port,
|
||||
param.security,
|
||||
strict_tls,
|
||||
param.certificate_checks,
|
||||
param.oauth2,
|
||||
if let Some(socks5_config) = socks5_config {
|
||||
socks5_config.to_string()
|
||||
@@ -635,7 +661,7 @@ async fn try_smtp_one_param(
|
||||
info!(context, "Trying: {}", inf);
|
||||
|
||||
if let Err(err) = smtp
|
||||
.connect(context, param, socks5_config, addr, strict_tls)
|
||||
.connect(context, param, socks5_config, addr, provider_strict_tls)
|
||||
.await
|
||||
{
|
||||
info!(context, "SMTP failure: {err:#}.");
|
||||
|
||||
@@ -9,6 +9,7 @@ use quick_xml::events::{BytesStart, Event};
|
||||
|
||||
use super::{Error, ServerParams};
|
||||
use crate::context::Context;
|
||||
use crate::login_param::LoginParam;
|
||||
use crate::net::read_url;
|
||||
use crate::provider::{Protocol, Socket};
|
||||
|
||||
@@ -247,6 +248,7 @@ fn parse_serverparams(in_emailaddr: &str, xml_raw: &str) -> Result<Vec<ServerPar
|
||||
hostname: server.hostname,
|
||||
port: server.port,
|
||||
username: server.username,
|
||||
strict_tls: None,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
@@ -256,11 +258,11 @@ fn parse_serverparams(in_emailaddr: &str, xml_raw: &str) -> Result<Vec<ServerPar
|
||||
pub(crate) async fn moz_autoconfigure(
|
||||
context: &Context,
|
||||
url: &str,
|
||||
addr: &str,
|
||||
param_in: &LoginParam,
|
||||
) -> Result<Vec<ServerParams>, Error> {
|
||||
let xml_raw = read_url(context, url).await?;
|
||||
|
||||
let res = parse_serverparams(addr, &xml_raw);
|
||||
let res = parse_serverparams(¶m_in.addr, &xml_raw);
|
||||
if let Err(err) = &res {
|
||||
warn!(
|
||||
context,
|
||||
|
||||
@@ -187,6 +187,7 @@ fn protocols_to_serverparams(protocols: Vec<ProtocolTag>) -> Vec<ServerParams> {
|
||||
hostname: protocol.server,
|
||||
port: protocol.port,
|
||||
username: String::new(),
|
||||
strict_tls: None,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -22,6 +22,9 @@ pub(crate) struct ServerParams {
|
||||
|
||||
/// Username, empty if unknown.
|
||||
pub username: String,
|
||||
|
||||
/// Whether TLS certificates should be strictly checked or not, `None` for automatic.
|
||||
pub strict_tls: Option<bool>,
|
||||
}
|
||||
|
||||
impl ServerParams {
|
||||
@@ -122,6 +125,14 @@ impl ServerParams {
|
||||
vec![self]
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_strict_tls(self) -> Vec<ServerParams> {
|
||||
vec![Self {
|
||||
// Strict if not set by the user or provider database.
|
||||
strict_tls: Some(self.strict_tls.unwrap_or(true)),
|
||||
..self
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
/// Expands vector of `ServerParams`, replacing placeholders with
|
||||
@@ -135,6 +146,7 @@ pub(crate) fn expand_param_vector(
|
||||
// The order of expansion is important.
|
||||
//
|
||||
// Ports are expanded the last, so they are changed the first.
|
||||
.flat_map(|params| params.expand_strict_tls().into_iter())
|
||||
.flat_map(|params| params.expand_usernames(addr).into_iter())
|
||||
.flat_map(|params| params.expand_hostnames(domain).into_iter())
|
||||
.flat_map(|params| params.expand_ports().into_iter())
|
||||
@@ -154,6 +166,7 @@ mod tests {
|
||||
port: 0,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true),
|
||||
}],
|
||||
"foobar@example.net",
|
||||
"example.net",
|
||||
@@ -167,6 +180,7 @@ mod tests {
|
||||
port: 993,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
}],
|
||||
);
|
||||
|
||||
@@ -177,6 +191,7 @@ mod tests {
|
||||
port: 123,
|
||||
socket: Socket::Automatic,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: None,
|
||||
}],
|
||||
"foobar@example.net",
|
||||
"example.net",
|
||||
@@ -191,6 +206,7 @@ mod tests {
|
||||
port: 123,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true),
|
||||
},
|
||||
ServerParams {
|
||||
protocol: Protocol::Smtp,
|
||||
@@ -198,10 +214,12 @@ mod tests {
|
||||
port: 123,
|
||||
socket: Socket::Starttls,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
// Test that strict_tls is not expanded for plaintext connections.
|
||||
let v = expand_param_vector(
|
||||
vec![ServerParams {
|
||||
protocol: Protocol::Smtp,
|
||||
@@ -209,6 +227,7 @@ mod tests {
|
||||
port: 123,
|
||||
socket: Socket::Plain,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true),
|
||||
}],
|
||||
"foobar@example.net",
|
||||
"example.net",
|
||||
@@ -221,6 +240,7 @@ mod tests {
|
||||
port: 123,
|
||||
socket: Socket::Plain,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
}],
|
||||
);
|
||||
|
||||
@@ -232,6 +252,7 @@ mod tests {
|
||||
port: 10480,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true),
|
||||
}],
|
||||
"foobar@example.net",
|
||||
"example.net",
|
||||
@@ -245,6 +266,7 @@ mod tests {
|
||||
port: 10480,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
},
|
||||
ServerParams {
|
||||
protocol: Protocol::Imap,
|
||||
@@ -252,6 +274,7 @@ mod tests {
|
||||
port: 10480,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
},
|
||||
ServerParams {
|
||||
protocol: Protocol::Imap,
|
||||
@@ -259,6 +282,7 @@ mod tests {
|
||||
port: 10480,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
}
|
||||
],
|
||||
);
|
||||
@@ -272,6 +296,7 @@ mod tests {
|
||||
port: 0,
|
||||
socket: Socket::Automatic,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true),
|
||||
}],
|
||||
"foobar@example.net",
|
||||
"example.net",
|
||||
@@ -285,6 +310,7 @@ mod tests {
|
||||
port: 465,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
},
|
||||
ServerParams {
|
||||
protocol: Protocol::Smtp,
|
||||
@@ -292,6 +318,7 @@ mod tests {
|
||||
port: 587,
|
||||
socket: Socket::Starttls,
|
||||
username: "foobar".to_string(),
|
||||
strict_tls: Some(true)
|
||||
},
|
||||
],
|
||||
);
|
||||
@@ -311,6 +338,7 @@ mod tests {
|
||||
port: 0,
|
||||
socket: Socket::Automatic,
|
||||
username: "".to_string(),
|
||||
strict_tls: Some(true),
|
||||
}],
|
||||
"foobar@example.net",
|
||||
"example.net",
|
||||
@@ -324,6 +352,7 @@ mod tests {
|
||||
port: 993,
|
||||
socket: Socket::Ssl,
|
||||
username: "foobar@example.net".to_string(),
|
||||
strict_tls: Some(true)
|
||||
},
|
||||
ServerParams {
|
||||
protocol: Protocol::Imap,
|
||||
@@ -331,6 +360,7 @@ mod tests {
|
||||
port: 143,
|
||||
socket: Socket::Starttls,
|
||||
username: "foobar@example.net".to_string(),
|
||||
strict_tls: Some(true)
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
@@ -209,7 +209,7 @@ pub const WORSE_IMAGE_SIZE: u32 = 640;
|
||||
// Key for the folder configuration version (see below).
|
||||
pub(crate) const DC_FOLDERS_CONFIGURED_KEY: &str = "folders_configured";
|
||||
// this value can be increased if the folder configuration is changed and must be redone on next program start
|
||||
pub(crate) const DC_FOLDERS_CONFIGURED_VERSION: i32 = 5;
|
||||
pub(crate) const DC_FOLDERS_CONFIGURED_VERSION: i32 = 4;
|
||||
|
||||
// If more recipients are needed in SMTP's `RCPT TO:` header, the recipient list is split into
|
||||
// chunks. This does not affect MIME's `To:` header. Can be overwritten by setting
|
||||
|
||||
@@ -814,12 +814,6 @@ impl Context {
|
||||
}
|
||||
|
||||
res.insert("is_chatmail", self.is_chatmail().await?.to_string());
|
||||
res.insert(
|
||||
"fix_is_chatmail",
|
||||
self.get_config_bool(Config::FixIsChatmail)
|
||||
.await?
|
||||
.to_string(),
|
||||
);
|
||||
res.insert(
|
||||
"is_muted",
|
||||
self.get_config_bool(Config::IsMuted).await?.to_string(),
|
||||
|
||||
@@ -11,7 +11,6 @@ pub enum HeaderDef {
|
||||
Date,
|
||||
From_,
|
||||
To,
|
||||
AutoSubmitted,
|
||||
|
||||
/// Carbon copy.
|
||||
Cc,
|
||||
|
||||
80
src/imap.rs
80
src/imap.rs
@@ -32,7 +32,7 @@ use crate::contact::{Contact, ContactId, Modifier, Origin};
|
||||
use crate::context::Context;
|
||||
use crate::events::EventType;
|
||||
use crate::headerdef::{HeaderDef, HeaderDefMap};
|
||||
use crate::login_param::{LoginParam, ServerLoginParam};
|
||||
use crate::login_param::{CertificateChecks, LoginParam, ServerLoginParam};
|
||||
use crate::message::{self, Message, MessageState, MessengerMessage, MsgId, Viewtype};
|
||||
use crate::mimeparser;
|
||||
use crate::oauth2::get_oauth2_access_token;
|
||||
@@ -231,13 +231,20 @@ impl Imap {
|
||||
lp: &ServerLoginParam,
|
||||
socks5_config: Option<Socks5Config>,
|
||||
addr: &str,
|
||||
strict_tls: bool,
|
||||
provider_strict_tls: bool,
|
||||
idle_interrupt_receiver: Receiver<()>,
|
||||
) -> Result<Self> {
|
||||
if lp.server.is_empty() || lp.user.is_empty() || lp.password.is_empty() {
|
||||
bail!("Incomplete IMAP connection parameters");
|
||||
}
|
||||
|
||||
let strict_tls = match lp.certificate_checks {
|
||||
CertificateChecks::Automatic => provider_strict_tls,
|
||||
CertificateChecks::Strict => true,
|
||||
CertificateChecks::AcceptInvalidCertificates
|
||||
| CertificateChecks::AcceptInvalidCertificates2 => false,
|
||||
};
|
||||
|
||||
let imap = Imap {
|
||||
idle_interrupt_receiver,
|
||||
addr: addr.to_string(),
|
||||
@@ -265,11 +272,17 @@ impl Imap {
|
||||
}
|
||||
|
||||
let param = LoginParam::load_configured_params(context).await?;
|
||||
// the trailing underscore is correct
|
||||
|
||||
let imap = Self::new(
|
||||
¶m.imap,
|
||||
param.socks5_config.clone(),
|
||||
¶m.addr,
|
||||
param.strict_tls(),
|
||||
param
|
||||
.provider
|
||||
.map_or(param.socks5_config.is_some(), |provider| {
|
||||
provider.opt.strict_tls
|
||||
}),
|
||||
idle_interrupt_receiver,
|
||||
)?;
|
||||
Ok(imap)
|
||||
@@ -433,11 +446,7 @@ impl Imap {
|
||||
.get_raw_config_int(constants::DC_FOLDERS_CONFIGURED_KEY)
|
||||
.await?;
|
||||
if folders_configured.unwrap_or_default() < constants::DC_FOLDERS_CONFIGURED_VERSION {
|
||||
let is_chatmail = match context.get_config_bool(Config::FixIsChatmail).await? {
|
||||
false => session.is_chatmail(),
|
||||
true => context.get_config_bool(Config::IsChatmail).await?,
|
||||
};
|
||||
let create_mvbox = !is_chatmail || context.get_config_bool(Config::MvboxMove).await?;
|
||||
let create_mvbox = true;
|
||||
self.configure_folders(context, &mut session, create_mvbox)
|
||||
.await?;
|
||||
}
|
||||
@@ -1045,12 +1054,18 @@ impl Session {
|
||||
.await?;
|
||||
|
||||
for (folder, rowid_set, uid_set) in UidGrouper::from(rows) {
|
||||
if let Err(err) = self.select_with_uidvalidity(context, &folder).await {
|
||||
warn!(context, "store_seen_flags_on_imap: Failed to select {folder}, will retry later: {err:#}.");
|
||||
} else if let Err(err) = self.add_flag_finalized_with_set(&uid_set, "\\Seen").await {
|
||||
self.select_with_uidvalidity(context, &folder)
|
||||
.await
|
||||
.context("failed to select folder")?;
|
||||
|
||||
if let Err(err) = self.add_flag_finalized_with_set(&uid_set, "\\Seen").await {
|
||||
warn!(
|
||||
context,
|
||||
"Cannot mark messages {uid_set} in {folder} as seen, will retry later: {err:#}.");
|
||||
"Cannot mark messages {} in folder {} as seen, will retry later: {}.",
|
||||
uid_set,
|
||||
folder,
|
||||
err
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
context,
|
||||
@@ -1504,8 +1519,8 @@ impl Session {
|
||||
|
||||
/// Attempts to configure mvbox.
|
||||
///
|
||||
/// Tries to find any folder examining `folders` in the order they go. If none is found, tries
|
||||
/// to create any folder in the same order. This method does not use LIST command to ensure that
|
||||
/// Tries to find any folder in the given list of `folders`. If none is found, tries to create
|
||||
/// `folders[0]`. This method does not use LIST command to ensure that
|
||||
/// configuration works even if mailbox lookup is forbidden via Access Control List (see
|
||||
/// <https://datatracker.ietf.org/doc/html/rfc4314>).
|
||||
///
|
||||
@@ -1539,17 +1554,16 @@ impl Session {
|
||||
if !create_mvbox {
|
||||
return Ok(None);
|
||||
}
|
||||
// Some servers require namespace-style folder names like "INBOX.DeltaChat", so we try all
|
||||
// the variants here.
|
||||
for folder in folders {
|
||||
match self.select_with_uidvalidity(context, folder).await {
|
||||
Ok(_) => {
|
||||
info!(context, "MVBOX-folder {} created.", folder);
|
||||
return Ok(Some(folder));
|
||||
}
|
||||
Err(err) => {
|
||||
warn!(context, "Cannot create MVBOX-folder {:?}: {}", folder, err);
|
||||
}
|
||||
let Some(folder) = folders.first() else {
|
||||
return Ok(None);
|
||||
};
|
||||
match self.select_with_uidvalidity(context, folder).await {
|
||||
Ok(_) => {
|
||||
info!(context, "MVBOX-folder {} created.", folder);
|
||||
return Ok(Some(folder));
|
||||
}
|
||||
Err(err) => {
|
||||
warn!(context, "Cannot create MVBOX-folder {:?}: {}", folder, err);
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
@@ -1797,20 +1811,6 @@ async fn needs_move_to_mvbox(
|
||||
context: &Context,
|
||||
headers: &[mailparse::MailHeader<'_>],
|
||||
) -> Result<bool> {
|
||||
let has_chat_version = headers.get_header_value(HeaderDef::ChatVersion).is_some();
|
||||
if !context.get_config_bool(Config::IsChatmail).await?
|
||||
&& has_chat_version
|
||||
&& headers
|
||||
.get_header_value(HeaderDef::AutoSubmitted)
|
||||
.filter(|val| val.to_ascii_lowercase() == "auto-generated")
|
||||
.is_some()
|
||||
{
|
||||
if let Some(from) = mimeparser::get_from(headers) {
|
||||
if context.is_self_addr(&from.addr).await? {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if !context.get_config_bool(Config::MvboxMove).await? {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -1824,7 +1824,7 @@ async fn needs_move_to_mvbox(
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if has_chat_version {
|
||||
if headers.get_header_value(HeaderDef::ChatVersion).is_some() {
|
||||
Ok(true)
|
||||
} else if let Some(parent) = get_prefetch_parent_message(context, headers).await? {
|
||||
match parent.is_dc_message {
|
||||
|
||||
@@ -24,7 +24,6 @@ const PREFETCH_FLAGS: &str = "(UID INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIE
|
||||
FROM \
|
||||
IN-REPLY-TO REFERENCES \
|
||||
CHAT-VERSION \
|
||||
AUTO-SUBMITTED \
|
||||
AUTOCRYPT-SETUP-MESSAGE\
|
||||
)])";
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::provider::Socket;
|
||||
use crate::provider::{get_provider_by_id, Provider};
|
||||
use crate::socks::Socks5Config;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, Display, FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, Display, FromPrimitive, ToPrimitive, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum CertificateChecks {
|
||||
@@ -30,7 +30,6 @@ pub enum CertificateChecks {
|
||||
/// means that provider database setting should be taken.
|
||||
/// If there is no provider database setting for certificate checks,
|
||||
/// `Automatic` is the same as `Strict`.
|
||||
#[default]
|
||||
Automatic = 0,
|
||||
|
||||
Strict = 1,
|
||||
@@ -42,6 +41,12 @@ pub enum CertificateChecks {
|
||||
AcceptInvalidCertificates = 3,
|
||||
}
|
||||
|
||||
impl Default for CertificateChecks {
|
||||
fn default() -> Self {
|
||||
Self::Automatic
|
||||
}
|
||||
}
|
||||
|
||||
/// Login parameters for a single server, either IMAP or SMTP
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ServerLoginParam {
|
||||
@@ -51,6 +56,10 @@ pub struct ServerLoginParam {
|
||||
pub port: u16,
|
||||
pub security: Socket,
|
||||
pub oauth2: bool,
|
||||
|
||||
/// TLS options: whether to allow invalid certificates and/or
|
||||
/// invalid hostnames
|
||||
pub certificate_checks: CertificateChecks,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||
@@ -60,10 +69,6 @@ pub struct LoginParam {
|
||||
pub smtp: ServerLoginParam,
|
||||
pub provider: Option<&'static Provider>,
|
||||
pub socks5_config: Option<Socks5Config>,
|
||||
|
||||
/// TLS options: whether to allow invalid certificates and/or
|
||||
/// invalid hostnames
|
||||
pub certificate_checks: CertificateChecks,
|
||||
}
|
||||
|
||||
impl LoginParam {
|
||||
@@ -125,12 +130,8 @@ impl LoginParam {
|
||||
.and_then(num_traits::FromPrimitive::from_i32)
|
||||
.unwrap_or_default();
|
||||
|
||||
// The setting is named `imap_certificate_checks`
|
||||
// for backwards compatibility,
|
||||
// but now it is a global setting applied to all protocols,
|
||||
// while `smtp_certificate_checks` is ignored.
|
||||
let key = &format!("{prefix}imap_certificate_checks");
|
||||
let certificate_checks =
|
||||
let imap_certificate_checks =
|
||||
if let Some(certificate_checks) = sql.get_raw_config_int(key).await? {
|
||||
num_traits::FromPrimitive::from_i32(certificate_checks).unwrap()
|
||||
} else {
|
||||
@@ -156,6 +157,14 @@ impl LoginParam {
|
||||
.and_then(num_traits::FromPrimitive::from_i32)
|
||||
.unwrap_or_default();
|
||||
|
||||
let key = &format!("{prefix}smtp_certificate_checks");
|
||||
let smtp_certificate_checks =
|
||||
if let Some(certificate_checks) = sql.get_raw_config_int(key).await? {
|
||||
num_traits::FromPrimitive::from_i32(certificate_checks).unwrap_or_default()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
let key = &format!("{prefix}server_flags");
|
||||
let server_flags = sql.get_raw_config_int(key).await?.unwrap_or_default();
|
||||
let oauth2 = matches!(server_flags & DC_LP_AUTH_FLAGS, DC_LP_AUTH_OAUTH2);
|
||||
@@ -177,6 +186,7 @@ impl LoginParam {
|
||||
port: mail_port as u16,
|
||||
security: mail_security,
|
||||
oauth2,
|
||||
certificate_checks: imap_certificate_checks,
|
||||
},
|
||||
smtp: ServerLoginParam {
|
||||
server: send_server,
|
||||
@@ -185,8 +195,8 @@ impl LoginParam {
|
||||
port: send_port as u16,
|
||||
security: send_security,
|
||||
oauth2,
|
||||
certificate_checks: smtp_certificate_checks,
|
||||
},
|
||||
certificate_checks,
|
||||
provider,
|
||||
socks5_config,
|
||||
})
|
||||
@@ -217,7 +227,7 @@ impl LoginParam {
|
||||
.await?;
|
||||
|
||||
let key = &format!("{prefix}imap_certificate_checks");
|
||||
sql.set_raw_config_int(key, self.certificate_checks as i32)
|
||||
sql.set_raw_config_int(key, self.imap.certificate_checks as i32)
|
||||
.await?;
|
||||
|
||||
let key = &format!("{prefix}send_server");
|
||||
@@ -237,9 +247,8 @@ impl LoginParam {
|
||||
sql.set_raw_config_int(key, self.smtp.security as i32)
|
||||
.await?;
|
||||
|
||||
// This is only saved for compatibility reasons, but never loaded.
|
||||
let key = &format!("{prefix}smtp_certificate_checks");
|
||||
sql.set_raw_config_int(key, self.certificate_checks as i32)
|
||||
sql.set_raw_config_int(key, self.smtp.certificate_checks as i32)
|
||||
.await?;
|
||||
|
||||
// The OAuth2 flag is either set for both IMAP and SMTP or not at all.
|
||||
@@ -256,17 +265,6 @@ impl LoginParam {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn strict_tls(&self) -> bool {
|
||||
let user_strict_tls = match self.certificate_checks {
|
||||
CertificateChecks::Automatic => None,
|
||||
CertificateChecks::Strict => Some(true),
|
||||
CertificateChecks::AcceptInvalidCertificates
|
||||
| CertificateChecks::AcceptInvalidCertificates2 => Some(false),
|
||||
};
|
||||
let provider_strict_tls = self.provider.map(|provider| provider.opt.strict_tls);
|
||||
user_strict_tls.or(provider_strict_tls).unwrap_or(true)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LoginParam {
|
||||
@@ -276,7 +274,7 @@ impl fmt::Display for LoginParam {
|
||||
|
||||
write!(
|
||||
f,
|
||||
"{} imap:{}:{}:{}:{}:{}:{} smtp:{}:{}:{}:{}:{}:{} cert_{}",
|
||||
"{} imap:{}:{}:{}:{}:{}:cert_{}:{} smtp:{}:{}:{}:{}:{}:cert_{}:{}",
|
||||
unset_empty(&self.addr),
|
||||
unset_empty(&self.imap.user),
|
||||
if !self.imap.password.is_empty() {
|
||||
@@ -287,6 +285,7 @@ impl fmt::Display for LoginParam {
|
||||
unset_empty(&self.imap.server),
|
||||
self.imap.port,
|
||||
self.imap.security,
|
||||
self.imap.certificate_checks,
|
||||
if self.imap.oauth2 {
|
||||
"OAUTH2"
|
||||
} else {
|
||||
@@ -301,12 +300,12 @@ impl fmt::Display for LoginParam {
|
||||
unset_empty(&self.smtp.server),
|
||||
self.smtp.port,
|
||||
self.smtp.security,
|
||||
self.smtp.certificate_checks,
|
||||
if self.smtp.oauth2 {
|
||||
"OAUTH2"
|
||||
} else {
|
||||
"AUTH_NORMAL"
|
||||
},
|
||||
self.certificate_checks
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -347,6 +346,7 @@ mod tests {
|
||||
port: 123,
|
||||
security: Socket::Starttls,
|
||||
oauth2: false,
|
||||
certificate_checks: CertificateChecks::Strict,
|
||||
},
|
||||
smtp: ServerLoginParam {
|
||||
server: "smtp.example.com".to_string(),
|
||||
@@ -355,11 +355,11 @@ mod tests {
|
||||
port: 456,
|
||||
security: Socket::Ssl,
|
||||
oauth2: false,
|
||||
certificate_checks: CertificateChecks::AcceptInvalidCertificates,
|
||||
},
|
||||
provider: get_provider_by_id("example.com"),
|
||||
// socks5_config is not saved by `save_to_database`, using default value
|
||||
socks5_config: None,
|
||||
certificate_checks: CertificateChecks::Strict,
|
||||
};
|
||||
|
||||
param.save_as_configured_params(&t).await?;
|
||||
|
||||
@@ -1769,17 +1769,19 @@ pub async fn markseen_msgs(context: &Context, msg_ids: Vec<MsgId>) -> Result<()>
|
||||
if curr_blocked == Blocked::Not
|
||||
&& curr_param.get_bool(Param::WantsMdn).unwrap_or_default()
|
||||
&& curr_param.get_cmd() == SystemMessage::Unknown
|
||||
&& context.should_send_mdns().await?
|
||||
{
|
||||
context
|
||||
.sql
|
||||
.execute(
|
||||
"INSERT INTO smtp_mdns (msg_id, from_id, rfc724_mid) VALUES(?, ?, ?)",
|
||||
(id, curr_from_id, curr_rfc724_mid),
|
||||
)
|
||||
.await
|
||||
.context("failed to insert into smtp_mdns")?;
|
||||
context.scheduler.interrupt_smtp().await;
|
||||
let mdns_enabled = context.get_config_bool(Config::MdnsEnabled).await?;
|
||||
if mdns_enabled {
|
||||
context
|
||||
.sql
|
||||
.execute(
|
||||
"INSERT INTO smtp_mdns (msg_id, from_id, rfc724_mid) VALUES(?, ?, ?)",
|
||||
(id, curr_from_id, curr_rfc724_mid),
|
||||
)
|
||||
.await
|
||||
.context("failed to insert into smtp_mdns")?;
|
||||
context.scheduler.interrupt_smtp().await;
|
||||
}
|
||||
}
|
||||
updated_chat_ids.insert(curr_chat_id);
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ impl MimeFactory {
|
||||
|
||||
if !msg.is_system_message()
|
||||
&& msg.param.get_int(Param::Reaction).unwrap_or_default() == 0
|
||||
&& context.should_request_mdns().await?
|
||||
&& context.get_config_bool(Config::MdnsEnabled).await?
|
||||
{
|
||||
req_mdn = true;
|
||||
}
|
||||
|
||||
@@ -26,16 +26,15 @@
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use email::Header;
|
||||
use futures_lite::StreamExt;
|
||||
use iroh_gossip::net::{Event, Gossip, GossipEvent, JoinOptions, GOSSIP_ALPN};
|
||||
use iroh_gossip::proto::TopicId;
|
||||
use iroh_gossip::net::{Gossip, JoinTopicFut, GOSSIP_ALPN};
|
||||
use iroh_gossip::proto::{Event as IrohEvent, TopicId};
|
||||
use iroh_net::key::{PublicKey, SecretKey};
|
||||
use iroh_net::relay::{RelayMap, RelayUrl};
|
||||
use iroh_net::{relay::RelayMode, Endpoint};
|
||||
use iroh_net::{NodeAddr, NodeId};
|
||||
use parking_lot::Mutex;
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::env;
|
||||
use tokio::sync::{oneshot, RwLock};
|
||||
use tokio::sync::RwLock;
|
||||
use tokio::task::JoinHandle;
|
||||
use url::Url;
|
||||
|
||||
@@ -60,9 +59,6 @@ pub struct Iroh {
|
||||
/// [Gossip] needed for iroh peer channels.
|
||||
pub(crate) gossip: Gossip,
|
||||
|
||||
/// Sequence numbers for gossip channels.
|
||||
pub(crate) sequence_numbers: Mutex<HashMap<TopicId, i32>>,
|
||||
|
||||
/// Topics for which an advertisement has already been sent.
|
||||
pub(crate) iroh_channels: RwLock<HashMap<TopicId, ChannelState>>,
|
||||
|
||||
@@ -87,7 +83,7 @@ impl Iroh {
|
||||
&self,
|
||||
ctx: &Context,
|
||||
msg_id: MsgId,
|
||||
) -> Result<Option<oneshot::Receiver<()>>> {
|
||||
) -> Result<Option<JoinTopicFut>> {
|
||||
let topic = get_iroh_topic_for_msg(ctx, msg_id)
|
||||
.await?
|
||||
.with_context(|| format!("Message {msg_id} has no gossip topic"))?;
|
||||
@@ -98,9 +94,14 @@ impl Iroh {
|
||||
// Otherwise we would receive every message twice or more times.
|
||||
let mut iroh_channels = self.iroh_channels.write().await;
|
||||
|
||||
if iroh_channels.contains_key(&topic) {
|
||||
return Ok(None);
|
||||
}
|
||||
let seq = if let Some(channel_state) = iroh_channels.get(&topic) {
|
||||
if channel_state.subscribe_loop.is_some() {
|
||||
return Ok(None);
|
||||
}
|
||||
channel_state.seq_number
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let peers = get_iroh_gossip_peers(ctx, msg_id).await?;
|
||||
let node_ids = peers.iter().map(|p| p.node_id).collect::<Vec<_>>();
|
||||
@@ -117,35 +118,33 @@ impl Iroh {
|
||||
}
|
||||
}
|
||||
|
||||
let (join_tx, join_rx) = oneshot::channel();
|
||||
|
||||
let (gossip_sender, gossip_receiver) = self
|
||||
.gossip
|
||||
.join_with_opts(topic, JoinOptions::with_bootstrap(node_ids))
|
||||
.split();
|
||||
// Connect to all peers
|
||||
let connect_future = self.gossip.join(topic, node_ids).await?;
|
||||
|
||||
let ctx = ctx.clone();
|
||||
let gossip = self.gossip.clone();
|
||||
let subscribe_loop = tokio::spawn(async move {
|
||||
if let Err(e) = subscribe_loop(&ctx, gossip_receiver, topic, msg_id, join_tx).await {
|
||||
if let Err(e) = subscribe_loop(&ctx, gossip, topic, msg_id).await {
|
||||
warn!(ctx, "subscribe_loop failed: {e}")
|
||||
}
|
||||
});
|
||||
|
||||
iroh_channels.insert(topic, ChannelState::new(subscribe_loop, gossip_sender));
|
||||
iroh_channels.insert(topic, ChannelState::new(seq, subscribe_loop));
|
||||
|
||||
Ok(Some(join_rx))
|
||||
Ok(Some(connect_future))
|
||||
}
|
||||
|
||||
/// Add gossip peers to realtime channel if it is already active.
|
||||
pub async fn maybe_add_gossip_peers(&self, topic: TopicId, peers: Vec<NodeAddr>) -> Result<()> {
|
||||
if self.iroh_channels.read().await.get(&topic).is_some() {
|
||||
for peer in &peers {
|
||||
self.endpoint.add_node_addr(peer.clone())?;
|
||||
if let Some(state) = self.iroh_channels.read().await.get(&topic) {
|
||||
if state.subscribe_loop.is_some() {
|
||||
for peer in &peers {
|
||||
self.endpoint.add_node_addr(peer.clone())?;
|
||||
}
|
||||
self.gossip
|
||||
.join(topic, peers.into_iter().map(|peer| peer.node_id).collect())
|
||||
.await?;
|
||||
}
|
||||
|
||||
self.gossip
|
||||
.join(topic, peers.into_iter().map(|peer| peer.node_id).collect())
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -162,16 +161,11 @@ impl Iroh {
|
||||
.with_context(|| format!("Message {msg_id} has no gossip topic"))?;
|
||||
self.join_and_subscribe_gossip(ctx, msg_id).await?;
|
||||
|
||||
let seq_num = self.get_and_incr(&topic);
|
||||
|
||||
let mut iroh_channels = self.iroh_channels.write().await;
|
||||
let state = iroh_channels
|
||||
.get_mut(&topic)
|
||||
.context("Just created state does not exist")?;
|
||||
let seq_num = self.get_and_incr(&topic).await;
|
||||
data.extend(seq_num.to_le_bytes());
|
||||
data.extend(self.public_key.as_bytes());
|
||||
|
||||
state.sender.broadcast(data.into()).await?;
|
||||
self.gossip.broadcast(topic, data.into()).await?;
|
||||
|
||||
if env::var("REALTIME_DEBUG").is_ok() {
|
||||
info!(ctx, "Sent realtime data");
|
||||
@@ -180,11 +174,13 @@ impl Iroh {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_and_incr(&self, topic: &TopicId) -> i32 {
|
||||
let mut sequence_numbers = self.sequence_numbers.lock();
|
||||
let entry = sequence_numbers.entry(*topic).or_default();
|
||||
*entry = entry.wrapping_add(1);
|
||||
*entry
|
||||
async fn get_and_incr(&self, topic: &TopicId) -> i32 {
|
||||
let mut seq = 0;
|
||||
if let Some(state) = self.iroh_channels.write().await.get_mut(topic) {
|
||||
seq = state.seq_number;
|
||||
state.seq_number = state.seq_number.wrapping_add(1)
|
||||
}
|
||||
seq
|
||||
}
|
||||
|
||||
/// Get the iroh [NodeAddr] without direct IP addresses.
|
||||
@@ -196,17 +192,12 @@ impl Iroh {
|
||||
|
||||
/// Leave the realtime channel for a given topic.
|
||||
pub(crate) async fn leave_realtime(&self, topic: TopicId) -> Result<()> {
|
||||
if let Some(channel) = self.iroh_channels.write().await.remove(&topic) {
|
||||
// Dropping the last GossipTopic results in quitting the topic.
|
||||
// It is split into GossipReceiver and GossipSender.
|
||||
// GossipSender (`channel.sender`) is dropped automatically.
|
||||
|
||||
// Subscribe loop owns GossipReceiver.
|
||||
// Aborting it and waiting for it to be dropped
|
||||
// drops the receiver.
|
||||
channel.subscribe_loop.abort();
|
||||
let _ = channel.subscribe_loop.await;
|
||||
if let Some(channel) = &mut self.iroh_channels.write().await.get_mut(&topic) {
|
||||
if let Some(subscribe_loop) = channel.subscribe_loop.take() {
|
||||
subscribe_loop.abort();
|
||||
}
|
||||
}
|
||||
self.gossip.quit(topic).await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -214,17 +205,17 @@ impl Iroh {
|
||||
/// Single gossip channel state.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ChannelState {
|
||||
/// Sequence number for the gossip channel.
|
||||
seq_number: i32,
|
||||
/// The subscribe loop handle.
|
||||
subscribe_loop: JoinHandle<()>,
|
||||
|
||||
sender: iroh_gossip::net::GossipSender,
|
||||
subscribe_loop: Option<JoinHandle<()>>,
|
||||
}
|
||||
|
||||
impl ChannelState {
|
||||
fn new(subscribe_loop: JoinHandle<()>, sender: iroh_gossip::net::GossipSender) -> Self {
|
||||
fn new(seq_number: i32, subscribe_loop: JoinHandle<()>) -> Self {
|
||||
Self {
|
||||
subscribe_loop,
|
||||
sender,
|
||||
seq_number,
|
||||
subscribe_loop: Some(subscribe_loop),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,7 +261,6 @@ impl Context {
|
||||
Ok(Iroh {
|
||||
endpoint,
|
||||
gossip,
|
||||
sequence_numbers: Mutex::new(HashMap::new()),
|
||||
iroh_channels: RwLock::new(HashMap::new()),
|
||||
public_key,
|
||||
})
|
||||
@@ -380,7 +370,7 @@ pub(crate) async fn get_iroh_topic_for_msg(
|
||||
pub async fn send_webxdc_realtime_advertisement(
|
||||
ctx: &Context,
|
||||
msg_id: MsgId,
|
||||
) -> Result<Option<oneshot::Receiver<()>>> {
|
||||
) -> Result<Option<JoinTopicFut>> {
|
||||
if !ctx.get_config_bool(Config::WebxdcRealtimeEnabled).await? {
|
||||
return Ok(None);
|
||||
}
|
||||
@@ -477,50 +467,32 @@ async fn handle_connection(
|
||||
|
||||
async fn subscribe_loop(
|
||||
context: &Context,
|
||||
mut stream: iroh_gossip::net::GossipReceiver,
|
||||
gossip: Gossip,
|
||||
topic: TopicId,
|
||||
msg_id: MsgId,
|
||||
join_tx: oneshot::Sender<()>,
|
||||
) -> Result<()> {
|
||||
let mut join_tx = Some(join_tx);
|
||||
|
||||
while let Some(event) = stream.try_next().await? {
|
||||
let mut stream = gossip.subscribe(topic).await?;
|
||||
loop {
|
||||
let event = stream.recv().await?;
|
||||
match event {
|
||||
Event::Gossip(event) => match event {
|
||||
GossipEvent::Joined(nodes) => {
|
||||
if let Some(join_tx) = join_tx.take() {
|
||||
// Try to notify that at least one peer joined,
|
||||
// but ignore the error if receiver is dropped and nobody listens.
|
||||
join_tx.send(()).ok();
|
||||
}
|
||||
|
||||
for node in nodes {
|
||||
iroh_add_peer_for_topic(context, msg_id, topic, node, None).await?;
|
||||
}
|
||||
}
|
||||
GossipEvent::NeighborUp(node) => {
|
||||
info!(context, "IROH_REALTIME: NeighborUp: {}", node.to_string());
|
||||
iroh_add_peer_for_topic(context, msg_id, topic, node, None).await?;
|
||||
}
|
||||
GossipEvent::NeighborDown(_node) => {}
|
||||
GossipEvent::Received(message) => {
|
||||
info!(context, "IROH_REALTIME: Received realtime data");
|
||||
context.emit_event(EventType::WebxdcRealtimeData {
|
||||
msg_id,
|
||||
data: message
|
||||
.content
|
||||
.get(0..message.content.len() - 4 - PUBLIC_KEY_LENGTH)
|
||||
.context("too few bytes in iroh message")?
|
||||
.into(),
|
||||
});
|
||||
}
|
||||
},
|
||||
Event::Lagged => {
|
||||
warn!(context, "Gossip lost some messages");
|
||||
IrohEvent::NeighborUp(node) => {
|
||||
info!(context, "IROH_REALTIME: NeighborUp: {}", node.to_string());
|
||||
iroh_add_peer_for_topic(context, msg_id, topic, node, None).await?;
|
||||
}
|
||||
IrohEvent::Received(event) => {
|
||||
info!(context, "IROH_REALTIME: Received realtime data");
|
||||
context.emit_event(EventType::WebxdcRealtimeData {
|
||||
msg_id,
|
||||
data: event
|
||||
.content
|
||||
.get(0..event.content.len() - 4 - PUBLIC_KEY_LENGTH)
|
||||
.context("too few bytes in iroh message")?
|
||||
.into(),
|
||||
});
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -568,10 +540,10 @@ mod tests {
|
||||
assert_eq!(alice_webxdc.get_viewtype(), Viewtype::Webxdc);
|
||||
|
||||
let webxdc = alice.pop_sent_msg().await;
|
||||
let bob_webxdc = bob.recv_msg(&webxdc).await;
|
||||
assert_eq!(bob_webxdc.get_viewtype(), Viewtype::Webxdc);
|
||||
let bob_webdxc = bob.recv_msg(&webxdc).await;
|
||||
assert_eq!(bob_webdxc.get_viewtype(), Viewtype::Webxdc);
|
||||
|
||||
bob_webxdc.chat_id.accept(bob).await.unwrap();
|
||||
bob_webdxc.chat_id.accept(bob).await.unwrap();
|
||||
|
||||
// Alice advertises herself.
|
||||
send_webxdc_realtime_advertisement(alice, alice_webxdc.id)
|
||||
@@ -582,7 +554,7 @@ mod tests {
|
||||
let bob_iroh = bob.get_or_try_init_peer_channel().await.unwrap();
|
||||
|
||||
// Bob adds alice to gossip peers.
|
||||
let members = get_iroh_gossip_peers(bob, bob_webxdc.id)
|
||||
let members = get_iroh_gossip_peers(bob, bob_webdxc.id)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
@@ -596,7 +568,7 @@ mod tests {
|
||||
);
|
||||
|
||||
bob_iroh
|
||||
.join_and_subscribe_gossip(bob, bob_webxdc.id)
|
||||
.join_and_subscribe_gossip(bob, bob_webdxc.id)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -624,7 +596,7 @@ mod tests {
|
||||
}
|
||||
// Bob sends ephemeral message
|
||||
bob_iroh
|
||||
.send_webxdc_realtime_data(bob, bob_webxdc.id, "bob -> alice".as_bytes().to_vec())
|
||||
.send_webxdc_realtime_data(bob, bob_webdxc.id, "bob -> alice".as_bytes().to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -656,7 +628,7 @@ mod tests {
|
||||
);
|
||||
|
||||
bob_iroh
|
||||
.send_webxdc_realtime_data(bob, bob_webxdc.id, "bob -> alice 2".as_bytes().to_vec())
|
||||
.send_webxdc_realtime_data(bob, bob_webdxc.id, "bob -> alice 2".as_bytes().to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -714,10 +686,10 @@ mod tests {
|
||||
assert_eq!(alice_webxdc.get_viewtype(), Viewtype::Webxdc);
|
||||
|
||||
let webxdc = alice.pop_sent_msg().await;
|
||||
let bob_webxdc = bob.recv_msg(&webxdc).await;
|
||||
assert_eq!(bob_webxdc.get_viewtype(), Viewtype::Webxdc);
|
||||
let bob_webdxc = bob.recv_msg(&webxdc).await;
|
||||
assert_eq!(bob_webdxc.get_viewtype(), Viewtype::Webxdc);
|
||||
|
||||
bob_webxdc.chat_id.accept(bob).await.unwrap();
|
||||
bob_webdxc.chat_id.accept(bob).await.unwrap();
|
||||
|
||||
// Alice advertises herself.
|
||||
send_webxdc_realtime_advertisement(alice, alice_webxdc.id)
|
||||
@@ -728,7 +700,7 @@ mod tests {
|
||||
let bob_iroh = bob.get_or_try_init_peer_channel().await.unwrap();
|
||||
|
||||
// Bob adds alice to gossip peers.
|
||||
let members = get_iroh_gossip_peers(bob, bob_webxdc.id)
|
||||
let members = get_iroh_gossip_peers(bob, bob_webdxc.id)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
@@ -742,7 +714,7 @@ mod tests {
|
||||
);
|
||||
|
||||
bob_iroh
|
||||
.join_and_subscribe_gossip(bob, bob_webxdc.id)
|
||||
.join_and_subscribe_gossip(bob, bob_webdxc.id)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -769,32 +741,11 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
let bob_topic = get_iroh_topic_for_msg(bob, bob_webxdc.id)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let bob_sequence_number = bob
|
||||
.iroh
|
||||
.get()
|
||||
.unwrap()
|
||||
.sequence_numbers
|
||||
.lock()
|
||||
.get(&bob_topic)
|
||||
.copied();
|
||||
leave_webxdc_realtime(bob, bob_webxdc.id).await.unwrap();
|
||||
let bob_sequence_number_after = bob
|
||||
.iroh
|
||||
.get()
|
||||
.unwrap()
|
||||
.sequence_numbers
|
||||
.lock()
|
||||
.get(&bob_topic)
|
||||
.copied();
|
||||
// Check that sequence number is persisted when leaving the channel.
|
||||
assert_eq!(bob_sequence_number, bob_sequence_number_after);
|
||||
// TODO: check that seq number is persisted
|
||||
leave_webxdc_realtime(bob, bob_webdxc.id).await.unwrap();
|
||||
|
||||
bob_iroh
|
||||
.join_and_subscribe_gossip(bob, bob_webxdc.id)
|
||||
.join_and_subscribe_gossip(bob, bob_webdxc.id)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
@@ -802,7 +753,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
bob_iroh
|
||||
.send_webxdc_realtime_data(bob, bob_webxdc.id, "bob -> alice".as_bytes().to_vec())
|
||||
.send_webxdc_realtime_data(bob, bob_webdxc.id, "bob -> alice".as_bytes().to_vec())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -832,7 +783,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert!(alice
|
||||
assert!(if let Some(state) = alice
|
||||
.iroh
|
||||
.get()
|
||||
.unwrap()
|
||||
@@ -840,7 +791,11 @@ mod tests {
|
||||
.read()
|
||||
.await
|
||||
.get(&topic)
|
||||
.is_none());
|
||||
{
|
||||
state.subscribe_loop.is_none()
|
||||
} else {
|
||||
false
|
||||
});
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
|
||||
@@ -520,7 +520,7 @@ static P_FREENET_DE: Provider = Provider {
|
||||
static P_GMAIL: Provider = Provider {
|
||||
id: "gmail",
|
||||
status: Status::Preparation,
|
||||
before_login_hint: "For Gmail accounts, you need to have \"2-Step Verification\" enabled and create an app-password.",
|
||||
before_login_hint: "For Gmail accounts, you need to create an app-password if you have \"2-Step Verification\" enabled. If this setting is not available, you need to enable \"less secure apps\".",
|
||||
after_login_hint: "",
|
||||
overview_page: "https://providers.delta.chat/gmail",
|
||||
server: &[
|
||||
@@ -1037,20 +1037,6 @@ static P_NINE_TESTRUN_ORG: Provider = Provider {
|
||||
port: 587,
|
||||
username_pattern: Email,
|
||||
},
|
||||
Server {
|
||||
protocol: Imap,
|
||||
socket: Ssl,
|
||||
hostname: "nine.testrun.org",
|
||||
port: 443,
|
||||
username_pattern: Email,
|
||||
},
|
||||
Server {
|
||||
protocol: Smtp,
|
||||
socket: Ssl,
|
||||
hostname: "nine.testrun.org",
|
||||
port: 443,
|
||||
username_pattern: Email,
|
||||
},
|
||||
],
|
||||
opt: ProviderOptions::new(),
|
||||
config_defaults: Some(&[ConfigDefault {
|
||||
@@ -1274,14 +1260,14 @@ static P_RISEUP_NET: Provider = Provider {
|
||||
socket: Ssl,
|
||||
hostname: "mail.riseup.net",
|
||||
port: 993,
|
||||
username_pattern: Email,
|
||||
username_pattern: Emaillocalpart,
|
||||
},
|
||||
Server {
|
||||
protocol: Smtp,
|
||||
socket: Ssl,
|
||||
hostname: "mail.riseup.net",
|
||||
port: 465,
|
||||
username_pattern: Email,
|
||||
username_pattern: Emaillocalpart,
|
||||
},
|
||||
],
|
||||
opt: ProviderOptions::new(),
|
||||
@@ -1315,37 +1301,6 @@ static P_SONIC: Provider = Provider {
|
||||
oauth2_authorizer: None,
|
||||
};
|
||||
|
||||
// stinpriza.net.md: stinpriza.net, stinpriza.eu, el-hoyo.net
|
||||
static P_STINPRIZA_NET: Provider = Provider {
|
||||
id: "stinpriza.net",
|
||||
status: Status::Ok,
|
||||
before_login_hint: "",
|
||||
after_login_hint: "",
|
||||
overview_page: "https://providers.delta.chat/stinpriza-net",
|
||||
server: &[
|
||||
Server {
|
||||
protocol: Imap,
|
||||
socket: Starttls,
|
||||
hostname: "stinpriza.net",
|
||||
port: 143,
|
||||
username_pattern: Email,
|
||||
},
|
||||
Server {
|
||||
protocol: Smtp,
|
||||
socket: Starttls,
|
||||
hostname: "stinpriza.net",
|
||||
port: 587,
|
||||
username_pattern: Email,
|
||||
},
|
||||
],
|
||||
opt: ProviderOptions {
|
||||
strict_tls: true,
|
||||
..ProviderOptions::new()
|
||||
},
|
||||
config_defaults: None,
|
||||
oauth2_authorizer: None,
|
||||
};
|
||||
|
||||
// systemausfall.org.md: systemausfall.org, solidaris.me
|
||||
static P_SYSTEMAUSFALL_ORG: Provider = Provider {
|
||||
id: "systemausfall.org",
|
||||
@@ -1600,13 +1555,11 @@ static P_VIVALDI: Provider = Provider {
|
||||
// vk.com.md: vk.com
|
||||
static P_VK_COM: Provider = Provider {
|
||||
id: "vk.com",
|
||||
status: Status::Preparation,
|
||||
before_login_hint: "Вам необходимо сгенерировать \"пароль для внешнего приложения\" в веб-интерфейсе mail.ru https://account.mail.ru/user/2-step-auth/passwords/ чтобы vk.com работал с Delta Chat.",
|
||||
status: Status::Broken,
|
||||
before_login_hint: "К сожалению, VK Почта не поддерживает работу с Delta Chat. См. https://help.vk.mail.ru/vkmail/questions/client",
|
||||
after_login_hint: "",
|
||||
overview_page: "https://providers.delta.chat/vk-com",
|
||||
server: &[
|
||||
Server { protocol: Imap, socket: Ssl, hostname: "imap.mail.ru", port: 993, username_pattern: Email },
|
||||
Server { protocol: Smtp, socket: Ssl, hostname: "smtp.mail.ru", port: 465, username_pattern: Email },
|
||||
],
|
||||
opt: ProviderOptions::new(),
|
||||
config_defaults: None,
|
||||
@@ -1804,7 +1757,7 @@ static P_ZOHO: Provider = Provider {
|
||||
oauth2_authorizer: None,
|
||||
};
|
||||
|
||||
pub(crate) static PROVIDER_DATA: [(&str, &Provider); 531] = [
|
||||
pub(crate) static PROVIDER_DATA: [(&str, &Provider); 528] = [
|
||||
("163.com", &P_163),
|
||||
("aktivix.org", &P_AKTIVIX_ORG),
|
||||
("aliyun.com", &P_ALIYUN),
|
||||
@@ -2259,9 +2212,6 @@ pub(crate) static PROVIDER_DATA: [(&str, &Provider); 531] = [
|
||||
("riseup.net", &P_RISEUP_NET),
|
||||
("rogers.com", &P_ROGERS_COM),
|
||||
("sonic.net", &P_SONIC),
|
||||
("stinpriza.net", &P_STINPRIZA_NET),
|
||||
("stinpriza.eu", &P_STINPRIZA_NET),
|
||||
("el-hoyo.net", &P_STINPRIZA_NET),
|
||||
("systemausfall.org", &P_SYSTEMAUSFALL_ORG),
|
||||
("solidaris.me", &P_SYSTEMAUSFALL_ORG),
|
||||
("systemli.org", &P_SYSTEMLI_ORG),
|
||||
@@ -2393,7 +2343,6 @@ pub(crate) static PROVIDER_IDS: Lazy<HashMap<&'static str, &'static Provider>> =
|
||||
("riseup.net", &P_RISEUP_NET),
|
||||
("rogers.com", &P_ROGERS_COM),
|
||||
("sonic", &P_SONIC),
|
||||
("stinpriza.net", &P_STINPRIZA_NET),
|
||||
("systemausfall.org", &P_SYSTEMAUSFALL_ORG),
|
||||
("systemli.org", &P_SYSTEMLI_ORG),
|
||||
("t-online", &P_T_ONLINE),
|
||||
@@ -2417,4 +2366,4 @@ pub(crate) static PROVIDER_IDS: Lazy<HashMap<&'static str, &'static Provider>> =
|
||||
});
|
||||
|
||||
pub static _PROVIDER_UPDATED: Lazy<chrono::NaiveDate> =
|
||||
Lazy::new(|| chrono::NaiveDate::from_ymd_opt(2024, 8, 14).unwrap());
|
||||
Lazy::new(|| chrono::NaiveDate::from_ymd_opt(2024, 6, 24).unwrap());
|
||||
|
||||
@@ -1405,12 +1405,9 @@ mod tests {
|
||||
ctx.ctx.get_config(Config::SendUser).await?,
|
||||
Some("SendUser".to_owned())
|
||||
);
|
||||
|
||||
// `sc` option is actually ignored and `ic` is used instead
|
||||
// because `smtp_certificate_checks` is deprecated.
|
||||
assert_eq!(
|
||||
ctx.ctx.get_config(Config::SmtpCertificateChecks).await?,
|
||||
Some("1".to_owned())
|
||||
Some("3".to_owned())
|
||||
);
|
||||
assert_eq!(
|
||||
ctx.ctx.get_config(Config::SendSecurity).await?,
|
||||
|
||||
@@ -39,6 +39,9 @@ pub enum LoginOptions {
|
||||
/// IMAP socket security.
|
||||
imap_security: Option<Socket>,
|
||||
|
||||
/// IMAP certificate checks.
|
||||
imap_certificate_checks: Option<CertificateChecks>,
|
||||
|
||||
/// SMTP host.
|
||||
smtp_host: Option<String>,
|
||||
|
||||
@@ -54,8 +57,8 @@ pub enum LoginOptions {
|
||||
/// SMTP socket security.
|
||||
smtp_security: Option<Socket>,
|
||||
|
||||
/// Certificate checks.
|
||||
certificate_checks: Option<CertificateChecks>,
|
||||
/// SMTP certificate checks.
|
||||
smtp_certificate_checks: Option<CertificateChecks>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -104,13 +107,14 @@ pub(super) fn decode_login(qr: &str) -> Result<Qr> {
|
||||
imap_username: parameter_map.get("iu").map(|s| s.to_owned()),
|
||||
imap_password: parameter_map.get("ipw").map(|s| s.to_owned()),
|
||||
imap_security: parse_socket_security(parameter_map.get("is"))?,
|
||||
imap_certificate_checks: parse_certificate_checks(parameter_map.get("ic"))?,
|
||||
smtp_host: parameter_map.get("sh").map(|s| s.to_owned()),
|
||||
smtp_port: parse_port(parameter_map.get("sp"))
|
||||
.context("could not parse smtp port")?,
|
||||
smtp_username: parameter_map.get("su").map(|s| s.to_owned()),
|
||||
smtp_password: parameter_map.get("spw").map(|s| s.to_owned()),
|
||||
smtp_security: parse_socket_security(parameter_map.get("ss"))?,
|
||||
certificate_checks: parse_certificate_checks(parameter_map.get("ic"))?,
|
||||
smtp_certificate_checks: parse_certificate_checks(parameter_map.get("sc"))?,
|
||||
},
|
||||
Some(Ok(v)) => LoginOptions::UnsuportedVersion(v),
|
||||
Some(Err(_)) => bail!("version could not be parsed as number E6"),
|
||||
@@ -173,12 +177,13 @@ pub(crate) async fn configure_from_login_qr(
|
||||
imap_username,
|
||||
imap_password,
|
||||
imap_security,
|
||||
imap_certificate_checks,
|
||||
smtp_host,
|
||||
smtp_port,
|
||||
smtp_username,
|
||||
smtp_password,
|
||||
smtp_security,
|
||||
certificate_checks,
|
||||
smtp_certificate_checks,
|
||||
} => {
|
||||
context
|
||||
.set_config_internal(Config::MailPw, Some(&mail_pw))
|
||||
@@ -211,6 +216,14 @@ pub(crate) async fn configure_from_login_qr(
|
||||
.set_config_internal(Config::MailSecurity, Some(&code.to_string()))
|
||||
.await?;
|
||||
}
|
||||
if let Some(value) = imap_certificate_checks {
|
||||
let code = value
|
||||
.to_u32()
|
||||
.context("could not convert imap certificate checks value to number")?;
|
||||
context
|
||||
.set_config_internal(Config::ImapCertificateChecks, Some(&code.to_string()))
|
||||
.await?;
|
||||
}
|
||||
if let Some(value) = smtp_host {
|
||||
context
|
||||
.set_config_internal(Config::SendServer, Some(&value))
|
||||
@@ -239,13 +252,10 @@ pub(crate) async fn configure_from_login_qr(
|
||||
.set_config_internal(Config::SendSecurity, Some(&code.to_string()))
|
||||
.await?;
|
||||
}
|
||||
if let Some(value) = certificate_checks {
|
||||
if let Some(value) = smtp_certificate_checks {
|
||||
let code = value
|
||||
.to_u32()
|
||||
.context("could not convert certificate checks value to number")?;
|
||||
context
|
||||
.set_config_internal(Config::ImapCertificateChecks, Some(&code.to_string()))
|
||||
.await?;
|
||||
.context("could not convert smtp certificate checks value to number")?;
|
||||
context
|
||||
.set_config_internal(Config::SmtpCertificateChecks, Some(&code.to_string()))
|
||||
.await?;
|
||||
@@ -274,12 +284,13 @@ mod test {
|
||||
imap_username: None,
|
||||
imap_password: None,
|
||||
imap_security: None,
|
||||
imap_certificate_checks: None,
|
||||
smtp_host: None,
|
||||
smtp_port: None,
|
||||
smtp_username: None,
|
||||
smtp_password: None,
|
||||
smtp_security: None,
|
||||
certificate_checks: None,
|
||||
smtp_certificate_checks: None,
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -381,12 +392,13 @@ mod test {
|
||||
imap_username: Some("max".to_owned()),
|
||||
imap_password: Some("87654".to_owned()),
|
||||
imap_security: Some(Socket::Ssl),
|
||||
imap_certificate_checks: Some(CertificateChecks::Strict),
|
||||
smtp_host: Some("mail.host.tld".to_owned()),
|
||||
smtp_port: Some(3000),
|
||||
smtp_username: Some("max@host.tld".to_owned()),
|
||||
smtp_password: Some("3242HS".to_owned()),
|
||||
smtp_security: Some(Socket::Plain),
|
||||
certificate_checks: Some(CertificateChecks::Strict),
|
||||
smtp_certificate_checks: Some(CertificateChecks::AcceptInvalidCertificates),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -466,13 +466,11 @@ pub async fn convert_folder_meaning(
|
||||
}
|
||||
|
||||
async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session) -> Result<Session> {
|
||||
if !ctx.get_config_bool(Config::FixIsChatmail).await? {
|
||||
ctx.set_config_internal(
|
||||
Config::IsChatmail,
|
||||
crate::config::from_bool(session.is_chatmail()),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
ctx.set_config_internal(
|
||||
Config::IsChatmail,
|
||||
crate::config::from_bool(session.is_chatmail()),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Update quota no more than once a minute.
|
||||
if ctx.quota_needs_update(60).await {
|
||||
|
||||
19
src/smtp.rs
19
src/smtp.rs
@@ -13,7 +13,7 @@ use crate::config::Config;
|
||||
use crate::contact::{Contact, ContactId};
|
||||
use crate::context::Context;
|
||||
use crate::events::EventType;
|
||||
use crate::login_param::{LoginParam, ServerLoginParam};
|
||||
use crate::login_param::{CertificateChecks, LoginParam, ServerLoginParam};
|
||||
use crate::message::Message;
|
||||
use crate::message::{self, MsgId};
|
||||
use crate::mimefactory::MimeFactory;
|
||||
@@ -94,7 +94,9 @@ impl Smtp {
|
||||
&lp.smtp,
|
||||
&lp.socks5_config,
|
||||
&lp.addr,
|
||||
lp.strict_tls(),
|
||||
lp.provider.map_or(lp.socks5_config.is_some(), |provider| {
|
||||
provider.opt.strict_tls
|
||||
}),
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -106,7 +108,7 @@ impl Smtp {
|
||||
lp: &ServerLoginParam,
|
||||
socks5_config: &Option<Socks5Config>,
|
||||
addr: &str,
|
||||
strict_tls: bool,
|
||||
provider_strict_tls: bool,
|
||||
) -> Result<()> {
|
||||
if self.is_connected() {
|
||||
warn!(context, "SMTP already connected.");
|
||||
@@ -125,6 +127,13 @@ impl Smtp {
|
||||
let domain = &lp.server;
|
||||
let port = lp.port;
|
||||
|
||||
let strict_tls = match lp.certificate_checks {
|
||||
CertificateChecks::Automatic => provider_strict_tls,
|
||||
CertificateChecks::Strict => true,
|
||||
CertificateChecks::AcceptInvalidCertificates
|
||||
| CertificateChecks::AcceptInvalidCertificates2 => false,
|
||||
};
|
||||
|
||||
let session_stream = connect::connect_stream(
|
||||
context,
|
||||
domain,
|
||||
@@ -631,7 +640,9 @@ async fn send_mdn_rfc724_mid(
|
||||
|
||||
/// Tries to send a single MDN. Returns true if more MDNs should be sent.
|
||||
async fn send_mdn(context: &Context, smtp: &mut Smtp) -> Result<bool> {
|
||||
if !context.should_send_mdns().await? {
|
||||
let mdns_enabled = context.get_config_bool(Config::MdnsEnabled).await?;
|
||||
if !mdns_enabled {
|
||||
// User has disabled MDNs.
|
||||
context.sql.execute("DELETE FROM smtp_mdns", []).await?;
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
18
src/sql.rs
18
src/sql.rs
@@ -105,11 +105,9 @@ impl Sql {
|
||||
|
||||
// Test that the key is correct using a single connection.
|
||||
let connection = Connection::open(&self.dbfile)?;
|
||||
if !passphrase.is_empty() {
|
||||
connection
|
||||
.pragma_update(None, "key", &passphrase)
|
||||
.context("Failed to set PRAGMA key")?;
|
||||
}
|
||||
connection
|
||||
.pragma_update(None, "key", &passphrase)
|
||||
.context("failed to set PRAGMA key")?;
|
||||
let key_is_correct = connection
|
||||
.query_row("SELECT count(*) FROM sqlite_master", [], |_row| Ok(()))
|
||||
.is_ok();
|
||||
@@ -326,10 +324,8 @@ impl Sql {
|
||||
|
||||
let pool = lock.take().context("SQL connection pool is not open")?;
|
||||
let conn = pool.get().await?;
|
||||
if !passphrase.is_empty() {
|
||||
conn.pragma_update(None, "rekey", passphrase.clone())
|
||||
.context("Failed to set PRAGMA rekey")?;
|
||||
}
|
||||
conn.pragma_update(None, "rekey", passphrase.clone())
|
||||
.context("failed to set PRAGMA rekey")?;
|
||||
drop(pool);
|
||||
|
||||
*lock = Some(Self::new_pool(&self.dbfile, passphrase.to_string())?);
|
||||
@@ -701,9 +697,7 @@ fn new_connection(path: &Path, passphrase: &str) -> Result<Connection> {
|
||||
conn.pragma_update(None, "temp_store", "memory")?;
|
||||
}
|
||||
|
||||
if !passphrase.is_empty() {
|
||||
conn.pragma_update(None, "key", passphrase)?;
|
||||
}
|
||||
conn.pragma_update(None, "key", passphrase)?;
|
||||
// Try to enable auto_vacuum. This will only be
|
||||
// applied if the database is new or after successful
|
||||
// VACUUM, which usually happens before backup export.
|
||||
|
||||
@@ -19,7 +19,7 @@ Authorization | OAuth2 ([RFC 6749][])
|
||||
End-to-end encryption | [Autocrypt Level 1][], OpenPGP ([RFC 4880][]), Security Multiparts for MIME ([RFC 1847][]) and [“Mixed Up” Encryption repairing](https://tools.ietf.org/id/draft-dkg-openpgp-pgpmime-message-mangling-00.html)
|
||||
Detect/prevent active attacks | [securejoin][] protocols
|
||||
Compare public keys | [openpgp4fpr][] URI Scheme
|
||||
Header encryption | [Header Protection for Cryptographically Protected E-mail](https://datatracker.ietf.org/doc/draft-ietf-lamps-header-protection/)
|
||||
Header encryption | [Protected Headers for Cryptographic E-mail](https://datatracker.ietf.org/doc/draft-autocrypt-lamps-protected-headers/)
|
||||
Configuration assistance | [Autoconfigure](https://web.archive.org/web/20210402044801/https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Autoconfiguration) and [Autodiscover][]
|
||||
Messenger functions | [Chat-over-Email](https://github.com/deltachat/deltachat-core-rust/blob/master/spec.md#chat-mail-specification)
|
||||
Detect mailing list | List-Id ([RFC 2919][]) and Precedence ([RFC 3834][])
|
||||
|
||||
Reference in New Issue
Block a user