diff --git a/melib/src/jmap/connection.rs b/melib/src/jmap/connection.rs index 5ba81cce..cce66eb0 100644 --- a/melib/src/jmap/connection.rs +++ b/melib/src/jmap/connection.rs @@ -184,8 +184,6 @@ impl JmapConnection { *self.store.online_status.lock().await = (Instant::now(), Err(err.clone())); return Err(err); } - *self.store.core_capabilities.lock().unwrap() = - session.capabilities[JMAP_CORE_CAPABILITY].clone(); if !session.capabilities.contains_key(JMAP_MAIL_CAPABILITY) { let err = Error::new(format!( "Server {} does not support JMAP Mail capability ({mail_capability}). Returned \ @@ -202,6 +200,7 @@ impl JmapConnection { *self.store.online_status.lock().await = (Instant::now(), Err(err.clone())); return Err(err); } + *self.store.core_capabilities.lock().unwrap() = session.capabilities.clone(); *self.store.online_status.lock().await = (Instant::now(), Ok(())); *self.session.lock().unwrap() = session; diff --git a/melib/src/jmap/mod.rs b/melib/src/jmap/mod.rs index 9fac1407..8e477ae6 100644 --- a/melib/src/jmap/mod.rs +++ b/melib/src/jmap/mod.rs @@ -68,6 +68,7 @@ macro_rules! _impl { pub const JMAP_CORE_CAPABILITY: &str = "urn:ietf:params:jmap:core"; pub const JMAP_MAIL_CAPABILITY: &str = "urn:ietf:params:jmap:mail"; +pub const JMAP_SUBMISSION_CAPABILITY: &str = "urn:ietf:params:jmap:submission"; pub mod operations; use operations::*; @@ -196,7 +197,7 @@ pub struct Store { pub mailbox_state: Arc>>, pub online_status: Arc)>>, pub is_subscribed: Arc, - pub core_capabilities: Arc>, + pub core_capabilities: Arc>>, pub event_consumer: BackendEventConsumer, } @@ -292,9 +293,18 @@ impl MailBackend for JmapType { supports_search: true, extensions: None, supports_tags: true, - supports_submission: false, + supports_submission: true, }; - CAPABILITIES + let supports_submission: bool = self + .store + .core_capabilities + .lock() + .map(|c| c.contains_key(JMAP_SUBMISSION_CAPABILITY)) + .unwrap_or(false); + MailBackendCapabilities { + supports_submission: CAPABILITIES.supports_submission || supports_submission, + ..CAPABILITIES + } } fn is_online(&self) -> ResultFuture<()> { @@ -322,7 +332,7 @@ impl MailBackend for JmapType { Ok(Box::pin(async_stream::try_stream! { let mut conn = connection.lock().await; conn.connect().await?; - let batch_size: u64 = conn.store.core_capabilities.lock().unwrap().max_objects_in_get; + let batch_size: u64 = conn.store.core_capabilities.lock().unwrap()[JMAP_CORE_CAPABILITY].max_objects_in_get; let mut fetch_state = protocol::EmailFetchState::Start { batch_size }; loop { let res = fetch_state.fetch( @@ -384,7 +394,7 @@ impl MailBackend for JmapType { let mut conn = connection.lock().await; conn.connect().await?; if store.mailboxes.read().unwrap().is_empty() { - let new_mailboxes = debug!(protocol::get_mailboxes(&mut conn).await)?; + let new_mailboxes = debug!(protocol::get_mailboxes(&mut conn, None).await)?; *store.mailboxes.write().unwrap() = new_mailboxes; } @@ -488,7 +498,7 @@ impl MailBackend for JmapType { } })?; - if let Some(err) = m.not_created.get(&creation_id) { + if let Some(err) = m.not_created.and_then(|m| m.get(&creation_id).cloned()) { return Err(Error::new(format!("Could not save message: {:?}", err))); } Ok(()) @@ -894,7 +904,7 @@ impl JmapType { event_consumer, is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)), collection: Collection::default(), - core_capabilities: Arc::new(Mutex::new(rfc8620::CapabilitiesObject::default())), + core_capabilities: Arc::new(Mutex::new(IndexMap::default())), byte_cache: Default::default(), id_store: Default::default(), reverse_id_store: Default::default(), diff --git a/melib/src/jmap/protocol.rs b/melib/src/jmap/protocol.rs index 841d6559..2df3e755 100644 --- a/melib/src/jmap/protocol.rs +++ b/melib/src/jmap/protocol.rs @@ -22,7 +22,7 @@ use std::convert::{TryFrom, TryInto}; use serde::Serialize; -use serde_json::{json, Value}; +use serde_json::Value; use super::{mailbox::JmapMailbox, *}; @@ -78,17 +78,15 @@ impl Request { } } -pub async fn get_mailboxes(conn: &mut JmapConnection) -> Result> { - let seq = get_request_no!(conn.request_no); - let res_text = conn - .send_request(serde_json::to_string(&json!({ - "using": [JMAP_CORE_CAPABILITY, JMAP_MAIL_CAPABILITY], - "methodCalls": [["Mailbox/get", { - "accountId": conn.mail_account_id() - }, - format!("#m{}",seq).as_str()]], - }))?) - .await?; +pub async fn get_mailboxes( + conn: &mut JmapConnection, + request: Option, +) -> Result> { + let mut req = request.unwrap_or_else(|| Request::new(conn.request_no.clone())); + let mailbox_get: MailboxGet = + MailboxGet::new(Get::::new().account_id(conn.mail_account_id())); + req.add_call(&mailbox_get); + let res_text = conn.send_request(serde_json::to_string(&req)?).await?; let mut v: MethodResponse = deserialize_from_str(&res_text)?; *conn.store.online_status.lock().await = (std::time::Instant::now(), Ok(()));