mail: update to lettre-0.10.0-rc.5 and adapt

This commit is contained in:
Vincent Breitmoser 2022-04-09 13:27:17 +02:00
parent 39fae28f53
commit 55ec155b30
4 changed files with 62 additions and 118 deletions

74
Cargo.lock generated
View File

@ -56,12 +56,6 @@ dependencies = [
"term",
]
[[package]]
name = "ascii_utils"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
[[package]]
name = "async-stream"
version = "0.3.2"
@ -166,12 +160,6 @@ dependencies = [
"byteorder",
]
[[package]]
name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
name = "base64"
version = "0.13.0"
@ -506,18 +494,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "email"
version = "0.0.20"
name = "email-encoding"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91549a51bb0241165f13d57fc4c72cef063b4088fb078b019ecbf464a45f22e4"
checksum = "6690291166824e467790ac08ba42f241791567e8337bbf00c5a6e87889629f98"
dependencies = [
"base64 0.9.3",
"chrono",
"encoding",
"lazy_static",
"rand 0.4.6",
"time 0.1.43",
"version_check 0.1.5",
"base64 0.13.0",
]
[[package]]
@ -615,12 +597,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "fast_chemail"
version = "0.9.6"
name = "fastrand"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4"
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [
"ascii_utils",
"instant",
]
[[package]]
@ -944,7 +926,6 @@ dependencies = [
"multipart",
"num_cpus",
"regex",
"rfc2047",
"ring",
"rocket",
"rocket_codegen",
@ -1356,17 +1337,19 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "lettre"
version = "0.10.0-pre"
source = "git+https://github.com/lettre/lettre?rev=245c600c82ee18b766e8729f005ff453a55dce34#245c600c82ee18b766e8729f005ff453a55dce34"
version = "0.10.0-rc.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5144148f337be14dabfc0f0d85b691a68ac6c77ef22a5c47c5504b70a7c9fcf3"
dependencies = [
"base64 0.11.0",
"email",
"fast_chemail",
"log 0.4.14",
"base64 0.13.0",
"email-encoding",
"fastrand",
"httpdate",
"idna 0.2.3",
"mime 0.3.16",
"serde",
"serde_json",
"time 0.2.27",
"once_cell",
"quoted_printable",
"regex",
"uuid 0.8.2",
]
@ -2097,17 +2080,10 @@ dependencies = [
]
[[package]]
name = "rand"
version = "0.4.6"
name = "quoted_printable"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi 0.3.9",
]
checksum = "3fee2dce59f7a43418e3382c766554c614e06a552d53a8f07ef499ea4b332c0f"
[[package]]
name = "rand"
@ -2379,12 +2355,6 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "rfc2047"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6986b5de4fa30c92b50020fdedf45bf9296d9842df4355b62f92dcc18bcdee15"
[[package]]
name = "ring"
version = "0.13.5"

View File

@ -39,8 +39,8 @@ gettext-macros = "0.6.1"
gettext-utils = "0.1"
gettext = "0.4"
glob = "0.3"
rfc2047 = "0.1"
hyperx = "1.4"
lettre = { version = "0.10.0-rc.5", default-features = false, features = ["builder", "file-transport", "sendmail-transport"] }
[dependencies.rocket_i18n]
git = "https://github.com/Plume-org/rocket_i18n"
@ -48,14 +48,6 @@ branch = "go-async"
default-features = false
features = ["rocket"]
[dependencies.lettre]
version = "0.10.0-pre"
default-features = false
# smtp-transport doesn't build (openssl problem)
features = ["builder", "file-transport", "sendmail-transport"]
git = "https://github.com/lettre/lettre"
rev = "245c600c82ee18b766e8729f005ff453a55dce34"
[build-dependencies]
vergen = "3"

View File

@ -2,16 +2,14 @@ use std::path::{Path, PathBuf};
use crate::counters;
use handlebars::Handlebars;
use lettre::builder::{EmailBuilder, Mailbox, MimeMultipartType, PartBuilder};
use lettre::{file::FileTransport, SendmailTransport, Transport as LettreTransport};
use lettre::message::{Mailbox, MultiPart, SinglePart, header};
use lettre::{FileTransport, SendmailTransport, Transport as LettreTransport};
use serde::Serialize;
use uuid::Uuid;
use gettext_macros::i18n;
use rocket_i18n::I18n;
use rfc2047::rfc2047_encode;
use crate::template_helpers;
use crate::database::types::Email;
@ -81,8 +79,9 @@ impl Service {
.host_str()
.ok_or_else(|| anyhow!("No host in base-URI"))?
.to_string();
let from = from.parse().map_err(|_| anyhow!("From must be valid email address"))?;
Ok(Self {
from: from.into(),
from,
domain,
templates,
transport,
@ -203,7 +202,7 @@ impl Service {
fn send(
&self,
to: &[&Email],
tos: &[&Email],
subject: &str,
template: &str,
locale: &str,
@ -212,46 +211,44 @@ impl Service {
let (html, txt) = self.render_template(template, locale, ctx)?;
if cfg!(debug_assertions) {
for recipient in to.iter() {
for recipient in tos.iter() {
println!("To: {}", recipient);
}
println!("{}", &txt);
}
// build this ourselves, as a temporary workaround for https://github.com/lettre/lettre/issues/400
let text = PartBuilder::new()
.body(txt)
.header(("Content-Type", "text/plain; charset=utf-8"))
.header(("Content-Transfer-Encoding", "8bit"))
.build();
let html = PartBuilder::new()
.body(html)
.header(("Content-Type", "text/html; charset=utf-8"))
.header(("Content-Transfer-Encoding", "8bit"))
.build();
let email = EmailBuilder::new()
let mut email = lettre::Message::builder()
.from(self.from.clone())
.subject(rfc2047_encode(subject))
.message_id(format!("<{}@{}>", Uuid::new_v4(), self.domain))
.message_type(MimeMultipartType::Alternative)
.header(("Content-Transfer-Encoding", "8bit"))
.child(text)
.child(html);
.subject(subject)
.message_id(Some(format!("<{}@{}>", Uuid::new_v4(), self.domain)))
.header(header::ContentTransferEncoding::EightBit);
let email = to.iter().fold(email, |email, to| email.to(to.to_string()));
for to in tos.iter() {
email = email.to(to.as_str().parse().unwrap());
}
let email = email.build()?;
let email = email.multipart(
MultiPart::alternative()
.singlepart(
SinglePart::builder()
.header(header::ContentTransferEncoding::EightBit)
.header(header::ContentType::TEXT_PLAIN)
.body(txt)
)
.singlepart(SinglePart::builder()
.header(header::ContentTransferEncoding::EightBit)
.header(header::ContentType::TEXT_HTML)
.body(html)),
)?;
match self.transport {
Transport::Sendmail => {
let mut transport = SendmailTransport::new();
transport.send(email)?;
let transport = SendmailTransport::new();
transport.send(&email)?;
}
Transport::Filemail(ref path) => {
let mut transport = FileTransport::new(path);
transport.send(email)?;
let transport = FileTransport::new(path);
transport.send(&email)?;
}
}
@ -259,31 +256,17 @@ impl Service {
}
}
// for some reason, this is no longer public in lettre itself
// FIXME replace with builtin struct on lettre update
// see https://github.com/lettre/lettre/blob/master/lettre/src/file/mod.rs#L41
#[cfg(test)]
#[derive(Deserialize)]
struct SerializableEmail {
#[serde(alias = "envelope")]
_envelope: lettre::Envelope,
#[serde(alias = "message_id")]
_message_id: String,
message: Vec<u8>,
}
/// Returns and removes the first mail it finds from the given
/// directory.
#[cfg(test)]
pub fn pop_mail(dir: &Path) -> Result<Option<String>> {
use std::fs;
use std::{fs, fs::read_to_string};
for entry in fs::read_dir(dir)? {
let entry = entry?;
if entry.file_type()?.is_file() {
let fh = fs::File::open(entry.path())?;
let body = read_to_string(entry.path())?.replace("\r\n", "\n");
fs::remove_file(entry.path())?;
let mail: SerializableEmail = ::serde_json::from_reader(fh)?;
let body = String::from_utf8_lossy(&mail.message).to_string();
println!("{}", body);
return Ok(Some(body));
}
}
@ -346,15 +329,14 @@ mod test {
(h, v)
})
.collect();
assert!(headers.contains(&("Content-Transfer-Encoding", "8bit")));
assert!(headers.contains(&("Content-Type", "text/plain; charset=utf-8")));
assert!(headers.contains(&("Content-Type", "text/html; charset=utf-8")));
assert!(headers.contains(&("From", "<test@localhost>")));
assert!(headers.contains(&("To", "<recipient@example.org>")));
assert!(headers.contains(&("From", "test@localhost")));
assert!(headers.contains(&("To", "recipient@example.org")));
assert_header(&headers, "Content-Type", |v| {
v.starts_with("multipart/alternative")
});
assert_header(&headers, "Date", |v| v.contains("+0000"));
assert_header(&headers, "Date", |v| v.contains("-0000"));
assert_header(&headers, "Message-ID", |v| v.contains("@localhost>"));
}
@ -413,7 +395,7 @@ mod test {
assert!(mail_content.contains("test/about"));
assert!(mail_content.contains("あなたのメールアド"));
assert!(mail_content.contains(
"Subject: =?utf-8?q?localhost=E3=81=AE=E3=81=82=E3=81=AA=E3=81=9F=E3=81=AE?="
"Subject: =?utf-8?b?bG9jYWxob3N044Gu44GC44Gq44Gf44Gu6Y2144Gu44Gf44KB44GrbG9jYWxob3N044KS5qSc6Ki844GZ44KL?="
));
}
@ -467,7 +449,7 @@ mod test {
assert!(mail_content.contains("test/about"));
assert!(mail_content.contains("この鍵の掲示されたア"));
assert!(mail_content.contains(
"Subject: =?utf-8?q?localhost=E3=81=AE=E9=8D=B5=E3=82=92=E7=AE=A1=E7=90=86?="
"Subject: =?utf-8?b?bG9jYWxob3N044Gu6Y2144KS566h55CG44GZ44KL?="
));
}

View File

@ -887,7 +887,7 @@ pub mod tests {
check_verify_link(&client, &token, "foo@invalid.example.com", "de");
let mail_content = pop_mail(&filemail_into).unwrap().unwrap();
assert!(mail_content.contains("Dies ist eine automatisierte Nachricht"));
assert!(mail_content.contains("Subject: =?utf-8?q?Best=C3=A4tige?= foo@invalid.example.com\r\n\t=?utf-8?q?f=C3=BCr?= deinen =?utf-8?q?Schl=C3=BCssel?= auf local.connection"));
assert!(mail_content.contains("Subject: =?utf-8?b?QmVzdMOkdGlnZQ==?= foo@invalid.example.com \n =?utf-8?b?ZsO8cg==?= deinen =?utf-8?b?U2NobMO8c3NlbA==?= auf \n local.connection"));
}
#[test]