brass/src/endpoints/user/post_reset.rs

107 lines
3.7 KiB
Rust

use actix_web::{web, HttpResponse, Responder};
use lettre::{message::header::ContentType, transport::smtp::{authentication::Credentials, client::TlsParameters}, Message, SmtpTransport, Transport};
use serde::Deserialize;
use sqlx::PgPool;
use crate::{
auth,
models::{PasswordReset, User},
};
#[derive(Deserialize)]
struct ResetPasswordForm {
email: Option<String>,
token: Option<String>,
password: Option<String>,
passwordretyped: Option<String>,
}
#[actix_web::post("/reset-password")]
async fn post(form: web::Form<ResetPasswordForm>, pool: web::Data<PgPool>) -> impl Responder {
if form.email.is_some()
&& form.token.is_none()
&& form.password.is_none()
&& form.passwordretyped.is_none()
{
if let Ok(user) = User::read_for_login(pool.get_ref(), form.email.as_ref().unwrap()).await {
let reset = PasswordReset::insert_new_for_user(pool.get_ref(), user.id)
.await
.unwrap();
// send email to user
let message = Message::builder()
.from("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
.reply_to("noreply <noreply@brasiwa-leipzig.de>".parse().unwrap())
.to(format!("{} <{}>", user.name, user.email).parse().unwrap())
.subject("Brass: Zurücksetzen des Passworts angefordert")
.header(ContentType::TEXT_PLAIN)
.body(format!(r##"
Hallo {},
hier der Link zur Passwortzurücksetzung: https://brasiwa-leipzig.de/reset-password?token={}
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.
Viele Grüße
"##, user.name, reset.token, reset.token))
.unwrap();
let mailer = SmtpTransport::from_url("smtp://localhost:1025")
.unwrap()
.build();
mailer.send(&message).unwrap();
println!("{reset:?}");
}
return HttpResponse::Ok().body("E-Mail versandt!");
} else if form.email.is_none()
&& form.token.is_some()
&& form.password.is_some()
&& form.passwordretyped.is_some()
{
let token =
PasswordReset::does_token_exist(pool.get_ref(), form.token.as_ref().unwrap()).await;
if token.is_err() {
return HttpResponse::BadRequest().body("Token existiert nicht bzw. ist abgelaufen!");
}
if form.password.as_ref().unwrap() != form.passwordretyped.as_ref().unwrap() {
return HttpResponse::BadRequest().body("Passwörter stimmen nicht überein!");
}
let (hash, salt) =
auth::utils::generate_salt_and_hash_plain_password(form.password.as_ref().unwrap())
.unwrap();
User::update(
pool.get_ref(),
token.as_ref().unwrap().id,
None,
None,
Some(&hash),
Some(&salt),
None,
None,
None,
None,
)
.await
.unwrap();
PasswordReset::delete(pool.get_ref(), &token.unwrap().token)
.await
.unwrap();
return HttpResponse::Ok().body(r#"<div class="block">Passwort wurde geändert.</div><a class="block button is-primary" hx-boost="true" href="/login">Zum Login</a>"#);
} else {
return HttpResponse::BadRequest().finish();
}
}