From d78de75c5ede52faddc39a2d7467ed0ae4a17bf2 Mon Sep 17 00:00:00 2001 From: AINDUSTRIES Date: Sat, 29 Aug 2026 18:06:05 +0200 Subject: [PATCH] Added update and reload actions for user settings --- src/main.rs | 14 +++++++---- src/users.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index cb47787..1fa6442 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,20 +2,21 @@ use std::env::var; use std::error::Error; use axum::http::{HeaderValue, Method}; -use axum::routing::get; +use axum::routing::{get, post}; use axum::{Router, serve}; use dotenvy::dotenv; +use http::header::CONTENT_TYPE; use sqlx::postgres::PgPool; use tokio::net::TcpListener; use tower_http::cors::CorsLayer; +use tower_sessions::SessionManagerLayer; use tower_sessions::cookie::SameSite; -use tower_sessions::{SessionManagerLayer}; use tower_sessions_sqlx_store::PostgresStore; use tower_sessions_sqlx_store::sqlx::PgPool as SessionPgPool; mod error; mod users; -use users::{login, me, logout}; +use users::{login, logout, me, reload, update}; #[tokio::main] async fn main() -> Result<(), Box> { @@ -33,11 +34,14 @@ async fn main() -> Result<(), Box> { .route("/me", get(me)) .route("/login", get(login)) .route("/logout", get(logout)) + .route("/update", post(update)) + .route("/reload", get(reload)) .layer( CorsLayer::new() .allow_origin("http://localhost:5173".parse::().unwrap()) - .allow_methods([Method::GET]) - .allow_credentials(true), + .allow_methods([Method::GET, Method::POST]) + .allow_credentials(true) + .allow_headers([CONTENT_TYPE]), ) .layer(session) .with_state(pool); diff --git a/src/users.rs b/src/users.rs index 1373764..55fceb4 100644 --- a/src/users.rs +++ b/src/users.rs @@ -5,6 +5,7 @@ use axum::{ extract::{Query, State}, }; use serde::{Deserialize, Serialize}; +use serde_json::Value; use sqlx::{PgPool, query, query_as, query_scalar, types::Uuid}; use tower_sessions::Session; @@ -88,10 +89,7 @@ impl User { return Ok(user); } - let response = reqwest::get(format!("https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=ABBFE30D7BDC1FD582DB1A2CEBD563B4&steamids={steamid}")) - .await?.bytes().await?; - let json: serde_json::Value = serde_json::from_slice(&response)?; - let raw_user = &json["response"]["players"][0]; + let raw_user = Self::fetch_steam(&steamid).await?; let mut user = User::new( raw_user["steamid"].to_string().trim_matches('"'), raw_user["personaname"].to_string().trim_matches('"'), @@ -100,6 +98,20 @@ impl User { user.create(pool).await?; Ok(user) } + + async fn fetch_steam(steamid: &String) -> Result> { + let response = reqwest::get(format!("https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=ABBFE30D7BDC1FD582DB1A2CEBD563B4&steamids={steamid}")) + .await?.bytes().await?; + let mut json: serde_json::Value = serde_json::from_slice(&response)?; + Ok(json["response"]["players"][0].take()) + } + + async fn update_from_steam(&mut self, pool: &PgPool) -> Result<(), Box> { + let raw_user = Self::fetch_steam(&self.steamid).await?; + self.name = raw_user["personaname"].to_string().trim_matches('"').into(); + self.avatar = raw_user["avatarfull"].to_string().trim_matches('"').into(); + self.update(pool).await + } } #[derive(Deserialize, Serialize)] @@ -158,7 +170,9 @@ pub async fn login( session: Session, ) -> Result<(), AppError> { if !info.is_valid().await? { - return Err(AppError::OpenIdError("Some query parameters are erronous or lacking.".into())); + return Err(AppError::OpenIdError( + "Some query parameters are erronous or lacking.".into(), + )); } let steamid = info .identity @@ -174,10 +188,7 @@ pub async fn logout(session: Session) -> Result<(), AppError> { } #[axum::debug_handler] -pub async fn me( - State(pool): State, - session: Session, -) -> Result, AppError> { +pub async fn me(State(pool): State, session: Session) -> Result, AppError> { if let Some(uuid) = session.get("uuid").await? { let user = User::fetch_id(&pool, uuid).await?; Ok(Json(user)) @@ -185,3 +196,43 @@ pub async fn me( Err(AppError::Unauthorised) } } + +#[derive(Deserialize)] +pub struct Settings { + username: String, + avatar: String, +} + +#[axum::debug_handler] +pub async fn update( + State(pool): State, + session: Session, + data: Json, +) -> Result<(), AppError> { + if let Some(uuid) = session.get("uuid").await? { + let mut user = User::fetch_id(&pool, uuid).await?; + + if !data.username.is_empty() { + user.name = data.username.clone(); + } + if !data.avatar.is_empty() { + user.avatar = data.avatar.clone(); + } + + user.update(&pool).await?; + + Ok(()) + } else { + Err(AppError::Unauthorised) + } +} + +pub async fn reload(State(pool): State, session: Session) -> Result<(), AppError> { + if let Some(uuid) = session.get("uuid").await? { + let mut user = User::fetch_id(&pool, uuid).await?; + user.update_from_steam(&pool).await?; + Ok(()) + } else { + Err(AppError::Unauthorised) + } +}