Use async email sender (#3554)
authordullbananas <dull.bananas0@gmail.com>
Mon, 10 Jul 2023 12:04:39 +0000 (05:04 -0700)
committerGitHub <noreply@github.com>
Mon, 10 Jul 2023 12:04:39 +0000 (14:04 +0200)
Cargo.lock
crates/api/src/site/registration_applications/approve.rs
crates/api_common/src/build_response.rs
crates/api_common/src/utils.rs
crates/api_crud/src/private_message/create.rs
crates/utils/Cargo.toml
crates/utils/src/email.rs
src/prometheus_metrics.rs

index aec15fd74a466ae0072254bd68d975692992c02d..4ffd5a7a9554eea128641870107a3d468b3d6bef 100644 (file)
@@ -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]]
index b7f672e61b6c3a53b0210d608d9e04e849c7a729..b153bd2a370c605ed697d29436a65ff1bd38a86e 100644 (file)
@@ -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?;
       }
     }
 
index 328827b2ce99a720859e7cf7be23f7c5f4c77a3f..217e05de6b96211f6f6e9ee7c65806c96646a46d 100644 (file)
@@ -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
         }
       }
     }
index fd143ed90ca2d7df5285e6a03599dbc6667b1d36..2ef06f52802ab727e3dbc21cbbb45e5647f17b38 100644 (file)
@@ -308,7 +308,7 @@ pub fn honeypot_check(honeypot: &Option<String>) -> 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<LocalSite>) -> 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(())
 }
index e1a855463d6baae18b735fa20c778f0a82191fdb..187b3f90ae6149dd6ac0fdb6458e37dfb4159f9e 100644 (file)
@@ -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 {
index fc1feb853bcc8e1a1f0af071ccc8a8720f9cf816..6ef13ee906fec3ac6c7491d034350654d6910695 100644 (file)
@@ -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"
index 62cbe3c5e046ad890a352db1eefaed61db221bcd..fba624666e7c45283de569001889f4c5f88917f0 100644 (file)
@@ -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<lettre::Tokio1Executor>;
+
+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(()),
index 4fe8150f2b908a26b94cb6137e98a4c7cbc46124..891ef2433eeb7f795db1c75bfa3b1462280aa4f3 100644 (file)
@@ -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 {