Skip to content

Commit 3258c92

Browse files
committed
New group consistency algorithm on the receiver side
1 parent 4412449 commit 3258c92

File tree

1 file changed

+81
-1
lines changed

1 file changed

+81
-1
lines changed

src/receive_imf.rs

+81-1
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,29 @@ pub(crate) async fn receive_imf_inner(
333333
}
334334
};
335335

336+
let recipients = if mime_parser.get_header(HeaderDef::ChatVersion).is_some() {
337+
// Chat messages should not have `Cc` field.
338+
// Use only the `To` field.
339+
&mime_parser.to
340+
} else {
341+
// Use `To` and `Cc` fields as recipients.
342+
&mime_parser.recipients
343+
};
336344
let to_ids = add_or_lookup_contacts_by_address_list(
337345
context,
338-
&mime_parser.recipients,
346+
recipients,
347+
if !mime_parser.incoming {
348+
Origin::OutgoingTo
349+
} else if incoming_origin.is_known() {
350+
Origin::IncomingTo
351+
} else {
352+
Origin::IncomingUnknownTo
353+
},
354+
)
355+
.await?;
356+
let past_ids = add_or_lookup_contacts_by_address_list(
357+
context,
358+
&mime_parser.past_members,
339359
if !mime_parser.incoming {
340360
Origin::OutgoingTo
341361
} else if incoming_origin.is_known() {
@@ -418,6 +438,7 @@ pub(crate) async fn receive_imf_inner(
418438
&mut mime_parser,
419439
imf_raw,
420440
&to_ids,
441+
&past_ids,
421442
rfc724_mid_orig,
422443
from_id,
423444
seen,
@@ -689,6 +710,7 @@ async fn add_parts(
689710
mime_parser: &mut MimeMessage,
690711
imf_raw: &[u8],
691712
to_ids: &[ContactId],
713+
past_ids: &[ContactId],
692714
rfc724_mid: &str,
693715
from_id: ContactId,
694716
seen: bool,
@@ -906,6 +928,7 @@ async fn add_parts(
906928
group_chat_id,
907929
from_id,
908930
to_ids,
931+
past_ids,
909932
is_partial_download.is_some(),
910933
&verified_encryption,
911934
)
@@ -1175,6 +1198,7 @@ async fn add_parts(
11751198
chat_id,
11761199
from_id,
11771200
to_ids,
1201+
past_ids,
11781202
is_partial_download.is_some(),
11791203
&verified_encryption,
11801204
)
@@ -2081,6 +2105,8 @@ async fn create_group(
20812105
/// original system message. If the better message is empty, the original system message should be
20822106
/// just omitted.
20832107
///
2108+
/// * `to_ids` - contents of the `To` header for chat messages
2109+
/// or combined `To` and `Cc` for non-chat messages
20842110
/// * `is_partial_download` - whether the message is not fully downloaded.
20852111
#[allow(clippy::too_many_arguments)]
20862112
async fn apply_group_changes(
@@ -2089,6 +2115,7 @@ async fn apply_group_changes(
20892115
chat_id: ChatId,
20902116
from_id: ContactId,
20912117
to_ids: &[ContactId],
2118+
past_ids: &[ContactId],
20922119
is_partial_download: bool,
20932120
verified_encryption: &VerifiedEncryption,
20942121
) -> Result<(Vec<String>, Option<String>)> {
@@ -2106,6 +2133,59 @@ async fn apply_group_changes(
21062133
let mut better_msg = None;
21072134
let mut group_changes_msgs = Vec::new();
21082135

2136+
if let Some(chat_group_member_timestamps) =
2137+
mime_parser.get_header(HeaderDef::ChatGroupMemberTimestamps)
2138+
{
2139+
let chat_group_member_timestamps: Vec<i64> = chat_group_member_timestamps
2140+
.split_ascii_whitespace()
2141+
.filter_map(|ts| ts.parse::<i64>().ok())
2142+
.collect();
2143+
2144+
let expected_timestamps_count = to_ids.len() + past_ids.len();
2145+
if chat_group_member_timestamps.len() == expected_timestamps_count {
2146+
context
2147+
.sql
2148+
.transaction(|transaction| {
2149+
for (contact_id, ts) in std::iter::zip(
2150+
to_ids.iter(),
2151+
chat_group_member_timestamps.iter().take(to_ids.len()),
2152+
) {
2153+
transaction.execute(
2154+
"INSERT INTO chats_contacts (chat_id, contact_id, add_timestamp)
2155+
VALUES (?1, ?2, ?3)
2156+
ON CONFLICT (chat_id, contact_id)
2157+
DO UPDATE SET add_timestamp=MAX(add_timestamp, ?3)",
2158+
(chat_id, contact_id, ts),
2159+
)?;
2160+
}
2161+
2162+
for (contact_id, ts) in std::iter::zip(
2163+
past_ids.iter(),
2164+
chat_group_member_timestamps.iter().skip(to_ids.len()),
2165+
) {
2166+
transaction.execute(
2167+
"UPDATE chats_contacts
2168+
SET remove_timestamp=MAX(remove_timestamp, ?)
2169+
WHERE chat_id=? AND contact_id=?",
2170+
(ts, chat_id, contact_id),
2171+
)?;
2172+
}
2173+
2174+
Ok(())
2175+
})
2176+
.await?;
2177+
} else {
2178+
warn!(
2179+
context,
2180+
"Chat-Group-Member-Timestamps has wrong number of timestamps, got {}, expected {}.",
2181+
chat_group_member_timestamps.len(),
2182+
expected_timestamps_count
2183+
);
2184+
}
2185+
2186+
return Ok((group_changes_msgs, better_msg));
2187+
}
2188+
21092189
// True if a Delta Chat client has explicitly added our current primary address.
21102190
let self_added =
21112191
if let Some(added_addr) = mime_parser.get_header(HeaderDef::ChatGroupMemberAdded) {

0 commit comments

Comments
 (0)