diff --git a/crates/common/src/storage/types/user.rs b/crates/common/src/storage/types/user.rs index c26434f..d0539ec 100644 --- a/crates/common/src/storage/types/user.rs +++ b/crates/common/src/storage/types/user.rs @@ -84,7 +84,7 @@ impl User { CREATE type::thing('user', $id) SET email = $email, password = crypto::argon2::generate($password), - admin = $count < 1, // Changed from == 0 to < 1 + admin = $count < 1, anonymous = false, created_at = $created_at, updated_at = $updated_at, @@ -103,6 +103,24 @@ impl User { user.ok_or(AppError::Auth("User failed to create".into())) } + pub async fn patch_password( + email: &str, + password: &str, + db: &SurrealDbClient, + ) -> Result<(), AppError> { + db.client + .query( + "UPDATE user + SET password = crypto::argon2::generate($password) + WHERE email = $email", + ) + .bind(("email", email.to_owned())) + .bind(("password", password.to_owned())) + .await?; + + Ok(()) + } + pub async fn authenticate( email: String, password: String, diff --git a/crates/html-router/src/lib.rs b/crates/html-router/src/lib.rs index 4a09e7a..8989d96 100644 --- a/crates/html-router/src/lib.rs +++ b/crates/html-router/src/lib.rs @@ -18,7 +18,10 @@ use html_state::HtmlState; use middleware_analytics::analytics_middleware; use middleware_auth::require_auth; use routes::{ - account::{delete_account, set_api_key, show_account_page, update_timezone}, + account::{ + change_password, delete_account, set_api_key, show_account_page, show_change_password, + update_timezone, + }, admin_panel::{show_admin_panel, toggle_registration_status}, chat::{ message_response_stream::get_response_stream, new_chat_user_message, new_user_message, @@ -109,6 +112,10 @@ where .route("/toggle-registrations", patch(toggle_registration_status)) .route("/set-api-key", post(set_api_key)) .route("/update-timezone", patch(update_timezone)) + .route( + "/change-password", + get(show_change_password).patch(change_password), + ) .route("/delete-account", delete(delete_account)) .route_layer(from_fn_with_state(app_state.clone(), require_auth)); diff --git a/crates/html-router/src/routes/account.rs b/crates/html-router/src/routes/account.rs index 2e038ef..b77bc4e 100644 --- a/crates/html-router/src/routes/account.rs +++ b/crates/html-router/src/routes/account.rs @@ -104,3 +104,38 @@ pub async fn update_timezone( }, )) } + +pub async fn show_change_password( + RequireUser(_user): RequireUser, +) -> Result { + Ok(TemplateResponse::new_template( + "auth/change_password_form.html", + {}, + )) +} + +#[derive(Deserialize)] +pub struct NewPasswordForm { + old_password: String, + new_password: String, +} + +pub async fn change_password( + State(state): State, + RequireUser(user): RequireUser, + auth: AuthSessionType, + Form(form): Form, +) -> Result { + // Authenticate to make sure the password matches + let authenticated_user = User::authenticate(user.email, form.old_password, &state.db).await?; + + User::patch_password(&authenticated_user.email, &form.new_password, &state.db).await?; + + auth.cache_clear_user(user.id); + + Ok(TemplateResponse::new_partial( + "auth/account_settings.html", + "change_password_section", + {}, + )) +} diff --git a/templates/auth/account_settings.html b/templates/auth/account_settings.html index 9005e1b..11c493a 100644 --- a/templates/auth/account_settings.html +++ b/templates/auth/account_settings.html @@ -95,15 +95,17 @@ {% endblock %} -
+
- + {% endblock %}
+ \ No newline at end of file