feat: update profile change password request

This commit is contained in:
Max Hohlfeld 2024-10-17 16:56:02 +02:00
parent 77a71787bd
commit bbc23c39a8
8 changed files with 646 additions and 536 deletions

1016
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
## Example Deployment OpenBSD
```
#!/bin/ksh
daemon="/usr/local/bin/brass"
@ -26,8 +26,10 @@ daemon_logger="daemon.info"
rc_bg=YES
rc_reload=NO
```
```
# Postgres
# DATABASE_URL=postgres://postgres@localhost/my_database
# SQLite
@ -43,3 +45,4 @@ SMTP_PORT="25"
# SMTP_LOGIN=""
# SMTP_PASSWORD=""
SMTP_TLSTYPE="none"
```

View File

@ -1,45 +1,16 @@
use actix_web::{HttpRequest, HttpResponse, Responder};
use actix_web::{web, Responder};
use askama::Template;
use askama_actix::TemplateToResponse;
use crate::models::User;
#[derive(Template)]
#[template(path = "user/profile_change_password.html")]
struct ProfileChangePasswordTemplate {}
#[actix_web::get("/users/changepassword")]
pub async fn get(request: HttpRequest) -> impl Responder {
if let Some(_) = request.headers().get("HX-Request") {
return HttpResponse::Ok().body(r##"
<div class="field">
<div class="control">
<a href="/profile" hx-boost="true" class="button is-link is-light">Schließen</a>
</div>
</div>
<form class="box" hx-post="/users/changepassword" hx-target-400="#error-message" hx-on:change="document.getElementById('error-message').innerHTML = ''">
pub async fn get(_user: web::ReqData<User>) -> impl Responder {
let template = ProfileChangePasswordTemplate {};
<div class="field">
<label class="label" for="currentpassword">aktuelles Passwort:</label>
<div class="control">
<input class="input" placeholder="**********" name="currentpassword" type="password" required>
</div>
</div>
<div class="field">
<label class="label" for="password">neues Passwort:</label>
<div class="control">
<input class="input" placeholder="**********" name="password" type="password" required>
</div>
</div>
<div class="field">
<label class="label" for="passwordretyped">neues Passwort wiederholen:</label>
<div class="control">
<input class="input" placeholder="**********" name="passwordretyped" type="password" required>
</div>
</div>
<div id="error-message" class="mb-3 help is-danger"></div>
<div class="level">
<input class="button is-primary level-left" type="submit" value="Passwort ändern" />
</div>
</form>
"##);
}
HttpResponse::NotFound().finish()
template.to_response()
}

View File

@ -1,14 +1,19 @@
use actix_web::{web, HttpResponse, Responder};
use actix_web::{web, Responder};
use serde::Deserialize;
use sqlx::PgPool;
use crate::{auth::utils, models::User};
use crate::{
endpoints::user::handle_password_change_request,
models::{NoneToken, User},
utils::ApplicationError,
};
#[derive(Deserialize)]
struct ChangePasswordForm {
currentpassword: String,
password: String,
passwordretyped: String,
dry: Option<bool>,
}
#[actix_web::post("/users/changepassword")]
@ -16,39 +21,20 @@ async fn post(
user: web::ReqData<User>,
form: web::Form<ChangePasswordForm>,
pool: web::Data<PgPool>,
) -> impl Responder {
// TODO: hier weiter gleichziehen mit post reset und post register
if user.password.as_ref().is_some_and(|p|
p == &utils::hash_plain_password_with_salt(
&form.currentpassword,
user.salt.as_ref().unwrap(),
)
.unwrap()
) {
if form.password != form.passwordretyped {
return HttpResponse::BadRequest().body("Passwörter stimmen nicht überein!");
}
) -> Result<impl Responder, ApplicationError> {
// TODO: refactor into check if HX-TARGET = #password-strength exists
let is_dry = form.dry.unwrap_or(false);
let (hash, salt) = utils::generate_salt_and_hash_plain_password(&form.password).unwrap();
let response = handle_password_change_request(
pool.get_ref(),
None::<&NoneToken>,
user.id,
&form.password,
&form.passwordretyped,
Some(&form.currentpassword),
is_dry,
)
.await?;
User::update(
pool.get_ref(),
user.id,
None,
None,
Some(&hash),
Some(&salt),
None,
None,
None,
None,
None,
)
.await
.unwrap();
return HttpResponse::Ok().body(r#"<div class="block">Passwort wurde geändert.</div>"#);
} else {
return HttpResponse::BadRequest().body("Aktuelles Passwort ist nicht korrekt!");
}
return Ok(response);
}

View File

@ -18,7 +18,7 @@ pub use location::Location;
pub use role::Role;
pub use user::User;
pub use assignement::Assignment;
pub use password_reset::{PasswordReset, Token};
pub use password_reset::{PasswordReset, Token, NoneToken};
pub use registration::Registration;
type Result<T> = std::result::Result<T, sqlx::Error>;

View File

@ -8,6 +8,13 @@ pub trait Token {
async fn delete(&self, pool: &PgPool) -> Result<()>;
}
pub struct NoneToken {}
impl Token for NoneToken {
async fn delete(&self, pool: &PgPool) -> Result<()> {
unimplemented!()
}
}
#[derive(Debug)]
pub struct PasswordReset {
pub id: i32,

View File

@ -13,7 +13,7 @@
<div class="field">
<label class="label" for="password">{{ new_password_label }}</label>
<div class="control">
<input class="input" hx-post="{{ endpoint }}?dry=true" hx-params="*" hx-trigger="keyup changed delay:500ms"
<input class="input" hx-post="{{ endpoint }}" hx-params="*" hx-trigger="keyup changed delay:500ms"
hx-target="#password-strength" hx-target-400="#password-strength" placeholder="**********" name="password"
type="password" required hx-swap="outerHTML" maxlength=256
hx-on:input="document.getElementById('password-strength').innerHTML = ''">

View File

@ -0,0 +1,41 @@
<div class="field">
<div class="control">
<a href="/profile" hx-boost="true" class="button is-link is-light">Schließen</a>
</div>
</div>
<form class="box" hx-post="/users/changepassword" hx-params="not dry" hx-target-400="#error-message"
hx-on:change="document.getElementById('error-message').innerHTML = ''">
<input type="hidden" name="dry" value="true" />
<div class="field">
<label class="label" for="currentpassword">aktuelles Passwort:</label>
<div class="control">
<input class="input" placeholder="**********" name="currentpassword" type="password" required>
</div>
</div>
<div class="field">
<label class="label" for="password">neues Passwort:</label>
<div class="control">
<input class="input" hx-post="/users/changepassword" hx-params="*" hx-trigger="keyup changed delay:500ms"
hx-target="#password-strength" hx-target-400="#password-strength" placeholder="**********" name="password"
type="password" required hx-swap="outerHTML" maxlength=256
hx-on:input="document.getElementById('password-strength').innerHTML = ''">
</div>
<div id="password-strength" class="mb-3 help content"></div>
</div>
<div class="field">
<label class="label" for="passwordretyped">neues Passwort wiederholen:</label>
<div class="control">
<input class="input" placeholder="**********" name="passwordretyped" type="password" maxlength=256 required>
</div>
</div>
<div id="error-message" class="mb-3 help is-danger"></div>
<div class="level">
<input class="button is-primary level-left" type="submit" value="Passwort ändern" />
</div>
</form>