fix(email): preserve legacy poll_interval alias and avoid lock across await
This commit is contained in:
parent
b3d5284be1
commit
e10d359cf9
1 changed files with 25 additions and 7 deletions
|
|
@ -61,7 +61,7 @@ pub struct EmailConfig {
|
||||||
pub from_address: String,
|
pub from_address: String,
|
||||||
/// IDLE timeout in seconds before re-establishing connection (default: 1740 = 29 minutes)
|
/// IDLE timeout in seconds before re-establishing connection (default: 1740 = 29 minutes)
|
||||||
/// RFC 2177 recommends clients restart IDLE every 29 minutes
|
/// RFC 2177 recommends clients restart IDLE every 29 minutes
|
||||||
#[serde(default = "default_idle_timeout")]
|
#[serde(default = "default_idle_timeout", alias = "poll_interval_secs")]
|
||||||
pub idle_timeout_secs: u64,
|
pub idle_timeout_secs: u64,
|
||||||
/// Allowed sender addresses/domains (empty = deny all, ["*"] = allow all)
|
/// Allowed sender addresses/domains (empty = deny all, ["*"] = allow all)
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
@ -196,7 +196,7 @@ impl EmailChannel {
|
||||||
// Connect TCP
|
// Connect TCP
|
||||||
let tcp = TcpStream::connect(&addr).await?;
|
let tcp = TcpStream::connect(&addr).await?;
|
||||||
|
|
||||||
// Establish TLS using native-tls
|
// Establish TLS using rustls
|
||||||
let certs = RootCertStore {
|
let certs = RootCertStore {
|
||||||
roots: webpki_roots::TLS_SERVER_ROOTS.into(),
|
roots: webpki_roots::TLS_SERVER_ROOTS.into(),
|
||||||
};
|
};
|
||||||
|
|
@ -420,17 +420,21 @@ impl EmailChannel {
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let messages = self.fetch_unseen(session).await?;
|
let messages = self.fetch_unseen(session).await?;
|
||||||
|
|
||||||
let mut seen = self.seen_messages.lock().await;
|
|
||||||
for email in messages {
|
for email in messages {
|
||||||
if seen.contains(&email.msg_id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Check allowlist
|
// Check allowlist
|
||||||
if !self.is_sender_allowed(&email.sender) {
|
if !self.is_sender_allowed(&email.sender) {
|
||||||
warn!("Blocked email from {}", email.sender);
|
warn!("Blocked email from {}", email.sender);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
seen.insert(email.msg_id.clone());
|
|
||||||
|
let is_new = {
|
||||||
|
let mut seen = self.seen_messages.lock().await;
|
||||||
|
seen.insert(email.msg_id.clone())
|
||||||
|
};
|
||||||
|
if !is_new {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let msg = ChannelMessage {
|
let msg = ChannelMessage {
|
||||||
id: email.msg_id,
|
id: email.msg_id,
|
||||||
reply_target: email.sender.clone(),
|
reply_target: email.sender.clone(),
|
||||||
|
|
@ -919,6 +923,20 @@ mod tests {
|
||||||
assert_eq!(config.idle_timeout_secs, 900);
|
assert_eq!(config.idle_timeout_secs, 900);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn idle_timeout_deserializes_legacy_poll_interval_alias() {
|
||||||
|
let json = r#"{
|
||||||
|
"imap_host": "imap.test.com",
|
||||||
|
"smtp_host": "smtp.test.com",
|
||||||
|
"username": "user",
|
||||||
|
"password": "pass",
|
||||||
|
"from_address": "bot@test.com",
|
||||||
|
"poll_interval_secs": 120
|
||||||
|
}"#;
|
||||||
|
let config: EmailConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.idle_timeout_secs, 120);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn idle_timeout_propagates_to_channel() {
|
fn idle_timeout_propagates_to_channel() {
|
||||||
let config = EmailConfig {
|
let config = EmailConfig {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue