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
jmap-status-and-connect-retry-wip
Manos Pitsidianakis 2022-10-04 15:53:01 +03:00
parent 117d7fbe04
commit 0c08cb737c
3 changed files with 37 additions and 8 deletions

View File

@ -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));
}

View File

@ -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

View File

@ -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,