Move spam messages to Junk folders when spam headers are present

This commit is contained in:
mdecimus 2023-12-21 10:56:28 +01:00
parent 91e8597998
commit 57885e6db6
4 changed files with 31 additions and 2 deletions

View file

@ -141,6 +141,14 @@ impl crate::Config {
.unwrap_or(true),
encrypt: settings.property_or_static("jmap.encryption.enable", "true")?,
encrypt_append: settings.property_or_static("jmap.encryption.append", "false")?,
spam_header: settings.value("jmap.spam.header").and_then(|v| {
v.split_once(':').map(|(k, v)| {
(
mail_parser::HeaderName::parse(k.trim().to_string()).unwrap(),
v.trim().to_string(),
)
})
}),
http_headers: settings
.values("jmap.http.headers")
.map(|(_, v)| {

View file

@ -48,7 +48,7 @@ use utils::map::vec_map::VecMap;
use crate::{
email::index::{IndexMessage, VisitValues, MAX_ID_LENGTH},
mailbox::UidMailbox,
mailbox::{UidMailbox, INBOX_ID, JUNK_ID},
services::housekeeper::Event,
IngestError, JMAP,
};
@ -84,7 +84,7 @@ impl JMAP {
#[allow(clippy::blocks_in_if_conditions)]
pub async fn email_ingest(
&self,
params: IngestEmail<'_>,
mut params: IngestEmail<'_>,
) -> Result<IngestedEmail, IngestError> {
// Check quota
let mut raw_message_len = params.raw_message.len() as i64;
@ -106,6 +106,21 @@ impl JMAP {
reason: "Failed to parse e-mail message.".to_string(),
})?;
// Check for Spam headers
if let Some((header_name, header_value)) = &self.config.spam_header {
if params.mailbox_ids == [INBOX_ID]
&& message.root_part().headers().iter().any(|header| {
&header.name == header_name
&& header
.value()
.as_text()
.map_or(false, |value| value.contains(header_value))
})
{
params.mailbox_ids[0] = JUNK_ID;
}
}
// Obtain message references and thread name
let thread_id = {
let mut references = Vec::with_capacity(5);

View file

@ -40,6 +40,7 @@ use jmap_proto::{
},
types::{collection::Collection, property::Property},
};
use mail_parser::HeaderName;
use nlp::language::Language;
use services::{
delivery::spawn_delivery_manager,
@ -157,6 +158,8 @@ pub struct Config {
pub oauth_expiry_refresh_token_renew: u64,
pub oauth_max_auth_attempts: u32,
pub spam_header: Option<(HeaderName<'static>, String)>,
pub http_headers: Vec<(hyper::header::HeaderName, hyper::header::HeaderValue)>,
pub encrypt: bool,

View file

@ -11,6 +11,9 @@ blob = "__BLOB_STORE__"
enable = true
append = false
[jmap.spam]
header = "X-Spam-Status: Yes"
[jmap.fts]
default-language = "en"