@@ -333,9 +333,29 @@ pub(crate) async fn receive_imf_inner(
333
333
}
334
334
} ;
335
335
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
+ } ;
336
344
let to_ids = add_or_lookup_contacts_by_address_list (
337
345
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 ,
339
359
if !mime_parser. incoming {
340
360
Origin :: OutgoingTo
341
361
} else if incoming_origin. is_known ( ) {
@@ -418,6 +438,7 @@ pub(crate) async fn receive_imf_inner(
418
438
& mut mime_parser,
419
439
imf_raw,
420
440
& to_ids,
441
+ & past_ids,
421
442
rfc724_mid_orig,
422
443
from_id,
423
444
seen,
@@ -689,6 +710,7 @@ async fn add_parts(
689
710
mime_parser : & mut MimeMessage ,
690
711
imf_raw : & [ u8 ] ,
691
712
to_ids : & [ ContactId ] ,
713
+ past_ids : & [ ContactId ] ,
692
714
rfc724_mid : & str ,
693
715
from_id : ContactId ,
694
716
seen : bool ,
@@ -906,6 +928,7 @@ async fn add_parts(
906
928
group_chat_id,
907
929
from_id,
908
930
to_ids,
931
+ past_ids,
909
932
is_partial_download. is_some ( ) ,
910
933
& verified_encryption,
911
934
)
@@ -1175,6 +1198,7 @@ async fn add_parts(
1175
1198
chat_id,
1176
1199
from_id,
1177
1200
to_ids,
1201
+ past_ids,
1178
1202
is_partial_download. is_some ( ) ,
1179
1203
& verified_encryption,
1180
1204
)
@@ -2081,6 +2105,8 @@ async fn create_group(
2081
2105
/// original system message. If the better message is empty, the original system message should be
2082
2106
/// just omitted.
2083
2107
///
2108
+ /// * `to_ids` - contents of the `To` header for chat messages
2109
+ /// or combined `To` and `Cc` for non-chat messages
2084
2110
/// * `is_partial_download` - whether the message is not fully downloaded.
2085
2111
#[ allow( clippy:: too_many_arguments) ]
2086
2112
async fn apply_group_changes (
@@ -2089,6 +2115,7 @@ async fn apply_group_changes(
2089
2115
chat_id : ChatId ,
2090
2116
from_id : ContactId ,
2091
2117
to_ids : & [ ContactId ] ,
2118
+ past_ids : & [ ContactId ] ,
2092
2119
is_partial_download : bool ,
2093
2120
verified_encryption : & VerifiedEncryption ,
2094
2121
) -> Result < ( Vec < String > , Option < String > ) > {
@@ -2106,6 +2133,59 @@ async fn apply_group_changes(
2106
2133
let mut better_msg = None ;
2107
2134
let mut group_changes_msgs = Vec :: new ( ) ;
2108
2135
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
+
2109
2189
// True if a Delta Chat client has explicitly added our current primary address.
2110
2190
let self_added =
2111
2191
if let Some ( added_addr) = mime_parser. get_header ( HeaderDef :: ChatGroupMemberAdded ) {
0 commit comments