refactor: create mail state and reword email
This commit is contained in:
parent
10df91adfe
commit
99b2fbafa0
6
.env
6
.env
@ -4,4 +4,10 @@
|
|||||||
DATABASE_URL=postgresql://max@localhost/brass
|
DATABASE_URL=postgresql://max@localhost/brass
|
||||||
# 64 byte long
|
# 64 byte long
|
||||||
SECRET_KEY="changeInProdOrHandAb11111111111111111111111111111111111111111111"
|
SECRET_KEY="changeInProdOrHandAb11111111111111111111111111111111111111111111"
|
||||||
|
HOSTNAME="localhost"
|
||||||
|
|
||||||
|
SMTP_SERVER="localhost"
|
||||||
|
SMTP_PORT="1025"
|
||||||
|
# SMTP_LOGIN=""
|
||||||
|
# SMTP_PASSWORD=""
|
||||||
|
SMTP_TLSTYPE="none"
|
||||||
|
@ -8,3 +8,4 @@
|
|||||||
|
|
||||||
## Useful stuff
|
## Useful stuff
|
||||||
- cargo-watch, cargo-add
|
- cargo-watch, cargo-add
|
||||||
|
- mailtutan
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
use actix_web::{web, HttpResponse, Responder};
|
use actix_web::{web, HttpResponse, Responder};
|
||||||
use lettre::{message::header::ContentType, Message, SmtpTransport, Transport};
|
use lettre::{
|
||||||
|
message::{header::ContentType, MultiPart, SinglePart},
|
||||||
|
Message, SmtpTransport, Transport,
|
||||||
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
@ -17,7 +22,11 @@ struct ResetPasswordForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::post("/reset-password")]
|
#[actix_web::post("/reset-password")]
|
||||||
async fn post(form: web::Form<ResetPasswordForm>, pool: web::Data<PgPool>) -> impl Responder {
|
async fn post(
|
||||||
|
form: web::Form<ResetPasswordForm>,
|
||||||
|
pool: web::Data<PgPool>,
|
||||||
|
mailer: web::Data<SmtpTransport>,
|
||||||
|
) -> impl Responder {
|
||||||
if form.email.is_some()
|
if form.email.is_some()
|
||||||
&& form.token.is_none()
|
&& form.token.is_none()
|
||||||
&& form.password.is_none()
|
&& form.password.is_none()
|
||||||
@ -28,35 +37,45 @@ async fn post(form: web::Form<ResetPasswordForm>, pool: web::Data<PgPool>) -> im
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// send email to user
|
let hostname = env::var("HOSTNAME").unwrap();
|
||||||
|
let reset_url = format!("https://{}/reset-password?token={}", hostname, reset.token);
|
||||||
|
|
||||||
let message = Message::builder()
|
let message = Message::builder()
|
||||||
.from("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
|
.from("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
|
||||||
.reply_to("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
|
.reply_to("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
|
||||||
.to(format!("{} <{}>", user.name, user.email).parse().unwrap())
|
.to(format!("{} <{}>", user.name, user.email).parse().unwrap())
|
||||||
.subject("Brass: Zurücksetzen des Passworts angefordert")
|
.subject("Brass: Zurücksetzen des Passworts angefordert")
|
||||||
.header(ContentType::TEXT_PLAIN)
|
.multipart(
|
||||||
.body(format!(r##"
|
MultiPart::alternative()
|
||||||
Hallo {},
|
.singlepart(
|
||||||
|
SinglePart::builder()
|
||||||
|
.header(ContentType::TEXT_PLAIN)
|
||||||
|
.body(format!(r##"Hallo {},
|
||||||
|
|
||||||
hier der Link zur Passwortzurücksetzung: https://brasiwa-leipzig.de/reset-password?token={}
|
du hast angefordert, dein Passwort zurückzusetzen. Kopiere dafür folgenden Link in deinen Browser:
|
||||||
Debug: http://localhost:8080/reset-password?token={}
|
|
||||||
|
|
||||||
Nur 24 Stunden gültig!
|
{}
|
||||||
Wenn du das nicht angefordert hast, dann hast du nichts weiter zu tun. Vielleicht solltest du deine Email bei haveibeenpawn checken!
|
|
||||||
|
|
||||||
Bitte nicht auf die E-Mail antworten.
|
Bitte beachte, dass der Link nur 24 Stunden gültig ist. Solltest du nichts angefordert haben, dann musst du nichts weiter tun.
|
||||||
|
|
||||||
Viele Grüße
|
Viele Grüße"##, user.name, reset_url))
|
||||||
"##, user.name, reset.token, reset.token))
|
)
|
||||||
|
.singlepart(
|
||||||
|
SinglePart::builder()
|
||||||
|
.header(ContentType::TEXT_HTML)
|
||||||
|
.body(format!(r##"<p>Hallo {},</p>
|
||||||
|
|
||||||
|
<p>du hast angefordert, dein Passwort zurückzusetzen. Klicke dafür <a href="{}" target="_blank">hier</a> oder kopiere folgenden Link in deinen Browser:</p>
|
||||||
|
|
||||||
|
<p>{}</p>
|
||||||
|
|
||||||
|
<p>Bitte beachte, dass der Link <b>nur 24 Stunden gültig</b> ist. Solltest du nichts angefordert haben, dann musst du nichts weiter tun.</p>
|
||||||
|
|
||||||
|
<p>Viele Grüße</p>"##, user.name, reset_url, reset_url))
|
||||||
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mailer = SmtpTransport::from_url("smtp://localhost:1025")
|
|
||||||
.unwrap()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
mailer.send(&message).unwrap();
|
mailer.send(&message).unwrap();
|
||||||
|
|
||||||
println!("{reset:?}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return HttpResponse::Ok().body("E-Mail versandt!");
|
return HttpResponse::Ok().body("E-Mail versandt!");
|
||||||
@ -91,7 +110,7 @@ async fn post(form: web::Form<ResetPasswordForm>, pool: web::Data<PgPool>) -> im
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -19,6 +19,7 @@ mod auth;
|
|||||||
mod endpoints;
|
mod endpoints;
|
||||||
mod models;
|
mod models;
|
||||||
mod middleware;
|
mod middleware;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
mod filters;
|
mod filters;
|
||||||
mod postgres_session_store;
|
mod postgres_session_store;
|
||||||
@ -75,6 +76,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;
|
let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;
|
||||||
|
let mailer = utils::email::get_mailer()?;
|
||||||
let secret_key = Key::from(env::var("SECRET_KEY")?.as_bytes());
|
let secret_key = Key::from(env::var("SECRET_KEY")?.as_bytes());
|
||||||
let store = SqlxPostgresqlSessionStore::from_pool(pool.clone().into());
|
let store = SqlxPostgresqlSessionStore::from_pool(pool.clone().into());
|
||||||
|
|
||||||
@ -121,6 +123,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(web::Data::new(pool.clone()))
|
.app_data(web::Data::new(pool.clone()))
|
||||||
|
.app_data(web::Data::new(mailer.clone()))
|
||||||
.configure(endpoints::init)
|
.configure(endpoints::init)
|
||||||
.wrap(middleware::RedirectToLogin)
|
.wrap(middleware::RedirectToLogin)
|
||||||
.wrap(middleware::LoadCurrentUser)
|
.wrap(middleware::LoadCurrentUser)
|
||||||
|
35
src/utils/email.rs
Normal file
35
src/utils/email.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
use lettre::{
|
||||||
|
transport::smtp::{authentication::Credentials, extension::ClientId},
|
||||||
|
SmtpTransport,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn get_mailer() -> anyhow::Result<SmtpTransport> {
|
||||||
|
let server = &env::var("SMTP_SERVER")?;
|
||||||
|
let port = &env::var("SMTP_PORT")?.parse()?;
|
||||||
|
let login = &env::var("SMTP_LOGIN")
|
||||||
|
.and_then(|x| Ok(Some(x)))
|
||||||
|
.unwrap_or(None);
|
||||||
|
let password = &env::var("SMTP_PASSWORD")
|
||||||
|
.and_then(|x| Ok(Some(x)))
|
||||||
|
.unwrap_or(None);
|
||||||
|
let tls_type = &env::var("SMTP_TLSTYPE")?;
|
||||||
|
let hostname = &env::var("HOSTNAME")?;
|
||||||
|
|
||||||
|
let mut builder = match tls_type.as_str() {
|
||||||
|
"starttls" => SmtpTransport::starttls_relay(server)?.port(*port),
|
||||||
|
"tls" => SmtpTransport::relay(server)?.port(*port),
|
||||||
|
_ => SmtpTransport::builder_dangerous(server).port(*port),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let (Some(login), Some(password)) = (login, password) {
|
||||||
|
builder = builder.credentials(Credentials::new(login.to_string(), password.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mailer = builder
|
||||||
|
.hello_name(ClientId::Domain(hostname.to_string()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Ok(mailer)
|
||||||
|
}
|
1
src/utils/mod.rs
Normal file
1
src/utils/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod email;
|
Loading…
x
Reference in New Issue
Block a user