From 934f72511e3ef1a8d6fef6521bccc52b732f0a10 Mon Sep 17 00:00:00 2001 From: dullbananas Date: Mon, 10 Jul 2023 05:04:39 -0700 Subject: [PATCH] Use async email sender (#3554) --- Cargo.lock | 4 ++++ .../site/registration_applications/approve.rs | 2 +- crates/api_common/src/build_response.rs | 3 +++ crates/api_common/src/utils.rs | 18 ++++++++++-------- crates/api_crud/src/private_message/create.rs | 3 ++- crates/utils/Cargo.toml | 2 +- crates/utils/src/email.rs | 15 ++++++++------- src/prometheus_metrics.rs | 2 +- 8 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aec15fd74..4ffd5a7a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2990,10 +2990,12 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eabca5e0b4d0e98e7f2243fb5b7520b6af2b65d8f87bcc86f2c75185a6ff243" dependencies = [ + "async-trait", "base64 0.13.1", "email-encoding", "email_address", "fastrand", + "futures-io", "futures-util", "hostname", "httpdate", @@ -3004,6 +3006,8 @@ dependencies = [ "once_cell", "quoted_printable", "socket2 0.4.9", + "tokio", + "tokio-native-tls", ] [[package]] diff --git a/crates/api/src/site/registration_applications/approve.rs b/crates/api/src/site/registration_applications/approve.rs index b7f672e61..b153bd2a3 100644 --- a/crates/api/src/site/registration_applications/approve.rs +++ b/crates/api/src/site/registration_applications/approve.rs @@ -51,7 +51,7 @@ impl Perform for ApproveRegistrationApplication { let approved_local_user_view = LocalUserView::read(context.pool(), approved_user_id).await?; if approved_local_user_view.local_user.email.is_some() { - send_application_approved_email(&approved_local_user_view, context.settings())?; + send_application_approved_email(&approved_local_user_view, context.settings()).await?; } } diff --git a/crates/api_common/src/build_response.rs b/crates/api_common/src/build_response.rs index 328827b2c..217e05de6 100644 --- a/crates/api_common/src/build_response.rs +++ b/crates/api_common/src/build_response.rs @@ -128,6 +128,7 @@ pub async fn send_local_notifs( &lang.notification_mentioned_by_body(&comment.content, &inbox_link, &person.name), context.settings(), ) + .await } } } @@ -170,6 +171,7 @@ pub async fn send_local_notifs( &lang.notification_comment_reply_body(&comment.content, &inbox_link, &person.name), context.settings(), ) + .await } } } @@ -206,6 +208,7 @@ pub async fn send_local_notifs( &lang.notification_post_reply_body(&comment.content, &inbox_link, &person.name), context.settings(), ) + .await } } } diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index fd143ed90..2ef06f528 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -308,7 +308,7 @@ pub fn honeypot_check(honeypot: &Option) -> Result<(), LemmyError> { } } -pub fn send_email_to_user( +pub async fn send_email_to_user( local_user_view: &LocalUserView, subject: &str, body: &str, @@ -325,7 +325,9 @@ pub fn send_email_to_user( &local_user_view.person.name, body, settings, - ) { + ) + .await + { Ok(_o) => _o, Err(e) => warn!("{}", e), }; @@ -351,7 +353,7 @@ pub async fn send_password_reset_email( let protocol_and_hostname = settings.get_protocol_and_hostname(); let reset_link = format!("{}/password_change/{}", protocol_and_hostname, &token); let body = &lang.password_reset_body(reset_link, &user.person.name); - send_email(subject, email, &user.person.name, body, settings) + send_email(subject, email, &user.person.name, body, settings).await } /// Send a verification email @@ -376,7 +378,7 @@ pub async fn send_verification_email( let lang = get_interface_language(user); let subject = lang.verify_email_subject(&settings.hostname); let body = lang.verify_email_body(&settings.hostname, &user.person.name, verify_link); - send_email(&subject, new_email, &user.person.name, &body, settings)?; + send_email(&subject, new_email, &user.person.name, &body, settings).await?; Ok(()) } @@ -435,7 +437,7 @@ pub fn local_site_opt_to_sensitive(local_site: &Option) -> bool { .unwrap_or(false) } -pub fn send_application_approved_email( +pub async fn send_application_approved_email( user: &LocalUserView, settings: &Settings, ) -> Result<(), LemmyError> { @@ -443,7 +445,7 @@ pub fn send_application_approved_email( let lang = get_interface_language(user); let subject = lang.registration_approved_subject(&user.person.actor_id); let body = lang.registration_approved_body(&settings.hostname); - send_email(&subject, email, &user.person.name, &body, settings) + send_email(&subject, email, &user.person.name, &body, settings).await } /// Send a new applicant email notification to all admins @@ -465,7 +467,7 @@ pub async fn send_new_applicant_email_to_admins( let lang = get_interface_language_from_settings(admin); let subject = lang.new_application_subject(&settings.hostname, applicant_username); let body = lang.new_application_body(applications_link); - send_email(&subject, email, &admin.person.name, &body, settings)?; + send_email(&subject, email, &admin.person.name, &body, settings).await?; } Ok(()) } @@ -487,7 +489,7 @@ pub async fn send_new_report_email_to_admins( let lang = get_interface_language_from_settings(admin); let subject = lang.new_report_subject(&settings.hostname, reported_username, reporter_username); let body = lang.new_report_body(reports_link); - send_email(&subject, email, &admin.person.name, &body, settings)?; + send_email(&subject, email, &admin.person.name, &body, settings).await?; } Ok(()) } diff --git a/crates/api_crud/src/private_message/create.rs b/crates/api_crud/src/private_message/create.rs index e1a855463..187b3f90a 100644 --- a/crates/api_crud/src/private_message/create.rs +++ b/crates/api_crud/src/private_message/create.rs @@ -95,7 +95,8 @@ impl PerformCrud for CreatePrivateMessage { &lang.notification_private_message_subject(sender_name), &lang.notification_private_message_body(inbox_link, &content_slurs_removed, sender_name), context.settings(), - ); + ) + .await; } Ok(PrivateMessageResponse { diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index fc1feb853..6ef13ee90 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -42,7 +42,7 @@ html2text = "0.6.0" deser-hjson = "1.0.2" smart-default = "0.7.1" jsonwebtoken = "8.1.1" -lettre = "0.10.1" +lettre = { version = "0.10.1", features = ["tokio1", "tokio1-native-tls"] } markdown-it = "0.5.1" totp-rs = { version = "5.0.2", features = ["gen_secret", "otpauth"] } enum-map = "2.5" diff --git a/crates/utils/src/email.rs b/crates/utils/src/email.rs index 62cbe3c5e..fba624666 100644 --- a/crates/utils/src/email.rs +++ b/crates/utils/src/email.rs @@ -4,9 +4,8 @@ use lettre::{ message::{Mailbox, MultiPart}, transport::smtp::{authentication::Credentials, extension::ClientId}, Address, + AsyncTransport, Message, - SmtpTransport, - Transport, }; use std::str::FromStr; use uuid::Uuid; @@ -15,7 +14,9 @@ pub mod translations { rosetta_i18n::include_translations!(); } -pub fn send_email( +type AsyncSmtpTransport = lettre::AsyncSmtpTransport; + +pub async fn send_email( subject: &str, to_email: &str, to_username: &str, @@ -69,11 +70,11 @@ pub fn send_email( // is bad. // Set the TLS - let builder_dangerous = SmtpTransport::builder_dangerous(smtp_server).port(smtp_port); + let builder_dangerous = AsyncSmtpTransport::builder_dangerous(smtp_server).port(smtp_port); let mut builder = match email_config.tls_type.as_str() { - "starttls" => SmtpTransport::starttls_relay(smtp_server)?, - "tls" => SmtpTransport::relay(smtp_server)?, + "starttls" => AsyncSmtpTransport::starttls_relay(smtp_server)?, + "tls" => AsyncSmtpTransport::relay(smtp_server)?, _ => builder_dangerous, }; @@ -88,7 +89,7 @@ pub fn send_email( let mailer = builder.hello_name(ClientId::Domain(domain)).build(); - let result = mailer.send(&email); + let result = mailer.send(email).await; match result { Ok(_) => Ok(()), diff --git a/src/prometheus_metrics.rs b/src/prometheus_metrics.rs index 4fe8150f2..891ef2433 100644 --- a/src/prometheus_metrics.rs +++ b/src/prometheus_metrics.rs @@ -47,7 +47,7 @@ pub fn serve_prometheus(config: Option<&PrometheusConfig>, lemmy_context: LemmyC .route("/metrics", web::get().to(metrics)) }) .bind((bind, port as u16)) - .expect(&format!("Cannot bind to {}:{}", bind, port)) + .unwrap_or_else(|_| panic!("Cannot bind to {}:{}", bind, port)) .run(); if let Err(err) = server.await {