From 86ad5506e3872586901111a863f112833f200ac8 Mon Sep 17 00:00:00 2001 From: iequidoo Date: Sat, 6 Jul 2024 11:58:11 -0300 Subject: [PATCH] feat: Always move outgoing auto-generated messages to the mvbox Recently there are many questions on the Delta Chat forum why some unexpected encrypted messages appear in Inbox. Seems they are mainly sync messages, though that also obviously happens to SecureJoin messages. Anyway, regardless of the `MvboxMove` setting, auto-generated outgoing messages should be moved to the DeltaChat folder so as not to complicate co-using Delta Chat with other MUAs. --- python/tests/test_1_online.py | 10 ++++++++++ src/config.rs | 18 +++++++----------- src/configure.rs | 3 +-- src/constants.rs | 2 +- src/headerdef.rs | 1 + src/imap.rs | 22 ++++++++++++++++++++-- src/imap/session.rs | 1 + 7 files changed, 41 insertions(+), 16 deletions(-) diff --git a/python/tests/test_1_online.py b/python/tests/test_1_online.py index d4f1901a8..2a476012c 100644 --- a/python/tests/test_1_online.py +++ b/python/tests/test_1_online.py @@ -484,6 +484,16 @@ 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) diff --git a/src/config.rs b/src/config.rs index 65f0cf012..3806cc802 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,7 +13,7 @@ use strum_macros::{AsRefStr, Display, EnumIter, EnumString}; use tokio::fs; use crate::blob::BlobObject; -use crate::constants::{self, DC_VERSION_STR}; +use crate::constants; use crate::context::Context; use crate::events::EventType; use crate::log::LogExt; @@ -131,7 +131,8 @@ pub enum Config { #[strum(props(default = "0"))] SentboxWatch, - /// True if chat messages should be moved to a separate folder. + /// True if chat messages should be moved to a separate folder. Auto-sent messages like sync + /// ones are moved there anyway. #[strum(props(default = "1"))] MvboxMove, @@ -385,9 +386,6 @@ 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 @@ -401,10 +399,7 @@ 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::MvboxMove | Config::OnlyFetchMvbox | Config::SentboxWatch - ) + matches!(self, Config::OnlyFetchMvbox | Config::SentboxWatch) } } @@ -430,7 +425,7 @@ impl Context { .into_owned() }) } - Config::SysVersion => Some((*DC_VERSION_STR).clone()), + Config::SysVersion => Some((*constants::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?, @@ -488,7 +483,8 @@ impl Context { /// Returns true if movebox ("DeltaChat" folder) should be watched. pub(crate) async fn should_watch_mvbox(&self) -> Result { Ok(self.get_config_bool(Config::MvboxMove).await? - || self.get_config_bool(Config::OnlyFetchMvbox).await?) + || self.get_config_bool(Config::OnlyFetchMvbox).await? + || !self.get_config_bool(Config::IsChatmail).await?) } /// Returns true if sentbox ("Sent" folder) should be watched. diff --git a/src/configure.rs b/src/configure.rs index 2f6b29deb..964eef1ad 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -477,8 +477,7 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> { ctx.set_config(Config::E2eeEnabled, Some("1")).await?; } - let create_mvbox = ctx.should_watch_mvbox().await?; - + let create_mvbox = !is_chatmail; imap.configure_folders(ctx, &mut imap_session, create_mvbox) .await?; diff --git a/src/constants.rs b/src/constants.rs index deb7d9cdf..72cda9b15 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -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 = 4; +pub(crate) const DC_FOLDERS_CONFIGURED_VERSION: i32 = 5; // 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 diff --git a/src/headerdef.rs b/src/headerdef.rs index 3b9b8e007..b4865dd71 100644 --- a/src/headerdef.rs +++ b/src/headerdef.rs @@ -11,6 +11,7 @@ pub enum HeaderDef { Date, From_, To, + AutoSubmitted, /// Carbon copy. Cc, diff --git a/src/imap.rs b/src/imap.rs index b313f2084..93dbbc463 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -446,7 +446,11 @@ impl Imap { .get_raw_config_int(constants::DC_FOLDERS_CONFIGURED_KEY) .await?; if folders_configured.unwrap_or_default() < constants::DC_FOLDERS_CONFIGURED_VERSION { - let create_mvbox = true; + 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?; self.configure_folders(context, &mut session, create_mvbox) .await?; } @@ -1811,6 +1815,20 @@ async fn needs_move_to_mvbox( context: &Context, headers: &[mailparse::MailHeader<'_>], ) -> Result { + 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 +1842,7 @@ async fn needs_move_to_mvbox( return Ok(false); } - if headers.get_header_value(HeaderDef::ChatVersion).is_some() { + if has_chat_version { Ok(true) } else if let Some(parent) = get_prefetch_parent_message(context, headers).await? { match parent.is_dc_message { diff --git a/src/imap/session.rs b/src/imap/session.rs index f085bc727..7896476f2 100644 --- a/src/imap/session.rs +++ b/src/imap/session.rs @@ -24,6 +24,7 @@ const PREFETCH_FLAGS: &str = "(UID INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIE FROM \ IN-REPLY-TO REFERENCES \ CHAT-VERSION \ + AUTO-SUBMITTED \ AUTOCRYPT-SETUP-MESSAGE\ )])";