From 1e561612096bd77759a0a0afdd1634607fae6dd2 Mon Sep 17 00:00:00 2001 From: mdecimus Date: Sun, 27 Apr 2025 20:03:57 +0200 Subject: [PATCH] Use latest UID list on COPY/MOVE (#1201) --- crates/imap/src/core/message.rs | 18 +++++++++++------- crates/imap/src/op/copy_move.rs | 14 +++++++++----- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/crates/imap/src/core/message.rs b/crates/imap/src/core/message.rs index dfefa896..6f37a2a2 100644 --- a/crates/imap/src/core/message.rs +++ b/crates/imap/src/core/message.rs @@ -275,17 +275,21 @@ impl SelectedMailbox { if !sequence.is_saved_search() { let mut ids = AHashMap::new(); let state = self.state.lock(); - if state.id_to_imap.is_empty() { - return Ok(ids); - } if is_uid { - for (id, imap_id) in &state.id_to_imap { - if sequence.contains(imap_id.uid, state.uid_max) { - ids.insert(*id, *imap_id); + let id_to_imap = state + .next_state + .as_ref() + .map(|s| &s.next_state.id_to_imap) + .unwrap_or(&state.id_to_imap); + if !state.id_to_imap.is_empty() { + for (id, imap_id) in id_to_imap { + if sequence.contains(imap_id.uid, state.uid_max) { + ids.insert(*id, *imap_id); + } } } - } else { + } else if !state.id_to_imap.is_empty() { for (id, imap_id) in &state.id_to_imap { if sequence.contains(imap_id.seqnum, state.total_messages as u32) { ids.insert(*id, *imap_id); diff --git a/crates/imap/src/op/copy_move.rs b/crates/imap/src/op/copy_move.rs index c531513e..b3877187 100644 --- a/crates/imap/src/op/copy_move.rs +++ b/crates/imap/src/op/copy_move.rs @@ -9,18 +9,18 @@ use std::{sync::Arc, time::Instant}; use directory::Permission; use email::{ ingest::EmailIngest, - mailbox::{UidMailbox, JUNK_ID}, + mailbox::{JUNK_ID, UidMailbox}, }; use imap_proto::{ - protocol::copy_move::Arguments, receiver::Request, Command, ResponseCode, ResponseType, - StatusResponse, + Command, ResponseCode, ResponseType, StatusResponse, protocol::copy_move::Arguments, + receiver::Request, }; use crate::{ core::{SelectedMailbox, Session, SessionData}, spawn_op, }; -use common::{listener::SessionStream, MailboxId}; +use common::{MailboxId, listener::SessionStream}; use jmap::email::{bayes::EmailBayesTrain, copy::EmailCopy, set::TagManager}; use jmap_proto::{ error::set::SetErrorType, @@ -31,7 +31,7 @@ use jmap_proto::{ }; use store::{ roaring::RoaringBitmap, - write::{assert::HashedValue, log::ChangeLogBuilder, BatchBuilder, ValueClass, F_VALUE}, + write::{BatchBuilder, F_VALUE, ValueClass, assert::HashedValue, log::ChangeLogBuilder}, }; use super::ImapContext; @@ -110,6 +110,10 @@ impl SessionData { is_qresync: bool, op_start: Instant, ) -> trc::Result<()> { + self.synchronize_messages(&src_mailbox) + .await + .imap_ctx(&arguments.tag, trc::location!())?; + // Convert IMAP ids to JMAP ids. let ids = src_mailbox .sequence_to_ids(&arguments.sequence_set, is_uid)