mirror of
https://github.com/chatmail/core.git
synced 2026-04-02 05:22:14 +03:00
Compare commits
2 Commits
v2.27.0
...
link2xt/li
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80f59b3ff0 | ||
|
|
5bdc3cefb7 |
@@ -63,6 +63,10 @@ pub(crate) struct MimeMessage {
|
||||
/// Whether the From address was repeated in the signed part
|
||||
/// (and we know that the signer intended to send from this address)
|
||||
pub from_is_signed: bool,
|
||||
|
||||
/// List-Id header as defined in <https://datatracker.ietf.org/doc/html/rfc2919>.
|
||||
pub list_id: Option<SingleInfo>,
|
||||
|
||||
pub list_post: Option<String>,
|
||||
pub chat_disposition_notification_to: Option<SingleInfo>,
|
||||
pub decryption_info: DecryptionInfo,
|
||||
@@ -212,6 +216,7 @@ impl MimeMessage {
|
||||
let mut headers = Default::default();
|
||||
let mut recipients = Default::default();
|
||||
let mut from = Default::default();
|
||||
let mut list_id = Default::default();
|
||||
let mut list_post = Default::default();
|
||||
let mut chat_disposition_notification_to = None;
|
||||
|
||||
@@ -221,6 +226,7 @@ impl MimeMessage {
|
||||
&mut headers,
|
||||
&mut recipients,
|
||||
&mut from,
|
||||
&mut list_id,
|
||||
&mut list_post,
|
||||
&mut chat_disposition_notification_to,
|
||||
&mail.headers,
|
||||
@@ -239,6 +245,7 @@ impl MimeMessage {
|
||||
&mut headers,
|
||||
&mut recipients,
|
||||
&mut from,
|
||||
&mut list_id,
|
||||
&mut list_post,
|
||||
&mut chat_disposition_notification_to,
|
||||
&part.headers,
|
||||
@@ -344,6 +351,7 @@ impl MimeMessage {
|
||||
&mut headers,
|
||||
&mut recipients,
|
||||
&mut signed_from,
|
||||
&mut list_id,
|
||||
&mut list_post,
|
||||
&mut chat_disposition_notification_to,
|
||||
&mail.headers,
|
||||
@@ -386,6 +394,7 @@ impl MimeMessage {
|
||||
parts: Vec::new(),
|
||||
header: headers,
|
||||
recipients,
|
||||
list_id,
|
||||
list_post,
|
||||
from,
|
||||
from_is_signed,
|
||||
@@ -1375,6 +1384,7 @@ impl MimeMessage {
|
||||
headers: &mut HashMap<String, String>,
|
||||
recipients: &mut Vec<SingleInfo>,
|
||||
from: &mut Option<SingleInfo>,
|
||||
list_id: &mut Option<SingleInfo>,
|
||||
list_post: &mut Option<String>,
|
||||
chat_disposition_notification_to: &mut Option<SingleInfo>,
|
||||
fields: &[mailparse::MailHeader<'_>],
|
||||
@@ -1392,6 +1402,14 @@ impl MimeMessage {
|
||||
}
|
||||
Err(e) => warn!(context, "Could not read {} address: {}", key, e),
|
||||
}
|
||||
} else if key == HeaderDef::ListId.get_headername() {
|
||||
match addrparse_header(field) {
|
||||
Ok(addrlist) => {
|
||||
*list_id = addrlist.extract_single_info();
|
||||
}
|
||||
Err(e) => warn!(context, "Could not read {} address: {}", key, e),
|
||||
}
|
||||
eprintln!("LIST ID parsed as {:?}", *list_id);
|
||||
} else {
|
||||
let value = field.get_value();
|
||||
headers.insert(key.to_string(), value);
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::collections::HashSet;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use anyhow::{bail, ensure, Context as _, Result};
|
||||
use mailparse::{parse_mail, SingleInfo};
|
||||
use mailparse::{addrparse, parse_mail, SingleInfo};
|
||||
use num_traits::FromPrimitive;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
@@ -1835,15 +1835,23 @@ async fn create_or_lookup_mailinglist(
|
||||
mime_parser: &MimeMessage,
|
||||
) -> Result<Option<(ChatId, Blocked)>> {
|
||||
static LIST_ID: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(.+)<(.+)>$").unwrap());
|
||||
eprintln!("List ID is {list_id_header:?}");
|
||||
let (mut name, listid) = match LIST_ID.captures(list_id_header) {
|
||||
Some(cap) => (cap[1].trim().to_string(), cap[2].trim().to_string()),
|
||||
None => (
|
||||
"".to_string(),
|
||||
list_id_header
|
||||
.trim()
|
||||
.trim_start_matches('<')
|
||||
.trim_end_matches('>')
|
||||
.to_string(),
|
||||
match addrparse(list_id_header)
|
||||
.ok()
|
||||
.and_then(|addrlist| addrlist.extract_single_info())
|
||||
.and_then(|info| info.display_name)
|
||||
{
|
||||
Some(name) => name.clone(),
|
||||
None => list_id_header
|
||||
.trim()
|
||||
.trim_start_matches('<')
|
||||
.trim_end_matches('>')
|
||||
.to_string(),
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
|
||||
@@ -1058,6 +1058,30 @@ async fn test_mailing_list_multiple_names_in_subject() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_mailing_list_with_quotes() -> Result<()> {
|
||||
let t = TestContext::new_alice().await;
|
||||
receive_imf(
|
||||
&t,
|
||||
b"From: Foo Bar <foobar@lists.example.net>\n\
|
||||
To: Alice <alice@example.org>\n\
|
||||
Subject: confirm xxyyzz\n\
|
||||
Message-ID: <3333@example.org>\n\
|
||||
List-Id: \"Mailing list for \\\"Foo Bar\\\"\"\n\
|
||||
\t<foo-bar.lists.example.net>\n\
|
||||
Date: Sun, 22 Mar 2020 22:37:57 +0000\n\
|
||||
\n\
|
||||
hello\n",
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
let msg = t.get_last_msg().await;
|
||||
let chat_id = msg.get_chat_id();
|
||||
let chat = Chat::load_from_db(&t, chat_id).await?;
|
||||
assert_eq!(chat.name, "Mailing list for \"Foo Bar\"");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_majordomo_mailing_list() -> Result<()> {
|
||||
let t = TestContext::new_alice().await;
|
||||
|
||||
Reference in New Issue
Block a user