aboutsummaryrefslogtreecommitdiff
path: root/crates/secd/src/client/email.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--crates/secd/src/client/email.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/crates/secd/src/client/email.rs b/crates/secd/src/client/email.rs
new file mode 100644
index 0000000..fc48702
--- /dev/null
+++ b/crates/secd/src/client/email.rs
@@ -0,0 +1,62 @@
+use std::{path::PathBuf, str::FromStr};
+
+use email_address::EmailAddress;
+
+use super::{
+ EmailMessenger, EmailMessengerError, EmailType, EMAIL_TEMPLATE_DEFAULT_LOGIN,
+ EMAIL_TEMPLATE_DEFAULT_SIGNUP,
+};
+
+pub(crate) struct LocalEmailStubber {
+ pub(crate) email_template_login: Option<String>,
+ pub(crate) email_template_signup: Option<String>,
+}
+
+#[async_trait::async_trait]
+impl EmailMessenger for LocalEmailStubber {
+ // TODO: this module really shouldn't be called client, it should be called services... the client is sqlx/mailgun/sns wrapper or whatever...
+ async fn send_email(
+ &self,
+ email_address: &str,
+ validation_id: &str,
+ secret_code: &str,
+ t: EmailType,
+ ) -> Result<(), EmailMessengerError> {
+ let login_template = self
+ .email_template_login
+ .clone()
+ .unwrap_or(EMAIL_TEMPLATE_DEFAULT_LOGIN.to_string());
+ let signup_template = self
+ .email_template_signup
+ .clone()
+ .unwrap_or(EMAIL_TEMPLATE_DEFAULT_SIGNUP.to_string());
+
+ let replace_template = |s: &str| {
+ s.replace(
+ "%secd_link%",
+ &format!("{}?code={}", validation_id, secret_code),
+ )
+ .replace("%secd_email_address%", email_address)
+ .replace("%secd_code%", secret_code)
+ };
+
+ if !EmailAddress::is_valid(email_address) {
+ return Err(EmailMessengerError::InvalidEmailAddress);
+ }
+
+ let body = match t {
+ EmailType::Login => replace_template(&login_template),
+ EmailType::Signup => replace_template(&signup_template),
+ };
+
+ // TODO: write to the system mailbox instead?
+ std::fs::write(
+ PathBuf::from_str(&format!("/tmp/{}.localmail", validation_id))
+ .map_err(|_| EmailMessengerError::Unknown)?,
+ body,
+ )
+ .map_err(|_| EmailMessengerError::FailedToSendEmail)?;
+
+ Ok(())
+ }
+}