mirror of
https://github.com/pimalaya/himalaya.git
synced 2026-06-15 11:27:53 +08:00
build: bump io-email
This commit is contained in:
Generated
+1
-1
@@ -1061,7 +1061,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "io-email"
|
||||
version = "0.0.1"
|
||||
source = "git+https://github.com/pimalaya/io-email#8bcdf92f8872f8436d8482814965e5750d87c4cc"
|
||||
source = "git+https://github.com/pimalaya/io-email#15aeedd215b5edf463e8b3cae8bbd4ae223e5cff"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chumsky",
|
||||
|
||||
+63
-33
@@ -24,16 +24,17 @@
|
||||
//! [`Deref`]/[`DerefMut`] onto the inner client so callers can call
|
||||
//! its methods directly.
|
||||
//!
|
||||
//! Construction is backend-asymmetric (IMAP needs TLS + SASL, JMAP
|
||||
//! needs an HTTP credential, Maildir just needs a root path). The
|
||||
//! single [`EmailClient::new`] entry-point loads the configuration,
|
||||
//! picks the merged account, then walks the configured backends in
|
||||
//! `jmap → imap → maildir` order and opens the first one allowed by
|
||||
//! the `BackendFlag`.
|
||||
//! Construction picks the first storage backend (`jmap → imap →
|
||||
//! maildir`) allowed by the `BackendFlag` that is configured on the
|
||||
//! account. When the account also has SMTP configured, an SMTP slot
|
||||
//! is registered on the same client so `send_message` works for
|
||||
//! IMAP/Maildir accounts; JMAP accounts already send via JMAP
|
||||
//! submission. SMTP connection failures are logged and skipped — the
|
||||
//! client still opens for reading.
|
||||
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{Result, bail};
|
||||
|
||||
use crate::{
|
||||
account::context::Account,
|
||||
@@ -47,25 +48,24 @@ pub struct EmailClient {
|
||||
}
|
||||
|
||||
impl EmailClient {
|
||||
/// Loads the configuration, picks the active account, builds the
|
||||
/// merged [`Account`], then opens the first backend allowed by
|
||||
/// `backend` that is configured on the account. Selection order
|
||||
/// is `jmap → imap → maildir`. Bails when no backend matches.
|
||||
pub fn new(
|
||||
config: Config,
|
||||
mut account_config: AccountConfig,
|
||||
backend: Backend,
|
||||
) -> Result<Self> {
|
||||
use io_email::client::EmailClientStd;
|
||||
|
||||
let mut inner = EmailClientStd::new();
|
||||
let mut configured = false;
|
||||
|
||||
#[cfg(feature = "jmap")]
|
||||
if backend.allows_jmap() {
|
||||
if !configured && backend.allows_jmap() {
|
||||
if let Some(jmap_config) = account_config.jmap.take() {
|
||||
use io_email::client::EmailClientStd;
|
||||
use io_jmap::client::JmapClientStd;
|
||||
use pimalaya_stream::tls::Tls;
|
||||
|
||||
use crate::jmap::client::{jmap_http_auth, parse_server_url};
|
||||
|
||||
let account = Account::from(config).merge(Account::from(account_config));
|
||||
let mut tls: Tls = jmap_config.tls.clone().into();
|
||||
tls.rustls.alpn = vec!["http/1.1".into()];
|
||||
let http_auth = jmap_http_auth(jmap_config.auth.clone())?;
|
||||
@@ -73,21 +73,17 @@ impl EmailClient {
|
||||
let mut client = JmapClientStd::connect(&url, &tls, http_auth)?;
|
||||
client.session_get(&url)?;
|
||||
|
||||
return Ok(Self {
|
||||
inner: EmailClientStd::Jmap(client),
|
||||
account,
|
||||
});
|
||||
inner = inner.with_jmap(client);
|
||||
configured = true;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "imap")]
|
||||
if backend.allows_imap() {
|
||||
if !configured && backend.allows_imap() {
|
||||
if let Some(imap_config) = account_config.imap.take() {
|
||||
use io_email::client::EmailClientStd;
|
||||
use io_imap::client::ImapClientStd;
|
||||
use pimalaya_stream::{sasl::Sasl, std::stream::StreamStd, tls::Tls};
|
||||
|
||||
let account = Account::from(config).merge(Account::from(account_config));
|
||||
let mut tls: Tls = imap_config.tls.into();
|
||||
tls.rustls.alpn = vec!["imap".into()];
|
||||
let sasl: Option<Sasl> = imap_config.sasl.map(Sasl::try_from).transpose()?;
|
||||
@@ -95,30 +91,64 @@ impl EmailClient {
|
||||
let client =
|
||||
ImapClientStd::<StreamStd>::connect(&server, &tls, imap_config.starttls, sasl)?;
|
||||
|
||||
return Ok(Self {
|
||||
inner: EmailClientStd::Imap(client),
|
||||
account,
|
||||
});
|
||||
inner = inner.with_imap(client);
|
||||
configured = true;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "maildir")]
|
||||
if backend.allows_maildir() {
|
||||
if !configured && backend.allows_maildir() {
|
||||
if let Some(maildir_config) = account_config.maildir.take() {
|
||||
use io_email::client::EmailClientStd;
|
||||
use io_maildir::client::MaildirClient;
|
||||
|
||||
let account = Account::from(config).merge(Account::from(account_config));
|
||||
let client = MaildirClient::new(maildir_config.root);
|
||||
|
||||
return Ok(Self {
|
||||
inner: EmailClientStd::Maildir(client),
|
||||
account,
|
||||
});
|
||||
inner = inner.with_maildir(client);
|
||||
configured = true;
|
||||
}
|
||||
}
|
||||
|
||||
bail!("no backend matching `{backend}` is configured for this account")
|
||||
if !configured {
|
||||
bail!("no backend matching `{backend}` is configured for this account");
|
||||
}
|
||||
|
||||
// Register SMTP alongside the storage backend so shared
|
||||
// `send_message` works for IMAP/Maildir accounts. JMAP already
|
||||
// sends via submission, but if both are present, SMTP wins
|
||||
// because storage is registered first.
|
||||
#[cfg(feature = "smtp")]
|
||||
if let Some(smtp_config) = account_config.smtp.take() {
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use io_smtp::{client::SmtpClientStd, rfc5321::types::ehlo_domain::EhloDomain};
|
||||
use pimalaya_stream::{sasl::Sasl, std::stream::StreamStd, tls::Tls};
|
||||
|
||||
let smtp = (|| -> Result<SmtpClientStd<StreamStd>> {
|
||||
let mut tls: Tls = smtp_config.tls.into();
|
||||
tls.rustls.alpn = vec!["smtp".into()];
|
||||
let sasl: Option<Sasl> = smtp_config.sasl.map(Sasl::try_from).transpose()?;
|
||||
let domain: EhloDomain<'static> = Ipv4Addr::new(127, 0, 0, 1).into();
|
||||
let server = crate::smtp::client::parse_smtp_server(&smtp_config.server)?;
|
||||
Ok(SmtpClientStd::<StreamStd>::connect(
|
||||
&server,
|
||||
&tls,
|
||||
smtp_config.starttls,
|
||||
domain,
|
||||
sasl,
|
||||
)?)
|
||||
})();
|
||||
|
||||
match smtp {
|
||||
Ok(client) => inner = inner.with_smtp(client),
|
||||
Err(err) => {
|
||||
log::warn!("SMTP backend disabled: {err}. Sending will be unavailable.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let account = Account::from(config).merge(Account::from(account_config));
|
||||
|
||||
Ok(Self { inner, account })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user