mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 04:58:47 +03:00
api!: remove is_chatmail and the XCHATMAIL capability
This removes the last usages of the deprecated `is_chatmail` and no `XCHATMAIL` IMAP capability is read anymore. UIs are not using it for a longer time anymore. The self-reporting statistics now set `is_chatmail` field to `true`: all transports have relay-typical metadata `false`: at least one doesn't `null`: we don't know BREAKING CHANGE: `is_chatmail` is no longer a known config key.
This commit is contained in:
@@ -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()`,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<bool> {
|
||||
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<u32> {
|
||||
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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -25,14 +25,6 @@ pub(crate) struct Capabilities {
|
||||
/// <https://tools.ietf.org/html/rfc4978>
|
||||
pub can_compress: 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>>,
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
|
||||
13
src/stats.rs
13
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<bool>,
|
||||
contact_stats: Vec<ContactStat>,
|
||||
message_stats: BTreeMap<Chattype, MessageStats>,
|
||||
securejoin_sources: SecurejoinSources,
|
||||
@@ -350,16 +351,22 @@ async fn get_stats(context: &Context) -> Result<String> {
|
||||
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?,
|
||||
|
||||
@@ -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<Value> {
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user