mirror of
https://github.com/chatmail/core.git
synced 2026-04-07 08:02:11 +03:00
Compare commits
21 Commits
link2xt/op
...
v1.138.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a738ebd19 | ||
|
|
d02eccd303 | ||
|
|
f1fa053f9f | ||
|
|
38c1caf180 | ||
|
|
97d2812644 | ||
|
|
2ab713d968 | ||
|
|
b7a25d5092 | ||
|
|
8cd85fa7a4 | ||
|
|
7cfab9a931 | ||
|
|
30086038e6 | ||
|
|
eec1062619 | ||
|
|
07ceabdf85 | ||
|
|
c349bf8e0c | ||
|
|
21eb4f6648 | ||
|
|
10fed7d7de | ||
|
|
b08a283fe5 | ||
|
|
45a2805100 | ||
|
|
cc8157ecf1 | ||
|
|
0c98aca5f0 | ||
|
|
170e4b3530 | ||
|
|
5ed91e9f6e |
23
.github/workflows/deltachat-rpc-server.yml
vendored
23
.github/workflows/deltachat-rpc-server.yml
vendored
@@ -271,13 +271,18 @@ jobs:
|
||||
name: Build & Publish npm prebuilds and deltachat-rpc-server
|
||||
needs: ["build_linux", "build_windows", "build_macos"]
|
||||
runs-on: "ubuntu-latest"
|
||||
permissions:
|
||||
id-token: write
|
||||
|
||||
# Needed to publish the binaries to the release.
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
show-progress: false
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Download Linux aarch64 binary
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -368,7 +373,7 @@ jobs:
|
||||
for platform in ./platform_package/*; do npm pack "$platform"; done
|
||||
npm pack
|
||||
ls -lah
|
||||
|
||||
|
||||
- name: Upload to artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -383,11 +388,19 @@ jobs:
|
||||
run: |
|
||||
gh release upload ${{ github.ref_name }} \
|
||||
--repo ${{ github.repository }} \
|
||||
*.tgz
|
||||
deltachat-rpc-server/npm-package/*.tgz
|
||||
|
||||
# Configure Node.js for publishing.
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Publish npm packets for prebuilds and `@deltachat/stdio-rpc-server`
|
||||
if: github.event_name == 'release'
|
||||
working-directory: deltachat-rpc-server/npm-package
|
||||
run: |
|
||||
ls -lah platform_package
|
||||
|
||||
for platform in *.tgz; do npm publish "$platform"; done
|
||||
for platform in *.tgz; do npm publish --provenance "$platform"; done
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
67
CHANGELOG.md
67
CHANGELOG.md
@@ -1,5 +1,68 @@
|
||||
# Changelog
|
||||
|
||||
## [1.138.4] - 2024-05-15
|
||||
|
||||
### CI
|
||||
|
||||
- Run actions/setup-node before npm publish.
|
||||
|
||||
## [1.138.3] - 2024-05-15
|
||||
|
||||
### CI
|
||||
|
||||
- Give CI job permission to publish binaries to the release.
|
||||
|
||||
## [1.138.2] - 2024-05-15
|
||||
|
||||
### API-Changes
|
||||
|
||||
- deltachat-rpc-client: Add CONFIG_SYNCED constant.
|
||||
|
||||
### CI
|
||||
|
||||
- Add npm token to publish deltachat-rpc-server packages.
|
||||
|
||||
### Features / Changes
|
||||
|
||||
- Reset more settings when configuring a chatmail account.
|
||||
|
||||
### Tests
|
||||
|
||||
- Set configuration after configure() finishes.
|
||||
|
||||
## [1.138.1] - 2024-05-14
|
||||
|
||||
### Features / Changes
|
||||
|
||||
- Detect XCHATMAIL capability and expose it as `is_chatmail` config.
|
||||
|
||||
### Fixes
|
||||
|
||||
- Never treat message with Chat-Group-ID as a private reply.
|
||||
- Always prefer Chat-Group-ID over In-Reply-To and References.
|
||||
- Ignore parent message if message references itself.
|
||||
|
||||
### CI
|
||||
|
||||
- Set RUSTUP_WINDOWS_PATH_ADD_BIN to work around `nextest` issue <https://github.com/nextest-rs/nextest/issues/1493>.
|
||||
- deltachat-rpc-server: Fix upload of npm packages to github releases ([#5564](https://github.com/deltachat/deltachat-core-rust/pull/5564)).
|
||||
|
||||
### Refactor
|
||||
|
||||
- Add MimeMessage.get_chat_group_id().
|
||||
- Make MimeMessage.get_header() return Option<&str>.
|
||||
- sql: Make open flags immutable.
|
||||
- Resultify token::lookup_or_new().
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- cargo: Bump parking_lot from 0.12.1 to 0.12.2.
|
||||
- cargo: Bump libc from 0.2.153 to 0.2.154.
|
||||
- cargo: Bump hickory-resolver from 0.24.0 to 0.24.1.
|
||||
- cargo: Bump serde_json from 1.0.115 to 1.0.116.
|
||||
- cargo: Bump human-panic from 1.2.3 to 2.0.0.
|
||||
- cargo: Bump brotli from 5.0.0 to 6.0.0.
|
||||
|
||||
## [1.138.0] - 2024-05-13
|
||||
|
||||
### API-Changes
|
||||
@@ -4072,3 +4135,7 @@ https://github.com/deltachat/deltachat-core-rust/pulls?q=is%3Apr+is%3Aclosed
|
||||
[1.137.3]: https://github.com/deltachat/deltachat-core-rust/compare/v1.137.2...v1.137.3
|
||||
[1.137.4]: https://github.com/deltachat/deltachat-core-rust/compare/v1.137.3...v1.137.4
|
||||
[1.138.0]: https://github.com/deltachat/deltachat-core-rust/compare/v1.137.4...v1.138.0
|
||||
[1.138.1]: https://github.com/deltachat/deltachat-core-rust/compare/v1.138.0...v1.138.1
|
||||
[1.138.2]: https://github.com/deltachat/deltachat-core-rust/compare/v1.138.1...v1.138.2
|
||||
[1.138.3]: https://github.com/deltachat/deltachat-core-rust/compare/v1.138.2...v1.138.3
|
||||
[1.138.4]: https://github.com/deltachat/deltachat-core-rust/compare/v1.138.3...v1.138.4
|
||||
|
||||
34
Cargo.lock
generated
34
Cargo.lock
generated
@@ -567,9 +567,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "5.0.0"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19483b140a7ac7174d34b5a581b406c64f84da5409d3e09cf4fff604f9270e67"
|
||||
checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
@@ -1157,7 +1157,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
@@ -1250,7 +1250,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-jsonrpc"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel 2.2.1",
|
||||
@@ -1274,7 +1274,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-repl"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
@@ -1289,7 +1289,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-rpc-server"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deltachat",
|
||||
@@ -1318,7 +1318,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat_ffi"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deltachat",
|
||||
@@ -2363,9 +2363,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hickory-resolver"
|
||||
version = "0.24.0"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35b8f021164e6a984c9030023544c57789c51760065cd510572fedcfb04164e8"
|
||||
checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
@@ -2468,9 +2468,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "human-panic"
|
||||
version = "1.2.3"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4f016c89920bbb30951a8405ecacbb4540db5524313b9445736e7e1855cf370"
|
||||
checksum = "a4c5d0e9120f6bca6120d142c7ede1ba376dd6bf276d69dd3dbe6cbeb7824179"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"os_info",
|
||||
@@ -2835,9 +2835,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.154"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
@@ -3398,9 +3398,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
@@ -4550,9 +4550,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.115"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
|
||||
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
rust-version = "1.77"
|
||||
@@ -47,7 +47,7 @@ async-smtp = { version = "0.9", default-features = false, features = ["runtime-t
|
||||
async_zip = { version = "0.0.12", default-features = false, features = ["deflate", "fs"] }
|
||||
backtrace = "0.3"
|
||||
base64 = "0.22"
|
||||
brotli = { version = "5", default-features=false, features = ["std"] }
|
||||
brotli = { version = "6", default-features=false, features = ["std"] }
|
||||
chrono = { workspace = true }
|
||||
email = { git = "https://github.com/deltachat/rust-email", branch = "master" }
|
||||
encoded-words = { git = "https://github.com/async-email/encoded-words", branch = "master" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat_ffi"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
description = "Deltachat FFI"
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
@@ -17,7 +17,7 @@ crate-type = ["cdylib", "staticlib"]
|
||||
deltachat = { path = "../", default-features = false }
|
||||
deltachat-jsonrpc = { path = "../deltachat-jsonrpc", optional = true }
|
||||
libc = "0.2"
|
||||
human-panic = { version = "1", default-features = false }
|
||||
human-panic = { version = "2", default-features = false }
|
||||
num-traits = "0.2"
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1.37.0", features = ["rt-multi-thread"] }
|
||||
|
||||
@@ -517,6 +517,7 @@ char* dc_get_blobdir (const dc_context_t* context);
|
||||
* 0=Nothing else happens when the key changes.
|
||||
* 1=After the key changed, `dc_chat_can_send()` returns false and `dc_chat_is_protection_broken()` returns true
|
||||
* until `dc_accept_chat()` is called.
|
||||
* - `is_chatmail` = 1 if the the server is a chatmail server, 0 otherwise.
|
||||
* - `ui.*` = All keys prefixed by `ui.` can be used by the user-interfaces for system-specific purposes.
|
||||
* The prefix should be followed by the system and maybe subsystem,
|
||||
* e.g. `ui.desktop.foo`, `ui.desktop.linux.bar`, `ui.android.foo`, `ui.dc40.bar`, `ui.bot.simplebot.baz`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-jsonrpc"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
description = "DeltaChat JSON-RPC API"
|
||||
edition = "2021"
|
||||
default-run = "deltachat-jsonrpc-server"
|
||||
|
||||
@@ -54,5 +54,5 @@
|
||||
},
|
||||
"type": "module",
|
||||
"types": "dist/deltachat.d.ts",
|
||||
"version": "1.138.0"
|
||||
"version": "1.138.4"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-repl"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
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.138.0"
|
||||
version = "1.138.4"
|
||||
description = "Python client for Delta Chat core JSON-RPC interface"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
|
||||
@@ -61,6 +61,7 @@ class EventType(str, Enum):
|
||||
WEBXDC_INSTANCE_DELETED = "WebxdcInstanceDeleted"
|
||||
CHATLIST_CHANGED = "ChatlistChanged"
|
||||
CHATLIST_ITEM_CHANGED = "ChatlistItemChanged"
|
||||
CONFIG_SYNCED = "ConfigSynced"
|
||||
|
||||
|
||||
class ChatId(IntEnum):
|
||||
|
||||
@@ -508,8 +508,8 @@ def test_reactions_for_a_reordering_move(acfactory):
|
||||
"""
|
||||
(ac1,) = acfactory.get_online_accounts(1)
|
||||
ac2 = acfactory.new_preconfigured_account()
|
||||
ac2.set_config("mvbox_move", "1")
|
||||
ac2.configure()
|
||||
ac2.set_config("mvbox_move", "1")
|
||||
ac2.bring_online()
|
||||
chat1 = acfactory.get_accepted_chat(ac1, ac2)
|
||||
ac2.stop_io()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-rpc-server"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
description = "DeltaChat JSON-RPC server"
|
||||
edition = "2021"
|
||||
readme = "README.md"
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
},
|
||||
"type": "module",
|
||||
"types": "index.d.ts",
|
||||
"version": "1.138.0"
|
||||
"version": "1.138.4"
|
||||
}
|
||||
|
||||
@@ -55,5 +55,5 @@
|
||||
"test:mocha": "mocha node/test/test.mjs --growl --reporter=spec --bail --exit"
|
||||
},
|
||||
"types": "node/dist/index.d.ts",
|
||||
"version": "1.138.0"
|
||||
"version": "1.138.4"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "deltachat"
|
||||
version = "1.138.0"
|
||||
version = "1.138.4"
|
||||
description = "Python bindings for the Delta Chat Core library using CFFI against the Rust-implemented libdeltachat"
|
||||
readme = "README.rst"
|
||||
requires-python = ">=3.7"
|
||||
|
||||
@@ -275,6 +275,7 @@ class ACSetup:
|
||||
def __init__(self, testprocess, init_time) -> None:
|
||||
self._configured_events = Queue()
|
||||
self._account2state: Dict[Account, str] = {}
|
||||
self._account2config: Dict[Account, Dict[str, str]] = {}
|
||||
self._imap_cleaned: Set[str] = set()
|
||||
self.testprocess = testprocess
|
||||
self.init_time = init_time
|
||||
@@ -336,6 +337,8 @@ class ACSetup:
|
||||
if not success:
|
||||
pytest.fail(f"configuring online account {acc} failed: {comment}")
|
||||
self._account2state[acc] = self.CONFIGURED
|
||||
if acc in self._account2config:
|
||||
acc.update_config(self._account2config[acc])
|
||||
return acc
|
||||
|
||||
def _onconfigure_start_io(self, acc):
|
||||
@@ -523,6 +526,7 @@ class ACFactory:
|
||||
configdict.setdefault("sentbox_watch", False)
|
||||
configdict.setdefault("sync_msgs", False)
|
||||
ac.update_config(configdict)
|
||||
self._acsetup._account2config[ac] = configdict
|
||||
self._preconfigure_key(ac, configdict["addr"])
|
||||
return ac
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
2024-05-13
|
||||
2024-05-15
|
||||
@@ -254,6 +254,9 @@ pub enum Config {
|
||||
/// True if account is configured.
|
||||
Configured,
|
||||
|
||||
/// True if account is a chatmail account.
|
||||
IsChatmail,
|
||||
|
||||
/// All secondary self addresses separated by spaces
|
||||
/// (`addr1@example.org addr2@example.org addr3@example.org`)
|
||||
SecondaryAddrs,
|
||||
|
||||
@@ -112,6 +112,11 @@ impl Context {
|
||||
|
||||
let mut param = LoginParam::load_candidate_params(self).await?;
|
||||
let old_addr = self.get_config(Config::ConfiguredAddr).await?;
|
||||
|
||||
// Reset our knowledge about whether the server is a chatmail server.
|
||||
// We will update it when we connect to IMAP.
|
||||
self.set_config_internal(Config::IsChatmail, None).await?;
|
||||
|
||||
let success = configure(self, &mut param).await;
|
||||
self.set_config_internal(Config::NotifyAboutWrongPw, None)
|
||||
.await?;
|
||||
@@ -453,6 +458,14 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
|
||||
progress!(ctx, 900);
|
||||
|
||||
if imap_session.is_chatmail() {
|
||||
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?;
|
||||
}
|
||||
|
||||
let create_mvbox = ctx.should_watch_mvbox().await?;
|
||||
|
||||
imap.configure_folders(ctx, &mut imap_session, create_mvbox)
|
||||
|
||||
@@ -461,18 +461,10 @@ impl Context {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
if self
|
||||
.get_config(Config::ConfiguredAddr)
|
||||
.await
|
||||
.unwrap_or_default()
|
||||
.filter(|s| s.ends_with(".testrun.org"))
|
||||
.is_some()
|
||||
{
|
||||
let mut lock = self.ratelimit.write().await;
|
||||
// Allow at least 1 message every second + a burst of 3.
|
||||
*lock = Ratelimit::new(Duration::new(3, 0), 3.0);
|
||||
}
|
||||
if self.is_chatmail().await.unwrap_or_default() {
|
||||
let mut lock = self.ratelimit.write().await;
|
||||
// Allow at least 1 message every second + a burst of 3.
|
||||
*lock = Ratelimit::new(Duration::new(3, 0), 3.0);
|
||||
}
|
||||
self.scheduler.start(self.clone()).await;
|
||||
}
|
||||
@@ -493,6 +485,11 @@ impl Context {
|
||||
self.scheduler.maybe_network().await;
|
||||
}
|
||||
|
||||
/// Returns true if an account is on a chatmail server.
|
||||
pub async fn is_chatmail(&self) -> Result<bool> {
|
||||
self.get_config_bool(Config::IsChatmail).await
|
||||
}
|
||||
|
||||
/// Does a background fetch
|
||||
/// pauses the scheduler and does one imap fetch, then unpauses and returns
|
||||
pub async fn background_fetch(&self) -> Result<()> {
|
||||
@@ -799,6 +796,8 @@ impl Context {
|
||||
res.insert("imap_server_id", format!("{server_id:?}"));
|
||||
}
|
||||
|
||||
res.insert("is_chatmail", self.is_chatmail().await?.to_string());
|
||||
|
||||
if let Some(metadata) = &*self.metadata.read().await {
|
||||
if let Some(comment) = &metadata.comment {
|
||||
res.insert("imap_server_comment", format!("{comment:?}"));
|
||||
|
||||
@@ -32,6 +32,14 @@ pub(crate) struct Capabilities {
|
||||
/// This is supported by <https://github.com/deltachat/chatmail>
|
||||
pub can_push: bool,
|
||||
|
||||
/// True if the server has an XCHATMAIL capability
|
||||
/// indicating that it is a <https://github.com/deltachat/chatmail> server.
|
||||
///
|
||||
/// This can be used to hide some advanced settings in the UI
|
||||
/// that are only interesting for normal email accounts,
|
||||
/// e.g. the ability to move messages to Delta Chat folder.
|
||||
pub is_chatmail: bool,
|
||||
|
||||
/// Server ID if the server supports ID capability.
|
||||
pub server_id: Option<HashMap<String, String>>,
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ async fn determine_capabilities(
|
||||
can_condstore: caps.has_str("CONDSTORE"),
|
||||
can_metadata: caps.has_str("METADATA"),
|
||||
can_push: caps.has_str("XDELTAPUSH"),
|
||||
is_chatmail: caps.has_str("XCHATMAIL"),
|
||||
server_id,
|
||||
};
|
||||
Ok(capabilities)
|
||||
|
||||
@@ -94,6 +94,11 @@ impl Session {
|
||||
self.capabilities.can_push
|
||||
}
|
||||
|
||||
// Returns true if IMAP server has `XCHATMAIL` capability.
|
||||
pub fn is_chatmail(&self) -> bool {
|
||||
self.capabilities.is_chatmail
|
||||
}
|
||||
|
||||
/// Returns the names of all folders on the IMAP server.
|
||||
pub async fn list_folders(&mut self) -> Result<Vec<async_imap::types::Name>> {
|
||||
let list = self.list(Some(""), Some("*")).await?.try_collect().await?;
|
||||
|
||||
@@ -556,19 +556,25 @@ impl MimeMessage {
|
||||
|
||||
/// Parses avatar action headers.
|
||||
async fn parse_avatar_headers(&mut self, context: &Context) {
|
||||
if let Some(header_value) = self.get_header(HeaderDef::ChatGroupAvatar).cloned() {
|
||||
self.group_avatar = self.avatar_action_from_header(context, header_value).await;
|
||||
if let Some(header_value) = self.get_header(HeaderDef::ChatGroupAvatar) {
|
||||
self.group_avatar = self
|
||||
.avatar_action_from_header(context, header_value.to_string())
|
||||
.await;
|
||||
}
|
||||
|
||||
if let Some(header_value) = self.get_header(HeaderDef::ChatUserAvatar).cloned() {
|
||||
self.user_avatar = self.avatar_action_from_header(context, header_value).await;
|
||||
if let Some(header_value) = self.get_header(HeaderDef::ChatUserAvatar) {
|
||||
self.user_avatar = self
|
||||
.avatar_action_from_header(context, header_value.to_string())
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_videochat_headers(&mut self) {
|
||||
if let Some(value) = self.get_header(HeaderDef::ChatContent).cloned() {
|
||||
if let Some(value) = self.get_header(HeaderDef::ChatContent) {
|
||||
if value == "videochat-invitation" {
|
||||
let instance = self.get_header(HeaderDef::ChatWebrtcRoom).cloned();
|
||||
let instance = self
|
||||
.get_header(HeaderDef::ChatWebrtcRoom)
|
||||
.map(|s| s.to_string());
|
||||
if let Some(part) = self.parts.first_mut() {
|
||||
part.typ = Viewtype::VideochatInvitation;
|
||||
part.param
|
||||
@@ -815,12 +821,14 @@ impl MimeMessage {
|
||||
.map(|s| s.to_string())
|
||||
}
|
||||
|
||||
pub fn get_header(&self, headerdef: HeaderDef) -> Option<&String> {
|
||||
self.headers.get(headerdef.get_headername())
|
||||
pub fn get_header(&self, headerdef: HeaderDef) -> Option<&str> {
|
||||
self.headers
|
||||
.get(headerdef.get_headername())
|
||||
.map(|s| s.as_str())
|
||||
}
|
||||
|
||||
/// Returns `Chat-Group-ID` header value if it is a valid group ID.
|
||||
pub fn get_chat_group_id(&self) -> Option<&String> {
|
||||
pub fn get_chat_group_id(&self) -> Option<&str> {
|
||||
self.get_header(HeaderDef::ChatGroupId)
|
||||
.filter(|s| validate_id(s))
|
||||
}
|
||||
|
||||
@@ -1373,11 +1373,9 @@ async fn add_parts(
|
||||
|
||||
let mime_in_reply_to = mime_parser
|
||||
.get_header(HeaderDef::InReplyTo)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let mime_references = mime_parser
|
||||
.get_header(HeaderDef::References)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
|
||||
// fine, so far. now, split the message into simple parts usable as "short messages"
|
||||
@@ -1437,7 +1435,7 @@ async fn add_parts(
|
||||
let reaction_str = simplify::remove_footers(part.msg.as_str());
|
||||
set_msg_reaction(
|
||||
context,
|
||||
&mime_in_reply_to,
|
||||
mime_in_reply_to,
|
||||
orig_chat_id.unwrap_or_default(),
|
||||
from_id,
|
||||
sort_timestamp,
|
||||
@@ -2463,7 +2461,7 @@ async fn apply_mailinglist_changes(
|
||||
|
||||
fn try_getting_grpid(mime_parser: &MimeMessage) -> Option<String> {
|
||||
if let Some(optional_field) = mime_parser.get_chat_group_id() {
|
||||
return Some(optional_field.clone());
|
||||
return Some(optional_field.to_string());
|
||||
}
|
||||
|
||||
// Useful for undecipherable messages sent to known group.
|
||||
|
||||
@@ -466,6 +466,12 @@ pub async fn convert_folder_meaning(
|
||||
}
|
||||
|
||||
async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session) -> Result<Session> {
|
||||
ctx.set_config_internal(
|
||||
Config::IsChatmail,
|
||||
crate::config::from_bool(session.is_chatmail()),
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Update quota no more than once a minute.
|
||||
let quota_needs_update = {
|
||||
let quota = ctx.quota.read().await;
|
||||
|
||||
@@ -65,8 +65,8 @@ pub async fn get_securejoin_qr(context: &Context, group: Option<ChatId>) -> Resu
|
||||
let sync_token = token::lookup(context, Namespace::InviteNumber, group)
|
||||
.await?
|
||||
.is_none();
|
||||
let invitenumber = token::lookup_or_new(context, Namespace::InviteNumber, group).await;
|
||||
let auth = token::lookup_or_new(context, Namespace::Auth, group).await;
|
||||
let invitenumber = token::lookup_or_new(context, Namespace::InviteNumber, group).await?;
|
||||
let auth = token::lookup_or_new(context, Namespace::Auth, group).await?;
|
||||
let self_addr = context.get_primary_self_addr().await?;
|
||||
let self_name = context
|
||||
.get_config(Config::Displayname)
|
||||
@@ -294,7 +294,7 @@ pub(crate) async fn handle_securejoin_handshake(
|
||||
|
||||
let join_vg = step.starts_with("vg-");
|
||||
|
||||
if !matches!(step.as_str(), "vg-request" | "vc-request") {
|
||||
if !matches!(step, "vg-request" | "vc-request") {
|
||||
let mut self_found = false;
|
||||
let self_fingerprint = load_self_public_key(context).await?.fingerprint();
|
||||
for (addr, key) in &mime_message.gossiped_keys {
|
||||
@@ -311,7 +311,7 @@ pub(crate) async fn handle_securejoin_handshake(
|
||||
}
|
||||
}
|
||||
|
||||
match step.as_str() {
|
||||
match step {
|
||||
"vg-request" | "vc-request" => {
|
||||
/*=======================================================
|
||||
==== Alice - the inviter side ====
|
||||
@@ -487,7 +487,7 @@ pub(crate) async fn handle_securejoin_handshake(
|
||||
=======================================================*/
|
||||
"vc-contact-confirm" => {
|
||||
if let Some(mut bobstate) = BobState::from_db(&context.sql).await? {
|
||||
if !bobstate.is_msg_expected(context, step.as_str()) {
|
||||
if !bobstate.is_msg_expected(context, step) {
|
||||
warn!(context, "Unexpected vc-contact-confirm.");
|
||||
return Ok(HandshakeMessage::Ignore);
|
||||
}
|
||||
@@ -498,9 +498,7 @@ pub(crate) async fn handle_securejoin_handshake(
|
||||
Ok(HandshakeMessage::Ignore)
|
||||
}
|
||||
"vg-member-added" => {
|
||||
let Some(member_added) = mime_message
|
||||
.get_header(HeaderDef::ChatGroupMemberAdded)
|
||||
.map(|s| s.as_str())
|
||||
let Some(member_added) = mime_message.get_header(HeaderDef::ChatGroupMemberAdded)
|
||||
else {
|
||||
warn!(
|
||||
context,
|
||||
@@ -516,7 +514,7 @@ pub(crate) async fn handle_securejoin_handshake(
|
||||
return Ok(HandshakeMessage::Propagate);
|
||||
}
|
||||
if let Some(mut bobstate) = BobState::from_db(&context.sql).await? {
|
||||
if !bobstate.is_msg_expected(context, step.as_str()) {
|
||||
if !bobstate.is_msg_expected(context, step) {
|
||||
warn!(context, "Unexpected vg-member-added.");
|
||||
return Ok(HandshakeMessage::Propagate);
|
||||
}
|
||||
@@ -571,7 +569,7 @@ pub(crate) async fn observe_securejoin_on_other_device(
|
||||
info!(context, "Observing secure-join message {step:?}.");
|
||||
|
||||
if !matches!(
|
||||
step.as_str(),
|
||||
step,
|
||||
"vg-request-with-auth" | "vc-request-with-auth" | "vg-member-added" | "vc-contact-confirm"
|
||||
) {
|
||||
return Ok(HandshakeMessage::Ignore);
|
||||
@@ -642,21 +640,21 @@ pub(crate) async fn observe_securejoin_on_other_device(
|
||||
|
||||
ChatId::set_protection_for_contact(context, contact_id, mime_message.timestamp_sent).await?;
|
||||
|
||||
if step.as_str() == "vg-member-added" {
|
||||
if step == "vg-member-added" {
|
||||
inviter_progress(context, contact_id, 800);
|
||||
}
|
||||
if step.as_str() == "vg-member-added" || step.as_str() == "vc-contact-confirm" {
|
||||
if step == "vg-member-added" || step == "vc-contact-confirm" {
|
||||
inviter_progress(context, contact_id, 1000);
|
||||
}
|
||||
|
||||
if step.as_str() == "vg-request-with-auth" || step.as_str() == "vc-request-with-auth" {
|
||||
if step == "vg-request-with-auth" || step == "vc-request-with-auth" {
|
||||
// This actually reflects what happens on the first device (which does the secure
|
||||
// join) and causes a subsequent "vg-member-added" message to create an unblocked
|
||||
// verified group.
|
||||
ChatId::create_for_contact_with_blocked(context, contact_id, Blocked::Not).await?;
|
||||
}
|
||||
|
||||
if step.as_str() == "vg-member-added" {
|
||||
if step == "vg-member-added" {
|
||||
Ok(HandshakeMessage::Propagate)
|
||||
} else {
|
||||
Ok(HandshakeMessage::Ignore)
|
||||
|
||||
@@ -261,7 +261,7 @@ impl BobState {
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
if !self.is_msg_expected(context, step.as_str()) {
|
||||
if !self.is_msg_expected(context, step) {
|
||||
info!(context, "{} message out of sync for BobState", step);
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -671,10 +671,9 @@ impl Sql {
|
||||
/// `passphrase` is the SQLCipher database passphrase.
|
||||
/// Empty string if database is not encrypted.
|
||||
fn new_connection(path: &Path, passphrase: &str) -> Result<Connection> {
|
||||
let mut flags = OpenFlags::SQLITE_OPEN_NO_MUTEX;
|
||||
flags.insert(OpenFlags::SQLITE_OPEN_READ_WRITE);
|
||||
flags.insert(OpenFlags::SQLITE_OPEN_CREATE);
|
||||
|
||||
let flags = OpenFlags::SQLITE_OPEN_NO_MUTEX
|
||||
| OpenFlags::SQLITE_OPEN_READ_WRITE
|
||||
| OpenFlags::SQLITE_OPEN_CREATE;
|
||||
let conn = Connection::open_with_flags(path, flags)?;
|
||||
conn.execute_batch(
|
||||
"PRAGMA cipher_memory_security = OFF; -- Too slow on Android
|
||||
|
||||
10
src/token.rs
10
src/token.rs
@@ -93,14 +93,14 @@ pub async fn lookup_or_new(
|
||||
context: &Context,
|
||||
namespace: Namespace,
|
||||
foreign_id: Option<ChatId>,
|
||||
) -> String {
|
||||
if let Ok(Some(token)) = lookup(context, namespace, foreign_id).await {
|
||||
return token;
|
||||
) -> Result<String> {
|
||||
if let Some(token) = lookup(context, namespace, foreign_id).await? {
|
||||
return Ok(token);
|
||||
}
|
||||
|
||||
let token = create_id();
|
||||
save(context, namespace, foreign_id, &token).await.ok();
|
||||
token
|
||||
save(context, namespace, foreign_id, &token).await?;
|
||||
Ok(token)
|
||||
}
|
||||
|
||||
pub async fn exists(context: &Context, namespace: Namespace, token: &str) -> Result<bool> {
|
||||
|
||||
Reference in New Issue
Block a user