From 062fbf6bbc776b75521ed76fc5b3ed43a4f04ecd Mon Sep 17 00:00:00 2001 From: xeovalyte Date: Wed, 2 Oct 2024 12:31:59 +0200 Subject: [PATCH] Added change password functionality --- src/components/settings.rs | 41 ++++++++++++++++++++++++++++++++++---- src/util/model/user.rs | 31 ++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/src/components/settings.rs b/src/components/settings.rs index e06a0c4..bc834fd 100644 --- a/src/components/settings.rs +++ b/src/components/settings.rs @@ -105,6 +105,16 @@ async fn change_email(new_email: String) -> Result<(), ServerFnError> { fn Password() -> Element { let mut is_open = use_signal(|| false); + let mut input_old_password = use_signal(|| "".to_string()); + let mut input_new_password = use_signal(|| "".to_string()); + let mut input_new_password_repeat = use_signal(|| "".to_string()); + + let submit = move |_| async move { + if let Ok(_) = change_password(input_old_password(), input_new_password()).await { + tracing::info!("User password changed"); + }; + }; + rsx! { div { class: "collapse collapse-arrow bg-base-200", @@ -117,7 +127,7 @@ fn Password() -> Element { div { class: "collapse-content", div { - class: "pl-2 space-y-3", + class: "pl-2 flex flex-col gap-3", label { class: "form-control w-full", div { @@ -125,8 +135,10 @@ fn Password() -> Element { span { class: "label-text", "Huidig wachtwoord" } } input { - r#type: "text", + r#type: "password", class: "input input-bordered w-full", + oninput: move |event| input_old_password.set(event.value()), + value: "{input_old_password}", } } label { @@ -136,8 +148,10 @@ fn Password() -> Element { span { class: "label-text", "Nieuw wachtwoord" } } input { - r#type: "text", + r#type: "password", class: "input input-bordered w-full", + oninput: move |event| input_new_password.set(event.value()), + value: "{input_new_password}", } } label { @@ -147,8 +161,18 @@ fn Password() -> Element { span { class: "label-text", "Herhaal nieuw wachtwoord" } } input { - r#type: "text", + r#type: "password", class: "input input-bordered w-full", + oninput: move |event| input_new_password_repeat.set(event.value()), + value: "{input_new_password_repeat}", + } + } + div { + class: "w-full flex mt-5", + button { + class: "ml-auto btn btn-primary", + onclick: submit, + "Opslaan", } } } @@ -156,3 +180,12 @@ fn Password() -> Element { }, } } + +#[server] +async fn change_password(old_password: String, new_password: String) -> Result<(), ServerFnError> { + let user = Session::fetch_current_user().await?; + + user.change_password(old_password, new_password).await?; + + Ok(()) +} diff --git a/src/util/model/user.rs b/src/util/model/user.rs index 4e0f379..7e9dc07 100644 --- a/src/util/model/user.rs +++ b/src/util/model/user.rs @@ -75,4 +75,35 @@ impl User { None => Err(crate::Error::NoDocument), } } + + pub async fn change_password( + &self, + old_password: String, + new_password: String, + ) -> Result<(), crate::Error> { + let mut res = DB + .query( + " + LET $user = (SELECT * FROM ONLY type::thing('user', $user_id)); + + IF crypto::argon2::compare($user.password, $old_password) { + UPDATE type::thing('user', $user_id) SET password = crypto::argon2::generate($new_password) + } ELSE { + THROW 'Password dit not match' + }; + ", + ) + .bind(("user_id", self.id.to_string())) + .bind(("old_password", old_password)) + .bind(("new_password", new_password)) + .await?; + + tracing::info!("{res:?}"); + + if res.take_errors().len() != 0 { + return Err(crate::Error::NoDocument); + } + + Ok(()) + } }