brass/web/src/mail/forgot_password.rs

103 lines
2.4 KiB
Rust

use askama::Template;
use lettre::{
message::{Mailbox, MultiPart, SinglePart},
Address, AsyncTransport, Message,
};
use crate::utils::ApplicationError;
use brass_db::models::User;
use super::Mailer;
impl Mailer {
pub async fn send_forgot_password_mail(
&self,
user: &User,
token: &str,
) -> Result<(), ApplicationError> {
let message = build(&self.hostname, &user.name, &user.email, token)?;
self.transport.send(message).await?;
Ok(())
}
}
#[derive(Template)]
#[template(path = "emails/forgot_password.txt")]
struct ForgotPasswordMailTemplatePlain<'a> {
name: &'a str,
reset_url: &'a str,
}
#[derive(Template)]
#[template(path = "emails/forgot_password.html")]
struct ForgotPasswordMailTemplateHtml<'a> {
name: &'a str,
reset_url: &'a str,
}
fn build(
hostname: &str,
name: &str,
email: &str,
token: &str,
) -> Result<Message, ApplicationError> {
let reset_url = format!("https://{hostname}/reset-password?token={token}");
let plain = ForgotPasswordMailTemplatePlain {
name,
reset_url: &reset_url,
}
.to_string();
let html = ForgotPasswordMailTemplateHtml {
name,
reset_url: &reset_url,
}
.to_string();
let sender_mailbox = Mailbox::new(
Some("noreply".to_string()),
Address::new("noreply", hostname)?,
);
let message = Message::builder()
.from(sender_mailbox.clone())
.reply_to(sender_mailbox)
.to(Mailbox::new(Some(name.to_string()), email.parse()?))
.subject("Brass: Zurücksetzen des Passworts angefordert")
.multipart(
MultiPart::alternative()
.singlepart(SinglePart::plain(plain))
.singlepart(SinglePart::html(html)),
)
.unwrap();
Ok(message)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::utils::test_helper::assert_mail_snapshot;
use lettre::{transport::stub::StubTransport, Transport};
#[test]
fn build_mail_snapshot() {
let message = build(
"brasiwa-leipzig.de",
"Max Mustermann",
"max@example.com",
"123456789",
)
.unwrap();
let sender = StubTransport::new_ok();
sender.send(&message).unwrap();
let messages = sender.messages();
let (_, sent_message) = messages.first().unwrap();
assert_mail_snapshot!(sent_message);
}
}