mail: update to lettre-0.10.0-rc.5 and adapt
This commit is contained in:
parent
39fae28f53
commit
55ec155b30
|
@ -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"
|
||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -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"
|
||||
|
||||
|
|
94
src/mail.rs
94
src/mail.rs
|
@ -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?="
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue