diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 35734eff4..9cfa675dc 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -854,7 +854,9 @@ pub(crate) async fn receive_imf_inner( if let Some(ref sync_items) = mime_parser.sync_items { if from_id == ContactId::SELF { if mime_parser.was_encrypted() { - context.execute_sync_items(sync_items).await; + context + .execute_sync_items(sync_items, mime_parser.timestamp_sent) + .await; } else { warn!(context, "Sync items are not encrypted."); } diff --git a/src/sync.rs b/src/sync.rs index e1e5a1c54..37f2d695e 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -253,13 +253,19 @@ impl Context { /// If an error is returned, the caller shall not try over because some sync items could be /// already executed. Sync items are considered independent and executed in the given order but /// regardless of whether executing of the previous items succeeded. - pub(crate) async fn execute_sync_items(&self, items: &SyncItems) { + pub(crate) async fn execute_sync_items(&self, items: &SyncItems, timestamp_sent: i64) { info!(self, "executing {} sync item(s)", items.items.len()); for item in &items.items { + // Limit the timestamp to ensure it is not in the future. + // + // `sent_timestamp` should be already corrected + // if the `Date` header is in the future. + let timestamp = std::cmp::min(item.timestamp, timestamp_sent); + match &item.data { SyncDataOrUnknown::SyncData(data) => match data { - AddQrToken(token) => self.add_qr_token(token, item.timestamp).await, - DeleteQrToken(token) => self.delete_qr_token(token, item.timestamp).await, + AddQrToken(token) => self.add_qr_token(token, timestamp).await, + DeleteQrToken(token) => self.delete_qr_token(token, timestamp).await, AlterChat { id, action } => self.sync_alter_chat(id, action).await, SyncData::Config { key, val } => self.sync_config(key, val).await, SyncData::SaveMessage { src, dest } => self.save_message(src, dest).await, @@ -557,6 +563,7 @@ mod tests { assert!(!token::exists(&t, Namespace::Auth, "yip-auth").await?); + let timestamp_sent = time(); let sync_items = t .parse_sync_items( r#"{"items":[ @@ -571,7 +578,7 @@ mod tests { .to_string(), ) ?; - t.execute_sync_items(&sync_items).await; + t.execute_sync_items(&sync_items, timestamp_sent).await; assert!( Contact::lookup_id_by_addr(&t, "bob@example.net", Origin::Unknown)