From 9b4d0b7b32fd468c94598e5865c90357590f8f43 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 19 Sep 2026 18:14:01 -0400 Subject: [PATCH] Get back here later --- src/callers/login.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++ src/callers/mod.rs | 1 + src/repo/mod.rs | 22 +++++++++++ 3 files changed, 116 insertions(+) diff --git a/src/callers/login.rs b/src/callers/login.rs index c583d97..4f271b8 100644 --- a/src/callers/login.rs +++ b/src/callers/login.rs @@ -20,6 +20,25 @@ pub mod request { pub access_token: String, } } + + pub mod update_password { + use serde::{Deserialize, Serialize}; + + #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] + pub struct Request { + pub user_id: uuid::Uuid, + pub username: String, + pub current_password: String, + pub updated_password: String, + pub confirmed_password: String, + } + + impl Request { + pub fn is_valid(&self) -> bool { + !self.user_id.is_nil() || !self.username.is_empty() || !self.current_password.is_empty() || !self.updated_password.is_empty() || !self.confirmed_password.is_empty() + } + } + } } pub mod response { @@ -46,6 +65,16 @@ pub mod response { pub data: Vec, } } + + pub mod update_password { + use serde::{Deserialize, Serialize}; + + #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] + pub struct Response { + pub message: String, + pub data: Vec, + } + } } /// Module for login endpoints @@ -261,4 +290,68 @@ pub mod endpoint { (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) } } + + #[utoipa::path( + patch, + path = super::super::endpoints::UPDATE_PASSWORD, + request_body( + content = super::request::update_password::Request, + description = "Update user password", + content_type = "application/json" + ), + responses( + (status = 200, description = "Password updated successfully", body = super::response::update_password::Response), + (status = 400, description = "Failure", body = super::response::update_password::Response) + ) + )] + pub async fn update_password( + axum::Extension(pool): axum::Extension, + axum::Json(payload): axum::Json, + ) -> ( + axum::http::StatusCode, + axum::Json, + ) { + let mut response = super::response::update_password::Response::default(); + + if !payload.is_valid() { + response.message = "Invalid request".to_string(); + return (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)); + } + + match repo::user::get(&pool, &payload.username).await { + Ok(user) => { + if hashing::verify_password(&payload.current_password, user.password.clone()).unwrap() { + match repo::salt::get(&pool, &user.salt_id).await { + Ok(salt) => { + // Left off here + let updated_hashed_password = hashing::hash_password(&payload.updated_password, &salt).unwrap(); + + match repo::user::update_password(&pool, &user, &updated_hashed_password).await { + Ok(_) => { + response.message = "Successful".to_string(); + response.data.push(user.id); + (axum::http::StatusCode::OK, axum::Json(response)) + } + Err(err) => { + response.message = err.to_string(); + (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) + } + } + } + Err(err) => { + (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) + } + } + + } else { + // invalid + (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) + } + } + Err(err) => { + response.message = err.to_string(); + (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) + } + } + } } diff --git a/src/callers/mod.rs b/src/callers/mod.rs index f280a4f..512f720 100644 --- a/src/callers/mod.rs +++ b/src/callers/mod.rs @@ -7,6 +7,7 @@ pub mod endpoints { pub const REGISTER: &str = "/api/v2/register"; pub const DBTEST: &str = "/api/v2/test/db"; pub const LOGIN: &str = "/api/v2/login"; + pub const UPDATE_PASSWORD: &str = "/api/v2/user/password"; pub const SERVICE_LOGIN: &str = "/api/v2/service/login"; pub const REFRESH_TOKEN: &str = "/api/v2/token/refresh"; } diff --git a/src/repo/mod.rs b/src/repo/mod.rs index b127180..df5ac09 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -44,6 +44,28 @@ pub mod user { } } + pub async fn update_password(pool: &sqlx::PgPool, user: &simodels::user::User, password: &str) -> Result { + match sqlx::query( + r#" + UPDATE "user" SET password = $1 WHERE id = $2 + "# + ) + .bind(password) + .bind(user.id) + .execute(pool) + // .fetch_optional(pool) + .await { + Ok(r) => { + return if r.rows_affected() > 0 { + Ok(true) + } else { + Ok(false) + } + } + Err(err) => Err(err) + } + } + pub async fn update_last_login( pool: &sqlx::PgPool, user: &simodels::user::User,