feat: finish reset password strength

This commit is contained in:
Max Hohlfeld 2024-08-23 20:47:56 +02:00
parent 0fd46e184b
commit a975ff7104
3 changed files with 30 additions and 17 deletions

View File

@ -15,7 +15,7 @@ use crate::{
utils::password_help, utils::password_help,
}; };
#[derive(Deserialize)] #[derive(Deserialize, Debug)]
struct ResetPasswordForm { struct ResetPasswordForm {
email: Option<String>, email: Option<String>,
token: Option<String>, token: Option<String>,
@ -87,6 +87,9 @@ Viele Grüße"##, user.name, reset_url))
&& form.password.is_some() && form.password.is_some()
&& form.passwordretyped.is_some() && form.passwordretyped.is_some()
{ {
let password = form.password.as_ref().unwrap();
let is_dry = form.dry.is_some_and(|b| b);
let token = let token =
PasswordReset::does_token_exist(pool.get_ref(), form.token.as_ref().unwrap()).await; PasswordReset::does_token_exist(pool.get_ref(), form.token.as_ref().unwrap()).await;
@ -94,22 +97,33 @@ Viele Grüße"##, user.name, reset_url))
return HttpResponse::BadRequest().body("Token existiert nicht bzw. ist abgelaufen!"); return HttpResponse::BadRequest().body("Token existiert nicht bzw. ist abgelaufen!");
} }
if password.chars().count() > 256 {
if is_dry {
return HttpResponse::BadRequest().body("<div id=\"password-strength\" class=\"mb-3 help content is-danger\">Password darf nicht länger als 256 Zeichen sein.</div>");
} else {
return HttpResponse::NoContent().finish();
}
}
let user = User::read_by_id(pool.get_ref(), token.as_ref().unwrap().id) let user = User::read_by_id(pool.get_ref(), token.as_ref().unwrap().id)
.await .await
.unwrap(); .unwrap();
let mut split_names: Vec<&str> = user.name.as_str().split_whitespace().collect(); let mut split_names: Vec<&str> = user.name.as_str().split_whitespace().collect();
let mut user_inputs = vec![user.email.as_str()]; let mut user_inputs = vec![user.email.as_str()];
user_inputs.append(&mut split_names); user_inputs.append(&mut split_names);
let entropy = zxcvbn(password, &user_inputs);
let entropy = zxcvbn(form.password.as_ref().unwrap(), &user_inputs);
if entropy.score() < Score::Three { if entropy.score() < Score::Three {
let message = password_help::generate_for_entropy(&entropy); if is_dry {
let message = password_help::generate_for_entropy(&entropy);
return HttpResponse::BadRequest().body(message); return HttpResponse::BadRequest().body(message);
} else {
return HttpResponse::NoContent().finish();
}
} }
if form.dry.is_some_and(|b| b) { if is_dry {
if entropy.score() == Score::Three { if entropy.score() == Score::Three {
return HttpResponse::Ok() return HttpResponse::Ok()
.body("<div id=\"password-strength\" class=\"mb-3 help content is-success\">Sicheres Passwort.</div>"); .body("<div id=\"password-strength\" class=\"mb-3 help content is-success\">Sicheres Passwort.</div>");
@ -119,7 +133,7 @@ Viele Grüße"##, user.name, reset_url))
} }
} }
if form.password.as_ref().unwrap() != form.passwordretyped.as_ref().unwrap() { if password != form.passwordretyped.as_ref().unwrap() {
return HttpResponse::BadRequest().body("Passwörter stimmen nicht überein!"); return HttpResponse::BadRequest().body("Passwörter stimmen nicht überein!");
} }

View File

@ -70,5 +70,5 @@ pub fn generate_for_entropy(entropy: &Entropy) -> String {
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(""); .join("");
format!("<div id=\"password-strength\" class=\"mb-3 help content is-danger\"><p>{warning}</p><p>{vorschlag_text}:<ul>{suggestion}</ul></p></div>") format!("<div id=\"password-strength\" class=\"mb-3 help content is-danger\"><p>{warning}</p>{vorschlag_text}:<ul>{suggestion}</ul></div>")
} }

View File

@ -5,7 +5,7 @@
<div class="container"> <div class="container">
<h1 class="title">Brass - Passwort zurücksetzen</h1> <h1 class="title">Brass - Passwort zurücksetzen</h1>
<form class="box" hx-post="/reset-password" hx-params="not dry" hx-target-400="#error-message-retype" <form class="box" hx-post="/reset-password" hx-params="not dry" hx-target-400="#error-message-retype"
hx-on:keyup="document.getElementById('error-message-retype').innerHTML = ''"> hx-on:input="document.getElementById('error-message-retype').innerHTML = ''">
<input type="hidden" name="token" value="{{ token }}" /> <input type="hidden" name="token" value="{{ token }}" />
<input type="hidden" name="dry" value="true" /> <input type="hidden" name="dry" value="true" />
@ -13,23 +13,22 @@
<div class="field"> <div class="field">
<label class="label" for="password">neues Passwort:</label> <label class="label" for="password">neues Passwort:</label>
<div class="control"> <div class="control">
<input class="input" hx-post="/reset-password?dry=true" hx-params="*" hx-trigger="keyup changed delay:1s" <input class="input" hx-post="/reset-password?dry=true" hx-params="*" hx-trigger="keyup changed delay:500ms"
hx-target="#password-strength" hx-target-400="#password-strength" placeholder="**********" name="password" type="password" required hx-target="#password-strength" hx-target-400="#password-strength" placeholder="**********" name="password"
hx-swap="outerHTML" hx-on:keyup="document.getElementById('password-strength').innerHTML = ''"> type="password" required hx-swap="outerHTML" maxlength=256
hx-on:input="document.getElementById('password-strength').innerHTML = ''">
</div> </div>
<div id="password-strength" class="mb-3 help content"></div>
</div> </div>
<div id="password-strength" class="mb-3 help content"></div>
<div class="field"> <div class="field">
<label class="label" for="passwordretyped">neues Passwort wiederholen:</label> <label class="label" for="passwordretyped">neues Passwort wiederholen:</label>
<div class="control"> <div class="control">
<input class="input" placeholder="**********" name="passwordretyped" type="password" max=256 required> <input class="input" placeholder="**********" name="passwordretyped" type="password" maxlength=256 required>
</div> </div>
<div id="error-message-retype" class="mb-3 help is-danger"></div>
</div> </div>
<div id="error-message-retype" class="mb-3 help is-danger"></div>
<div class="level"> <div class="level">
<input class="button is-primary level-left" type="submit" value="Passwort zurücksetzen" /> <input class="button is-primary level-left" type="submit" value="Passwort zurücksetzen" />
</div> </div>