diff options
author | pennae <github@quasiparticle.net> | 2022-07-13 10:33:30 +0200 |
---|---|---|
committer | pennae <github@quasiparticle.net> | 2022-07-13 13:27:12 +0200 |
commit | 2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328 (patch) | |
tree | caff55807c5fc773a36aa773cfde9cd6ebbbb6c8 /src/mailer.rs | |
download | minor-skulk-2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328.tar.gz minor-skulk-2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328.tar.xz minor-skulk-2f8dce44d3f2be74b5c6ec0a2e7f4ceced715328.zip |
initial import
Diffstat (limited to 'src/mailer.rs')
-rw-r--r-- | src/mailer.rs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/mailer.rs b/src/mailer.rs new file mode 100644 index 0000000..1ea1a8b --- /dev/null +++ b/src/mailer.rs @@ -0,0 +1,105 @@ +use std::time::Duration; + +use lettre::{ + message::Mailbox, + transport::smtp::client::{Tls, TlsParameters}, + AsyncSmtpTransport, Message, Tokio1Executor, +}; +use rocket::http::uri::Absolute; +use serde_json::json; + +use crate::types::UserID; + +pub struct Mailer { + from: Mailbox, + verify_base: Absolute<'static>, + transport: AsyncSmtpTransport<Tokio1Executor>, +} + +impl Mailer { + pub fn new( + from: Mailbox, + host: &str, + port: u16, + verify_base: Absolute<'static>, + ) -> anyhow::Result<Self> { + Ok(Mailer { + from, + verify_base, + transport: AsyncSmtpTransport::<Tokio1Executor>::builder_dangerous(host) + .port(port) + .tls(Tls::Opportunistic(TlsParameters::new(host.to_string())?)) + .timeout(Some(Duration::from_secs(5))) + .build(), + }) + } + + pub(crate) async fn send_account_verify( + &self, + uid: &UserID, + to: &str, + code: &str, + ) -> anyhow::Result<()> { + let fragment = base64::encode_config( + serde_json::to_string(&json!({ + "uid": uid, + "email": to, + "code": code, + }))?, + base64::URL_SAFE, + ); + let email = Message::builder() + .from(self.from.clone()) + .to(to.parse()?) + .subject("account verify code") + .body(format!("{}/#/verify/{fragment}", self.verify_base))?; + lettre::AsyncTransport::send(&self.transport, email).await?; + Ok(()) + } + + pub(crate) async fn send_session_verify(&self, to: &str, code: &str) -> anyhow::Result<()> { + let email = Message::builder() + .from(self.from.clone()) + .to(to.parse()?) + .subject("session verify code") + .body(format!("{code}"))?; + lettre::AsyncTransport::send(&self.transport, email).await?; + Ok(()) + } + + pub(crate) async fn send_password_changed(&self, to: &str) -> anyhow::Result<()> { + let email = Message::builder() + .from(self.from.clone()) + .to(to.parse()?) + .subject("account password has been changed") + .body(String::from( + "your account password has been changed. if you haven't done this, \ + you're probably in trouble now.", + ))?; + lettre::AsyncTransport::send(&self.transport, email).await?; + Ok(()) + } + + pub(crate) async fn send_password_forgot(&self, to: &str, code: &str) -> anyhow::Result<()> { + let email = Message::builder() + .from(self.from.clone()) + .to(to.parse()?) + .subject("account reset code") + .body(code.to_string())?; + lettre::AsyncTransport::send(&self.transport, email).await?; + Ok(()) + } + + pub(crate) async fn send_account_reset(&self, to: &str) -> anyhow::Result<()> { + let email = Message::builder() + .from(self.from.clone()) + .to(to.parse()?) + .subject("account has been reset") + .body(String::from( + "your account has been reset. if you haven't done this, \ + you're probably in trouble now.", + ))?; + lettre::AsyncTransport::send(&self.transport, email).await?; + Ok(()) + } +} |