From 4ed50d357640d64995617caf2f12bd53de3c656f Mon Sep 17 00:00:00 2001 From: siddhantCodes Date: Tue, 27 Feb 2024 17:22:14 +0530 Subject: [PATCH 1/2] move mail.rs to fastn-ds add send_email method in DocumentStore --- Cargo.lock | 1 + .../create_and_send_confirmation_email.rs | 26 +++++++----------- .../src/auth/email_password/set_password.rs | 17 +++++------- fastn-core/src/lib.rs | 1 - fastn-ds/Cargo.toml | 1 + fastn-ds/src/lib.rs | 27 +++++++++++++++++++ {fastn-core => fastn-ds}/src/mail.rs | 0 7 files changed, 45 insertions(+), 28 deletions(-) rename {fastn-core => fastn-ds}/src/mail.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 3957fe92d6..7de85d1046 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1818,6 +1818,7 @@ dependencies = [ "dirs", "ftd 0.3.0", "ignore", + "lettre", "thiserror", "tokio", "tracing", diff --git a/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs b/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs index 6ed4d80e5a..77c5ece895 100644 --- a/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs +++ b/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs @@ -107,22 +107,16 @@ pub(crate) async fn create_and_send_confirmation_email( tracing::info!("confirmation link: {}", &confirmation_link); - fastn_core::mail::Mailer::send_raw( - req_config - .config - .ds - .env_bool("FASTN_ENABLE_EMAIL", true) - .await - .unwrap_or(true), - &req_config.config.ds, - format!("{} <{}>", name, email) - .parse::() - .unwrap(), - "Verify your email", - confirmation_mail_body(html, &confirmation_link), - ) - .await - .map_err(|e| fastn_core::Error::generic(format!("failed to send email: {e}")))?; + req_config + .config + .ds + .send_email( + (&name, &email), + "Verify your email", + confirmation_mail_body(html, &confirmation_link), + ) + .await + .map_err(|e| fastn_core::Error::generic(format!("failed to send email: {e}")))?; Ok((confirmation_link, session_id)) } diff --git a/fastn-core/src/auth/email_password/set_password.rs b/fastn-core/src/auth/email_password/set_password.rs index 5ced66f71e..0f22208c3d 100644 --- a/fastn-core/src/auth/email_password/set_password.rs +++ b/fastn-core/src/auth/email_password/set_password.rs @@ -177,17 +177,12 @@ pub(crate) async fn forgot_password_request( println!("RESET LINK: {}", &reset_link); } - fastn_core::mail::Mailer::send_raw( - enable_email, - &req_config.config.ds, - format!("{} <{}>", user.name, email.0) - .parse::() - .unwrap(), - "Reset your password", - html, - ) - .await - .map_err(|e| fastn_core::Error::generic(format!("failed to send email: {e}")))?; + req_config + .config + .ds + .send_email((&user.name, &email.0), "Reset your password", html) + .await + .map_err(|e| fastn_core::Error::generic(format!("failed to send email: {e}")))?; let resp_body = serde_json::json!({ "success": true, diff --git a/fastn-core/src/lib.rs b/fastn-core/src/lib.rs index 3a11ab4055..f2cb2616b6 100644 --- a/fastn-core/src/lib.rs +++ b/fastn-core/src/lib.rs @@ -33,7 +33,6 @@ mod version; pub mod catch_panic; pub(crate) mod google_sheets; mod library2022; -mod mail; pub use auth::UserData; pub(crate) use auto_import::AutoImport; diff --git a/fastn-ds/Cargo.toml b/fastn-ds/Cargo.toml index 72d297fc34..869dc0c7bb 100644 --- a/fastn-ds/Cargo.toml +++ b/fastn-ds/Cargo.toml @@ -17,3 +17,4 @@ camino.workspace = true ignore.workspace = true dirs.workspace = true tracing.workspace = true +lettre.workspace = true diff --git a/fastn-ds/src/lib.rs b/fastn-ds/src/lib.rs index 02b1cbc845..6b0f5b117b 100644 --- a/fastn-ds/src/lib.rs +++ b/fastn-ds/src/lib.rs @@ -1,5 +1,7 @@ extern crate self as fastn_ds; +mod mail; + #[derive(Debug, Clone)] pub struct DocumentStore { root: Path, @@ -246,6 +248,31 @@ impl DocumentStore { pub async fn env(&self, key: &str) -> Result { std::env::var(key).map_err(|_| EnvironmentError::NotSet(key.to_string())) } + + /// Send an email + /// to: (name, email) + pub async fn send_email( + &self, + to: (&str, &str), + subject: &str, + body_html: String, + ) -> Result<(), fastn_ds::mail::MailError> { + let enable_email = self + .env_bool("FASTN_ENABLE_EMAIL", true) + .await + .unwrap_or(true); + + let (name, email) = to; + + fastn_ds::mail::Mailer::send_raw( + enable_email, + self, + format!("{} <{}>", name, email).parse()?, + subject, + body_html, + ) + .await + } } #[derive(thiserror::Error, PartialEq, Debug)] diff --git a/fastn-core/src/mail.rs b/fastn-ds/src/mail.rs similarity index 100% rename from fastn-core/src/mail.rs rename to fastn-ds/src/mail.rs From 8983829c36e80434de49c48dc843ad7ce8227c92 Mon Sep 17 00:00:00 2001 From: siddhantCodes Date: Fri, 1 Mar 2024 15:50:31 +0530 Subject: [PATCH 2/2] accept email_kind in fastn_ds::send_email --- .../create_and_send_confirmation_email.rs | 1 + fastn-core/src/auth/email_password/set_password.rs | 7 ++++++- fastn-ds/src/lib.rs | 5 ++++- fastn-ds/src/mail.rs | 14 ++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs b/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs index 77c5ece895..829e4f0482 100644 --- a/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs +++ b/fastn-core/src/auth/email_password/create_and_send_confirmation_email.rs @@ -114,6 +114,7 @@ pub(crate) async fn create_and_send_confirmation_email( (&name, &email), "Verify your email", confirmation_mail_body(html, &confirmation_link), + fastn_ds::mail::EmailKind::AccountVerification, ) .await .map_err(|e| fastn_core::Error::generic(format!("failed to send email: {e}")))?; diff --git a/fastn-core/src/auth/email_password/set_password.rs b/fastn-core/src/auth/email_password/set_password.rs index 0f22208c3d..8f066a70a9 100644 --- a/fastn-core/src/auth/email_password/set_password.rs +++ b/fastn-core/src/auth/email_password/set_password.rs @@ -180,7 +180,12 @@ pub(crate) async fn forgot_password_request( req_config .config .ds - .send_email((&user.name, &email.0), "Reset your password", html) + .send_email( + (&user.name, &email.0), + "Reset your password", + html, + fastn_ds::mail::EmailKind::PasswordReset, + ) .await .map_err(|e| fastn_core::Error::generic(format!("failed to send email: {e}")))?; diff --git a/fastn-ds/src/lib.rs b/fastn-ds/src/lib.rs index 6b0f5b117b..3735b0090e 100644 --- a/fastn-ds/src/lib.rs +++ b/fastn-ds/src/lib.rs @@ -1,6 +1,6 @@ extern crate self as fastn_ds; -mod mail; +pub mod mail; #[derive(Debug, Clone)] pub struct DocumentStore { @@ -256,6 +256,7 @@ impl DocumentStore { to: (&str, &str), subject: &str, body_html: String, + mkind: fastn_ds::mail::EmailKind, ) -> Result<(), fastn_ds::mail::MailError> { let enable_email = self .env_bool("FASTN_ENABLE_EMAIL", true) @@ -264,6 +265,8 @@ impl DocumentStore { let (name, email) = to; + tracing::info!("sending mail of {mkind}"); + fastn_ds::mail::Mailer::send_raw( enable_email, self, diff --git a/fastn-ds/src/mail.rs b/fastn-ds/src/mail.rs index 47c2384537..dbb6c55ec9 100644 --- a/fastn-ds/src/mail.rs +++ b/fastn-ds/src/mail.rs @@ -99,3 +99,17 @@ impl Mailer { Ok(()) } } + +pub enum EmailKind { + AccountVerification, + PasswordReset, +} + +impl std::fmt::Display for EmailKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + EmailKind::AccountVerification => write!(f, "account-verification"), + EmailKind::PasswordReset => write!(f, "password-reset"), + } + } +}