brass/web/src/endpoints/user/post_reset.rs

91 lines
2.7 KiB
Rust

use actix_web::{web, HttpResponse, Responder};
use maud::html;
use serde::Deserialize;
use sqlx::PgPool;
use crate::{
mail::Mailer,
models::{PasswordReset, User},
utils::{password_change::PasswordChangeBuilder, ApplicationError},
};
#[derive(Deserialize, Debug)]
struct ResetPasswordForm {
email: Option<String>,
token: Option<String>,
password: Option<String>,
passwordretyped: Option<String>,
dry: Option<bool>,
}
#[actix_web::post("/reset-password")]
async fn post(
form: web::Form<ResetPasswordForm>,
pool: web::Data<PgPool>,
mailer: web::Data<Mailer>,
) -> Result<impl Responder, ApplicationError> {
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().to_lowercase()).await
{
let reset = PasswordReset::insert_new_for_user(pool.get_ref(), user.id).await?;
mailer
.send_forgot_password_mail(&user, &reset.token)
.await?;
}
Ok(HttpResponse::Ok().body("E-Mail versandt!"))
} else if form.email.is_none()
&& form.token.is_some()
&& form.password.is_some()
&& form.passwordretyped.is_some()
{
// TODO: refactor into check if HX-TARGET = #password-strength exists
let is_dry = form.dry.is_some_and(|b| b);
let token = if let Some(token) =
PasswordReset::does_token_exist(pool.get_ref(), form.token.as_ref().unwrap()).await?
{
token
} else {
return Ok(HttpResponse::NoContent().finish());
};
let mut builder = PasswordChangeBuilder::<PasswordReset>::new(
pool.get_ref(),
token.userid,
&form.password.as_ref().unwrap(),
&form.passwordretyped.as_ref().unwrap(),
)
.with_token(token);
let change = builder.build();
let response = if is_dry {
change.validate_for_input().await?
} else {
change.validate().await?;
change.commit().await?;
HttpResponse::Ok().body(
html! {
div class="block mb-3" {
"Passwort erfolgreich geändert."
}
a class="block button is-primary" hx-boost="true" href="/login"{
"Zum Login"
}
}
.into_string(),
)
};
return Ok(response);
} else {
return Ok(HttpResponse::BadRequest().finish());
}
}