Skip to content

Commit 73d167b

Browse files
committed
feat: Don't mark messages as seen on IMAP if bcc_self=0 or bot=1
bcc_self=0 means that the user disabled it or it's a chatmail setup with the only device and w/o backups. If a backup is made someday, old messages not marked as IMAP-seen aren't a problem and new ones are marked as IMAP-seen. For bots, particularly multi-device ones (which are a rare case), probably no sane logic can be built on the "seen" message status. Moreover, if the user has additionally a bot that reads incoming messages, it doesn't mean that the user doesn't want to read them too. Also don't mark a message as IMAP-seen just if it already exists on the device as this doesn't mean that it exists on another device. Also don't mark MDNs and DSNs as IMAP-seen. Marking MDNs as seen is useless, they shouldn't be displayed by any MUA. Auto-marking DSNs as seen should be avoided because the user may want to see them in another MUA.
1 parent 7ee6f2c commit 73d167b

File tree

4 files changed

+29
-21
lines changed

4 files changed

+29
-21
lines changed

deltachat-rpc-client/tests/test_multidevice.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ def test_one_account_send_bcc_setting(acfactory, log, direct_imap):
4444

4545
# now make sure we are sending message to ourselves too
4646
assert self_addr in ev.msg
47-
assert self_addr in ev.msg
4847

4948
# BCC-self messages are marked as seen by the sender device.
5049
while True:

python/tests/test_1_online.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def test_html_message(acfactory, lp):
162162

163163
def test_webxdc_message(acfactory, data, lp):
164164
ac1, ac2 = acfactory.get_online_accounts(2)
165+
ac2.set_config("bcc_self", "1")
165166
chat = acfactory.get_accepted_chat(ac1, ac2)
166167

167168
lp.sec("ac1: prepare and send text message to ac2")
@@ -512,6 +513,8 @@ def test_send_and_receive_message_markseen(acfactory, lp):
512513
# make DC's life harder wrt to encodings
513514
ac1.set_config("displayname", "ä name")
514515

516+
ac2.set_config("bcc_self", "1")
517+
515518
# clear any fresh device messages
516519
ac1.get_device_chat().mark_noticed()
517520
ac2.get_device_chat().mark_noticed()
@@ -569,9 +572,6 @@ def test_send_and_receive_message_markseen(acfactory, lp):
569572
assert ev.data2 > dc.const.DC_MSG_ID_LAST_SPECIAL
570573
lp.step("2")
571574

572-
# Check that ac1 marks the read receipt as read.
573-
ac1._evtracker.get_info_contains("Marked messages .* in folder INBOX as seen.")
574-
575575
assert msg1.is_out_mdn_received()
576576
assert msg3.is_out_mdn_received()
577577

@@ -587,7 +587,7 @@ def test_send_and_receive_message_markseen(acfactory, lp):
587587
def test_moved_markseen(acfactory):
588588
"""Test that message already moved to DeltaChat folder is marked as seen."""
589589
ac1 = acfactory.new_online_configuring_account()
590-
ac2 = acfactory.new_online_configuring_account(mvbox_move=True)
590+
ac2 = acfactory.new_online_configuring_account(mvbox_move=True, bcc_self=True)
591591
acfactory.bring_accounts_online()
592592

593593
ac2.stop_io()
@@ -715,15 +715,17 @@ def test_mdn_asymmetric(acfactory, lp):
715715
chat = ac1.create_chat(ac2)
716716
ac2.create_chat(ac1)
717717

718-
# make sure mdns are enabled (usually enabled by default already)
719-
ac1.set_config("mdns_enabled", "1")
720-
ac2.set_config("mdns_enabled", "1")
718+
ac1.set_config("bcc_self", "1")
719+
ac2.set_config("bcc_self", "1")
721720

722721
lp.sec("sending text message from ac1 to ac2")
723722
msg_out = chat.send_text("message1")
724723

725724
assert len(chat.get_messages()) == 1 + E2EE_INFO_MSGS
726725

726+
# Wait for the message to be marked as seen on IMAP.
727+
ac1._evtracker.get_info_contains("Marked messages [0-9]+ in folder DeltaChat as seen.")
728+
727729
lp.sec("disable ac1 MDNs")
728730
ac1.set_config("mdns_enabled", "0")
729731

@@ -735,16 +737,17 @@ def test_mdn_asymmetric(acfactory, lp):
735737
lp.sec("ac2: mark incoming message as seen")
736738
ac2.mark_seen_messages([msg])
737739

740+
# Wait for the message to be marked as seen on IMAP.
741+
ac2._evtracker.get_info_contains("Marked messages [0-9]+ in folder INBOX as seen.")
742+
738743
lp.sec("ac1: waiting for incoming activity")
739744
# MDN should be moved even though MDNs are already disabled
740745
ac1._evtracker.get_matching("DC_EVENT_IMAP_MESSAGE_MOVED")
741746

742747
assert len(chat.get_messages()) == 1 + E2EE_INFO_MSGS
743748

744-
# Wait for the message to be marked as seen on IMAP.
745-
ac1._evtracker.get_info_contains("Marked messages [0-9]+ in folder DeltaChat as seen.")
746-
747749
# MDN is received even though MDNs are already disabled
750+
ac1._evtracker.get_matching("DC_EVENT_MSG_READ")
748751
assert msg_out.is_out_mdn_received()
749752

750753
ac1.direct_imap.select_config_folder("mvbox")

src/imap.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,11 +2248,16 @@ pub(crate) async fn prefetch_should_download(
22482248
message_id: &str,
22492249
mut flags: impl Iterator<Item = Flag<'_>>,
22502250
) -> Result<bool> {
2251-
if message::rfc724_mid_exists(context, message_id)
2252-
.await?
2253-
.is_some()
2251+
if let Some((.., seen)) = message::rfc724_mid_exists_ex(
2252+
context,
2253+
message_id,
2254+
"state>=16", // `InSeen`
2255+
)
2256+
.await?
22542257
{
2255-
markseen_on_imap_table(context, message_id).await?;
2258+
if seen {
2259+
markseen_on_imap_table(context, message_id).await?;
2260+
}
22562261
return Ok(false);
22572262
}
22582263

@@ -2397,6 +2402,11 @@ async fn mark_seen_by_uid(
23972402
/// Schedule marking the message as Seen on IMAP by adding all known IMAP messages corresponding to
23982403
/// the given Message-ID to `imap_markseen` table.
23992404
pub(crate) async fn markseen_on_imap_table(context: &Context, message_id: &str) -> Result<()> {
2405+
if !context.get_config_bool(Config::BccSelf).await?
2406+
|| context.get_config_bool(Config::Bot).await?
2407+
{
2408+
return Ok(());
2409+
}
24002410
context
24012411
.sql
24022412
.execute(

src/receive_imf.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -993,11 +993,6 @@ pub(crate) async fn receive_imf_inner(
993993
)
994994
.await?;
995995
}
996-
if target.is_none() && !mime_parser.mdn_reports.is_empty() && mime_parser.has_chat_version()
997-
{
998-
// This is a Delta Chat MDN. Mark as read.
999-
markseen_on_imap_table(context, rfc724_mid_orig).await?;
1000-
}
1001996
}
1002997

1003998
if mime_parser.is_call() {
@@ -1145,8 +1140,9 @@ async fn decide_chat_assignment(
11451140
info!(context, "Message is an MDN (TRASH).");
11461141
true
11471142
} else if mime_parser.delivery_report.is_some() {
1143+
// Auto-marking DSNs as IMAP-seen should be avoided because the user may want to see them in
1144+
// another MUA.
11481145
info!(context, "Message is a DSN (TRASH).");
1149-
markseen_on_imap_table(context, rfc724_mid).await.ok();
11501146
true
11511147
} else if mime_parser.get_header(HeaderDef::ChatEdit).is_some()
11521148
|| mime_parser.get_header(HeaderDef::ChatDelete).is_some()

0 commit comments

Comments
 (0)