feat: mailer adapter: bootstrap smtp client
This commit is contained in:
parent
e60a78054e
commit
ef2c2fec2f
4 changed files with 128 additions and 0 deletions
|
@ -0,0 +1,65 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use super::*;
|
||||
use crate::identity::application::port::output::mailer::{account_validation_link::*, errors::*};
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl AccountValidationLinkOutMailerPort for LettreMailer {
|
||||
async fn account_validation_link(
|
||||
&self,
|
||||
to: &str,
|
||||
username: &str,
|
||||
validation_secret: &str,
|
||||
) -> OutMailerPortResult<()> {
|
||||
|
||||
let email = Message::builder()
|
||||
.from(&self.from)
|
||||
.reply_to(&self.reply_to)
|
||||
.to(to)
|
||||
.subject("Please validate your account on Vanikam") // TODO: use better title
|
||||
.header(ContentType::TEXT_PLAIN)
|
||||
.body(format!(r#"Hello {username},
|
||||
Please click here to validate your Vanikam account: {validation_secret}
|
||||
Warm regards,
|
||||
Vanikam Admin
|
||||
"#)) // TODO: change signature
|
||||
.unwrap();
|
||||
mailer.send(email).await.unwrap();
|
||||
|
||||
}
|
||||
}
|
||||
// TODO: mailer tests
|
||||
|
||||
//#[cfg(test)]
|
||||
//mod tests {
|
||||
// use super::*;
|
||||
//
|
||||
// #[actix_rt::test]
|
||||
// async fn test_postgres_create_verification_secret() {
|
||||
// let settings = crate::settings::tests::get_settings().await;
|
||||
// let db = super::DBOutPostgresAdapter::new(
|
||||
// sqlx::postgres::PgPool::connect(&settings.database.url)
|
||||
// .await
|
||||
// .unwrap(),
|
||||
// );
|
||||
//
|
||||
// let msg = CreateSecretMsgBuilder::default()
|
||||
// .secret("secret".into())
|
||||
// .purpose("purpose".into())
|
||||
// .username("username".into())
|
||||
// .build()
|
||||
// .unwrap();
|
||||
//
|
||||
// db.create_verification_secret(msg.clone()).await.unwrap();
|
||||
//
|
||||
// // duplicate: secret exists
|
||||
// assert_eq!(
|
||||
// db.create_verification_secret(msg).await.err(),
|
||||
// Some(OutDBPortError::VerificationOTPSecretExists)
|
||||
// );
|
||||
//
|
||||
// settings.drop_db().await;
|
||||
// }
|
||||
//}
|
55
src/identity/adapters/output/mailer/lettre/mod.rs
Normal file
55
src/identity/adapters/output/mailer/lettre/mod.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use lettre::{
|
||||
message::header::ContentType, transport::smtp::authentication::Credentials, AsyncSmtpTransport,
|
||||
Message, Tokio1Executor,
|
||||
};
|
||||
|
||||
use crate::settings::Settings;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LettreMailer {
|
||||
mailer: AsyncSmtpTransport<Tokio1Executor>,
|
||||
from: String,
|
||||
reply_to: String,
|
||||
to: String,
|
||||
}
|
||||
|
||||
impl LettreMailer {
|
||||
pub async fn new(s: &Settings) -> Self {
|
||||
let email = Message::builder()
|
||||
.from("NoBody <nobody@domain.tld>".parse().unwrap())
|
||||
.reply_to("Yuin <yuin@domain.tld>".parse().unwrap())
|
||||
.to("Hei <hei@domain.tld>".parse().unwrap())
|
||||
.subject("Happy new async year")
|
||||
.header(ContentType::TEXT_PLAIN)
|
||||
.body(String::from("Be happy with async!"))
|
||||
.unwrap();
|
||||
|
||||
let creds = Credentials::new("smtp_username".to_owned(), "smtp_password".to_owned());
|
||||
|
||||
// Open a remote connection to gmail
|
||||
let mailer: AsyncSmtpTransport<Tokio1Executor> =
|
||||
AsyncSmtpTransport::<Tokio1Executor>::relay("smtp.gmail.com")
|
||||
.unwrap()
|
||||
.credentials(creds)
|
||||
.build();
|
||||
|
||||
Self {
|
||||
mailer,
|
||||
from: String::default(), // TODO: create settings module to read config
|
||||
to: String::default(),
|
||||
reply_to: String::default(),
|
||||
}
|
||||
|
||||
// Send the email
|
||||
// match mailer.send(email).await {
|
||||
// Ok(_) => println!("Email sent successfully!"),
|
||||
// Err(e) => panic!("Could not send email: {e:?}"),
|
||||
// };
|
||||
}
|
||||
}
|
5
src/identity/adapters/output/mailer/mod.rs
Normal file
5
src/identity/adapters/output/mailer/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
pub mod lettre;
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
pub mod db;
|
||||
pub mod mailer;
|
||||
|
|
Loading…
Reference in a new issue