107 lines
3.7 KiB
Rust
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();
|
|
}
|
|
}
|