diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 29dfbccdf..602e2597c 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -461,10 +461,6 @@ char* dc_get_blobdir (const dc_context_t* context); * - `gossip_period` = How often to gossip Autocrypt keys in chats with multiple recipients, in * seconds. 2 days by default. * This is not supposed to be changed by UIs and only used for testing. - * - `is_chatmail` = (deprecated) 1 if the the server is a chatmail server, 0 otherwise. - * This is deprecated, UIs should not behave differently - * for chatmail relays and classical email servers. - * Most usages in UIs can be replaced by `force_encryption`. * - `is_muted` = Whether a context is muted by the user. * Muted contexts should not sound, vibrate or show notifications. * In contrast to `dc_set_chat_mute_duration()`, diff --git a/deltachat-rpc-client/tests/test_something.py b/deltachat-rpc-client/tests/test_something.py index cd04380b9..541497a83 100644 --- a/deltachat-rpc-client/tests/test_something.py +++ b/deltachat-rpc-client/tests/test_something.py @@ -421,7 +421,6 @@ def test_dont_move_sync_msgs(acf, direct_imap): addr, password = acf.get_credentials() ac1 = acf.get_unconfigured_account() ac1.set_config("bcc_self", "1") - ac1.set_config("fix_is_chatmail", "1") ac1.add_or_update_transport({"addr": addr, "password": password}) ac1.start_io() ac1_direct_imap = direct_imap(ac1) diff --git a/src/config.rs b/src/config.rs index 5010da6cf..b509a8c20 100644 --- a/src/config.rs +++ b/src/config.rs @@ -305,18 +305,6 @@ pub enum Config { /// True if account is configured. Configured, - /// Deprecated, we are trying to get rid of this global setting. - /// It is possible to configure a profile with both chatmail relays - /// and classical email servers. - /// - /// Most usages in UIs can be replaced by `force_encryption`. - /// - /// True if account is a chatmail account. - IsChatmail, - - /// True if `IsChatmail` mustn't be autoconfigured. For tests. - FixIsChatmail, - /// True if account is muted. IsMuted, diff --git a/src/configure.rs b/src/configure.rs index 57670059b..d9a83d7a8 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -490,17 +490,6 @@ pub(crate) async fn configure( progress!(ctx, 900); - let is_configured = ctx.is_configured().await?; - if !ctx.get_config_bool(Config::FixIsChatmail).await? { - if imap_session.is_chatmail() { - ctx.sql.set_raw_config("is_chatmail", Some("1")).await?; - } else if !is_configured { - // Reset the setting that may have been set - // during failed configuration. - ctx.sql.set_raw_config("is_chatmail", Some("0")).await?; - } - } - // Drop the imap connection explicitly // to make sure that it's not forgotten in a future refactoring drop(imap_session); diff --git a/src/context.rs b/src/context.rs index 7d5384116..c6d9f81bd 100644 --- a/src/context.rs +++ b/src/context.rs @@ -568,15 +568,6 @@ impl Context { self.scheduler.maybe_network().await; } - /// Deprecated, we are trying to get rid of this global setting. - /// It is possible to configure a profile with both chatmail relays - /// and classical email servers. - /// - /// Returns true if an account is on a chatmail server. - pub async fn is_chatmail(&self) -> Result { - self.get_config_bool(Config::IsChatmail).await - } - /// Returns maximum number of recipients a single email can be sent to. pub(crate) async fn get_max_smtp_rcpt_to(&self) -> Result { let Some((transport_id, param)) = ConfiguredLoginParam::load(self).await? else { @@ -885,13 +876,6 @@ impl Context { res.insert("imap_server_id", format!("{server_id:?}")); } - 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(), diff --git a/src/e2ee.rs b/src/e2ee.rs index c762643c1..6d5e5359d 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -6,7 +6,6 @@ mod tests { use crate::chat; use crate::chat::send_text_msg; - use crate::config::Config; use crate::message::Message; use crate::mimeparser::SystemMessage; use crate::receive_imf::receive_imf; @@ -61,7 +60,6 @@ Sent with my Delta Chat Messenger: https://delta.chat"; async fn test_chatmail_can_send_unencrypted() -> Result<()> { let mut tcm = TestContextManager::new(); let bob = &tcm.bob().await; - bob.set_config_bool(Config::IsChatmail, true).await?; bob.allow_unencrypted().await?; let bob_chat_id = receive_imf( bob, diff --git a/src/imap/capabilities.rs b/src/imap/capabilities.rs index 05bfa74e2..147782b30 100644 --- a/src/imap/capabilities.rs +++ b/src/imap/capabilities.rs @@ -25,14 +25,6 @@ pub(crate) struct Capabilities { /// pub can_compress: bool, - /// True if the server has an XCHATMAIL capability - /// indicating that it is a 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>, } diff --git a/src/imap/client.rs b/src/imap/client.rs index 9f5d4de36..8b055b17c 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -82,7 +82,6 @@ pub(crate) async fn identify_server( can_check_quota: caps.has_str("QUOTA"), can_metadata: caps.has_str("METADATA"), can_compress: caps.has_str("COMPRESS=DEFLATE"), - is_chatmail: caps.has_str("XCHATMAIL"), server_id, }; Ok(capabilities) diff --git a/src/imap/session.rs b/src/imap/session.rs index f04570193..8287dd664 100644 --- a/src/imap/session.rs +++ b/src/imap/session.rs @@ -111,11 +111,6 @@ impl Session { self.capabilities.can_metadata } - // Returns true if IMAP server has `XCHATMAIL` capability. - pub(crate) fn is_chatmail(&self) -> bool { - self.capabilities.is_chatmail - } - /// Prefetch `n_uids` messages starting from `uid_next`. Returns a list of fetch results in the /// order of ascending UIDs. #[expect(clippy::arithmetic_side_effects)] diff --git a/src/imex.rs b/src/imex.rs index c9bcd121a..47a9f9bd3 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -981,7 +981,6 @@ mod tests { context1.get_config(Config::BccSelf).await?, Some("0".to_string()) ); - context1.set_config_bool(Config::IsChatmail, true).await?; assert_eq!(context1.get_config_bool(Config::IsMuted).await?, false); context1.set_config_bool(Config::IsMuted, true).await?; @@ -1001,7 +1000,6 @@ mod tests { .get_matching(|evt| matches!(evt, EventType::ImexProgress(1000))) .await; assert!(context2.is_configured().await?); - assert!(context2.is_chatmail().await?); for ctx in [context1, context2] { // BccSelf should be enabled automatically when exporting a backup assert_eq!(ctx.get_config_bool(Config::BccSelf).await?, true); diff --git a/src/scheduler.rs b/src/scheduler.rs index 6264181a7..f786a81bc 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -521,7 +521,6 @@ async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session) }; maybe_broadcast_reactions(ctx).await.log_err(ctx).ok(); - maybe_send_stats(ctx).await.log_err(ctx).ok(); session .update_metadata(ctx) @@ -534,6 +533,8 @@ async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session) ); } + maybe_send_stats(ctx).await.log_err(ctx).ok(); + let session = fetch_idle(ctx, imap, session).await?; Ok(session) } diff --git a/src/sql/migrations/migrations_tests.rs b/src/sql/migrations/migrations_tests.rs index ed684002b..98d48c80f 100644 --- a/src/sql/migrations/migrations_tests.rs +++ b/src/sql/migrations/migrations_tests.rs @@ -16,15 +16,15 @@ async fn test_clear_config_cache() -> anyhow::Result<()> { // This test checks that the config cache is invalidated in `execute_migration()`. let t = TestContext::new().await; - assert_eq!(t.get_config_bool(Config::IsChatmail).await?, false); + assert_eq!(t.sql.get_raw_config_bool("cached_key").await?, false); t.sql .execute_migration( - "INSERT INTO config (keyname, value) VALUES ('is_chatmail', '1')", + "INSERT INTO config (keyname, value) VALUES ('cached_key', '1')", 1000, ) .await?; - assert_eq!(t.get_config_bool(Config::IsChatmail).await?, true); + assert_eq!(t.sql.get_raw_config_bool("cached_key").await?, true); assert_eq!(t.sql.get_raw_config_int(VERSION_CFG).await?.unwrap(), 1000); Ok(()) diff --git a/src/stats.rs b/src/stats.rs index e23736e63..d5d4c5521 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -42,7 +42,8 @@ struct Statistics { /// Size of the public key in bytes (encoded in binary, not base64). pubkey_size: usize, stats_id: String, - is_chatmail: bool, + /// Whether all transports are chatmail relays, `None` if not known for all of them. + is_chatmail: Option, contact_stats: Vec, message_stats: BTreeMap, securejoin_sources: SecurejoinSources, @@ -350,16 +351,22 @@ async fn get_stats(context: &Context) -> Result { let sending_disabled_timestamps = get_timestamps(context, "stats_sending_disabled_events").await?; + let number_of_transports = context.count_transports().await?; + let metadata = context.metadata.read().await; + let is_chatmail = (!metadata.is_empty() && metadata.len() == number_of_transports) + .then(|| metadata.values().all(|m| m.supports_push)); + drop(metadata); + let stats = Statistics { core_version: DC_VERSION_STR.to_string(), - number_of_transports: context.count_transports().await?, + number_of_transports, key_create_timestamps, number_of_keys, key_version: self_public_key.primary_key.version().into(), key_algorithm: format!("{:?}", self_public_key.algorithm()), pubkey_size: DcKey::to_bytes(&self_public_key).len(), stats_id: stats_id(context).await?, - is_chatmail: context.is_chatmail().await?, + is_chatmail, contact_stats: get_contact_stats(context, last_old_contact).await?, message_stats: get_message_stats(context).await?, securejoin_sources: get_securejoin_source_stats(context).await?, diff --git a/src/stats/stats_tests.rs b/src/stats/stats_tests.rs index df75eb372..7ff5236aa 100644 --- a/src/stats/stats_tests.rs +++ b/src/stats/stats_tests.rs @@ -4,11 +4,13 @@ use super::*; use crate::chat::{ Chat, create_broadcast, create_group, create_group_unencrypted, get_chat_contacts, }; +use crate::imap::ServerMetadata; use crate::mimeparser::SystemMessage; use crate::qr::check_qr; use crate::securejoin::{get_securejoin_qr, join_securejoin, join_securejoin_with_ux_info}; use crate::test_utils::{TestContext, TestContextManager, get_chat_msg}; use crate::tools::SystemTime; +use crate::transport::add_pseudo_transport; use pretty_assertions::assert_eq; use serde_json::{Number, Value}; @@ -463,18 +465,33 @@ async fn test_stats_securejoin_invites() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_stats_is_chatmail() -> Result<()> { + async fn is_chatmail(context: &TestContext) -> Result { + let stats: Value = serde_json::from_str(&get_stats(context).await?)?; + Ok(stats.get("is_chatmail").unwrap().clone()) + } + let alice = &TestContext::new_alice().await; alice.set_config_bool(Config::StatsSending, true).await?; + assert!(is_chatmail(alice).await?.is_null()); - let r = get_stats(alice).await?; - let r: serde_json::Value = serde_json::from_str(&r)?; - assert_eq!(r.get("is_chatmail").unwrap().as_bool().unwrap(), false); + alice.metadata.write().await.insert( + 0, + ServerMetadata { + supports_push: true, + ..Default::default() + }, + ); + assert_eq!(is_chatmail(alice).await?, Value::Bool(true)); - alice.set_config_bool(Config::IsChatmail, true).await?; + add_pseudo_transport(alice, "alice@example.net").await?; + assert!(is_chatmail(alice).await?.is_null()); - let r = get_stats(alice).await?; - let r: serde_json::Value = serde_json::from_str(&r)?; - assert_eq!(r.get("is_chatmail").unwrap().as_bool().unwrap(), true); + alice + .metadata + .write() + .await + .insert(1, ServerMetadata::default()); + assert_eq!(is_chatmail(alice).await?, Value::Bool(false)); Ok(()) } diff --git a/src/sync.rs b/src/sync.rs index 9586fd849..ce8710c92 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -703,9 +703,7 @@ mod tests { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_send_sync_msg_enables_bccself() -> Result<()> { - for (chatmail, sync_message_sent) in - [(false, false), (false, true), (true, false), (true, true)] - { + for sync_message_sent in [false, true] { let alice1 = TestContext::new_alice().await; let alice2 = TestContext::new_alice().await; @@ -714,9 +712,6 @@ mod tests { alice1.set_config_bool(Config::SyncMsgs, true).await?; alice2.set_config_bool(Config::SyncMsgs, true).await?; - alice1.set_config_bool(Config::IsChatmail, chatmail).await?; - alice2.set_config_bool(Config::IsChatmail, chatmail).await?; - alice1.set_config_bool(Config::BccSelf, true).await?; alice2.set_config_bool(Config::BccSelf, false).await?; @@ -735,7 +730,7 @@ mod tests { alice1.send_text(chat.id, "Hi").await }; - // On chatmail accounts, BccSelf defaults to false. + // BccSelf defaults to false. // When receiving a sync message from another device, // there obviously is a multi-device-setup, and BccSelf // should be enabled.