Skip to content

Commit 2166412

Browse files
committed
fix: Change BccSelf default to 0 for chatmail (#6340)
Change `BccSelf` default to 0 for chatmail configurations and enable it upon a backup export. As for `DeleteServerAfter` who was set to 0 upon a backup export before, make its default dependent on `BccSelf` for chatmail. We don't need `BccSelf` for chatmail by default because we assume single-device use. Also `BccSelf` is needed for "classic" email accounts even if `DeleteServerAfter` is set to "immediately" to detect that a message was sent if SMTP server is slow to respond and connection is lost before receiving the status line which isn't a problem for chatmail servers.
1 parent ed9c01f commit 2166412

File tree

4 files changed

+78
-19
lines changed

4 files changed

+78
-19
lines changed

src/chat.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2943,7 +2943,8 @@ pub(crate) async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -
29432943
// because BCC-self messages are also used to detect
29442944
// that message was sent if SMTP server is slow to respond
29452945
// and connection is frequently lost
2946-
// before receiving status line.
2946+
// before receiving status line. NB: This is not a problem for chatmail servers, so `BccSelf`
2947+
// disabled by default is fine.
29472948
//
29482949
// `from` must be the last addr, see `receive_imf_inner()` why.
29492950
if context.get_config_bool(Config::BccSelf).await?

src/config.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ pub enum Config {
143143
/// Send BCC copy to self.
144144
///
145145
/// Should be enabled for multidevice setups.
146-
#[strum(props(default = "1"))]
146+
/// Default is 0 for chatmail accounts before a backup export, 1 otherwise.
147147
BccSelf,
148148

149149
/// True if encryption is preferred according to Autocrypt standard.
@@ -202,7 +202,7 @@ pub enum Config {
202202
/// Value 1 is treated as "delete at once": messages are deleted
203203
/// immediately, without moving to DeltaChat folder.
204204
///
205-
/// Default is 1 for chatmail accounts before a backup export, 0 otherwise.
205+
/// Default is 1 for chatmail accounts without `BccSelf`, 0 otherwise.
206206
DeleteServerAfter,
207207

208208
/// Timer in seconds after which the message is deleted from the
@@ -519,11 +519,19 @@ impl Context {
519519

520520
// Default values
521521
let val = match key {
522-
Config::ConfiguredInboxFolder => Some("INBOX"),
523-
Config::DeleteServerAfter => match Box::pin(self.is_chatmail()).await? {
524-
false => Some("0"),
525-
true => Some("1"),
522+
Config::BccSelf => match Box::pin(self.is_chatmail()).await? {
523+
false => Some("1"),
524+
true => Some("0"),
526525
},
526+
Config::ConfiguredInboxFolder => Some("INBOX"),
527+
Config::DeleteServerAfter => {
528+
match !Box::pin(self.get_config_bool(Config::BccSelf)).await?
529+
&& Box::pin(self.is_chatmail()).await?
530+
{
531+
true => Some("1"),
532+
false => Some("0"),
533+
}
534+
}
527535
_ => key.get_str("default"),
528536
};
529537
Ok(val.map(|s| s.to_string()))
@@ -1105,6 +1113,28 @@ mod tests {
11051113
Ok(())
11061114
}
11071115

1116+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
1117+
async fn test_delete_server_after_default() -> Result<()> {
1118+
let t = &TestContext::new_alice().await;
1119+
1120+
// Check that the settings are displayed correctly.
1121+
assert_eq!(t.get_config(Config::BccSelf).await?, Some("1".to_string()));
1122+
assert_eq!(
1123+
t.get_config(Config::DeleteServerAfter).await?,
1124+
Some("0".to_string())
1125+
);
1126+
1127+
// Leaving emails on the server even w/o `BccSelf` is a good default at least because other
1128+
// MUAs do so even if the server doesn't save sent messages to some sentbox (like Gmail
1129+
// does).
1130+
t.set_config_bool(Config::BccSelf, false).await?;
1131+
assert_eq!(
1132+
t.get_config(Config::DeleteServerAfter).await?,
1133+
Some("0".to_string())
1134+
);
1135+
Ok(())
1136+
}
1137+
11081138
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
11091139
async fn test_sync() -> Result<()> {
11101140
let alice0 = TestContext::new_alice().await;

src/imex.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ async fn import_backup_stream_inner<R: tokio::io::AsyncRead + Unpin>(
416416
.context("cannot import unpacked database");
417417
}
418418
if res.is_ok() {
419-
res = adjust_delete_server_after(context).await;
419+
res = adjust_bcc_self(context).await;
420420
}
421421
fs::remove_file(unpacked_database)
422422
.await
@@ -796,7 +796,7 @@ async fn export_database(
796796
.to_str()
797797
.with_context(|| format!("path {} is not valid unicode", dest.display()))?;
798798

799-
adjust_delete_server_after(context).await?;
799+
adjust_bcc_self(context).await?;
800800
context
801801
.sql
802802
.set_raw_config_int("backup_time", timestamp)
@@ -826,15 +826,14 @@ async fn export_database(
826826
.await
827827
}
828828

829-
/// Sets `Config::DeleteServerAfter` to "never" if needed so that new messages are present on the
830-
/// server after a backup restoration or available for all devices in multi-device case.
831-
/// NB: Calling this after a backup import isn't reliable as we can crash in between, but this is a
832-
/// problem only for old backups, new backups already have `DeleteServerAfter` set if necessary.
833-
async fn adjust_delete_server_after(context: &Context) -> Result<()> {
834-
if context.is_chatmail().await? && !context.config_exists(Config::DeleteServerAfter).await? {
835-
context
836-
.set_config(Config::DeleteServerAfter, Some("0"))
837-
.await?;
829+
/// Sets `Config::BccSelf` (and `DeleteServerAfter` to "never" in effect) if needed so that new
830+
/// messages are present on the server after a backup restoration or available for all devices in
831+
/// multi-device case. NB: Calling this after a backup import isn't reliable as we can crash in
832+
/// between, but this is a problem only for old backups, new backups already have `BccSelf` set if
833+
/// necessary.
834+
async fn adjust_bcc_self(context: &Context) -> Result<()> {
835+
if context.is_chatmail().await? && !context.config_exists(Config::BccSelf).await? {
836+
context.set_config(Config::BccSelf, Some("1")).await?;
838837
}
839838
Ok(())
840839
}
@@ -1030,12 +1029,20 @@ mod tests {
10301029

10311030
let context1 = &TestContext::new_alice().await;
10321031

1033-
// Check that the setting is displayed correctly.
1032+
// Check that the settings are displayed correctly.
1033+
assert_eq!(
1034+
context1.get_config(Config::BccSelf).await?,
1035+
Some("1".to_string())
1036+
);
10341037
assert_eq!(
10351038
context1.get_config(Config::DeleteServerAfter).await?,
10361039
Some("0".to_string())
10371040
);
10381041
context1.set_config_bool(Config::IsChatmail, true).await?;
1042+
assert_eq!(
1043+
context1.get_config(Config::BccSelf).await?,
1044+
Some("0".to_string())
1045+
);
10391046
assert_eq!(
10401047
context1.get_config(Config::DeleteServerAfter).await?,
10411048
Some("1".to_string())
@@ -1058,6 +1065,10 @@ mod tests {
10581065
assert!(context2.is_configured().await?);
10591066
assert!(context2.is_chatmail().await?);
10601067
for ctx in [context1, context2] {
1068+
assert_eq!(
1069+
ctx.get_config(Config::BccSelf).await?,
1070+
Some("1".to_string())
1071+
);
10611072
assert_eq!(
10621073
ctx.get_config(Config::DeleteServerAfter).await?,
10631074
Some("0".to_string())

src/sql/migrations.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,23 @@ CREATE INDEX msgs_status_updates_index2 ON msgs_status_updates (uid);
11211121
.await?;
11221122
}
11231123

1124+
inc_and_check(&mut migration_version, 127)?;
1125+
if dbversion < migration_version {
1126+
// Existing chatmail configurations having `delete_server_after` disabled should get
1127+
// `bcc_self` enabled, they may be multidevice configurations because before,
1128+
// `delete_server_after` was set to 0 upon a backup export for them, but together with this
1129+
// migration `bcc_self` is enabled instead (whose default is changed to 0 for chatmail). We
1130+
// don't check `is_chatmail` for simplicity.
1131+
sql.execute_migration(
1132+
"INSERT OR IGNORE INTO config (keyname, value)
1133+
SELECT 'bcc_self', '1'
1134+
FROM config WHERE keyname='delete_server_after' AND value='0'
1135+
",
1136+
migration_version,
1137+
)
1138+
.await?;
1139+
}
1140+
11241141
let new_version = sql
11251142
.get_raw_config_int(VERSION_CFG)
11261143
.await?

0 commit comments

Comments
 (0)