summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2022-10-04 15:53:01 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2022-10-04 15:58:36 +0300
commit0c08cb737ceaa5c738712905c7d57f956d449ed0 (patch)
tree6a7d9a0b6ae2e39a44f5b2591e119f3d7bd4104b
parent117d7fbe046fe23c400a925ccba7317d8a1d3f08 (diff)
downloadmeli-0c08cb737ceaa5c738712905c7d57f956d449ed0.zip
melib/jmap: mark mailboxes as subscribed on personal accounts
The spec https://jmap.io/spec-mail.html#mailboxes says a mailbox property `isSubscribed` should be considered true if the account is marked as `isPersonal`. Closes #157 JMAP incompatible with Stalwart server #157 https://git.meli.delivery/meli/meli/issues/157
-rw-r--r--melib/src/backends/jmap/connection.rs31
-rw-r--r--melib/src/backends/jmap/mailbox.rs2
-rw-r--r--melib/src/backends/jmap/protocol.rs12
3 files changed, 37 insertions, 8 deletions
diff --git a/melib/src/backends/jmap/connection.rs b/melib/src/backends/jmap/connection.rs
index aaaf3a5a..1cff3a95 100644
--- a/melib/src/backends/jmap/connection.rs
+++ b/melib/src/backends/jmap/connection.rs
@@ -21,6 +21,7 @@
use super::*;
use isahc::config::Configurable;
+use std::sync::MutexGuard;
#[derive(Debug)]
pub struct JmapConnection {
@@ -56,19 +57,31 @@ impl JmapConnection {
if self.store.online_status.lock().await.1.is_ok() {
return Ok(());
}
- let mut jmap_session_resource_url =
- if self.server_conf.server_hostname.starts_with("https://") {
- self.server_conf.server_hostname.to_string()
- } else {
- format!("https://{}", &self.server_conf.server_hostname)
- };
+ let mut jmap_session_resource_url = self.server_conf.server_hostname.to_string();
if self.server_conf.server_port != 443 {
jmap_session_resource_url.push(':');
jmap_session_resource_url.push_str(&self.server_conf.server_port.to_string());
}
jmap_session_resource_url.push_str("/.well-known/jmap");
- let mut req = self.client.get_async(&jmap_session_resource_url).await?;
+ let mut req = self.client.get_async(&jmap_session_resource_url).await.map_err(|err| {
+ let err = MeliError::new(format!("Could not connect to JMAP server endpoint for {}. Is your server hostname setting correct? (i.e. \"jmap.mailserver.org\") (Note: only session resource discovery via /.well-known/jmap is supported. DNS SRV records are not suppported.)\nError connecting to server: {}", &self.server_conf.server_hostname, &err)).set_source(Some(Arc::new(err)));
+ //*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
+ err
+ })?;
+
+ if !req.status().is_success() {
+ let kind: crate::error::NetworkErrorKind = req.status().into();
+ let res_text = req.text().await.unwrap_or_default();
+ let err = MeliError::new(format!(
+ "Could not connect to JMAP server endpoint for {}. Reply from server: {}",
+ &self.server_conf.server_hostname, res_text
+ ))
+ .set_kind(kind.into());
+ *self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
+ return Err(err);
+ }
+
let res_text = req.text().await?;
let session: JmapSession = match serde_json::from_str(&res_text) {
@@ -105,6 +118,10 @@ impl JmapConnection {
self.session.lock().unwrap().primary_accounts["urn:ietf:params:jmap:mail"].clone()
}
+ pub fn session_guard(&'_ self) -> MutexGuard<'_, JmapSession> {
+ self.session.lock().unwrap()
+ }
+
pub fn add_refresh_event(&self, event: RefreshEvent) {
(self.store.event_consumer)(self.store.account_hash, BackendEvent::Refresh(event));
}
diff --git a/melib/src/backends/jmap/mailbox.rs b/melib/src/backends/jmap/mailbox.rs
index f20b2ed7..abeae0bf 100644
--- a/melib/src/backends/jmap/mailbox.rs
+++ b/melib/src/backends/jmap/mailbox.rs
@@ -95,9 +95,11 @@ impl BackendMailbox for JmapMailbox {
None => SpecialUsageMailbox::Normal,
}
}
+
fn is_subscribed(&self) -> bool {
self.is_subscribed
}
+
fn set_is_subscribed(&mut self, new_val: bool) -> Result<()> {
self.is_subscribed = new_val;
// FIXME: jmap subscribe
diff --git a/melib/src/backends/jmap/protocol.rs b/melib/src/backends/jmap/protocol.rs
index 90033c8f..a8bd2ff4 100644
--- a/melib/src/backends/jmap/protocol.rs
+++ b/melib/src/backends/jmap/protocol.rs
@@ -108,6 +108,16 @@ pub async fn get_mailboxes(conn: &JmapConnection) -> Result<HashMap<MailboxHash,
let GetResponse::<MailboxObject> {
list, account_id, ..
} = m;
+ // Is account set as `personal`? (`isPersonal` property). Then, even if `isSubscribed` is false
+ // on a mailbox, it should be regarded as subscribed.
+ let is_personal: bool = {
+ let session = conn.session_guard();
+ session
+ .accounts
+ .get(&account_id)
+ .map(|acc| acc.is_personal)
+ .unwrap_or(false)
+ };
*conn.store.account_id.lock().unwrap() = account_id;
let mut ret: HashMap<MailboxHash, JmapMailbox> = list
.into_iter()
@@ -141,7 +151,7 @@ pub async fn get_mailboxes(conn: &JmapConnection) -> Result<HashMap<MailboxHash,
path: name,
children: Vec::new(),
id,
- is_subscribed,
+ is_subscribed: is_subscribed || is_personal,
my_rights,
parent_id,
parent_hash,