diff --git a/Cargo.toml b/Cargo.toml index e2b68ae..9b917a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ tokio = { version = "1.37.0", features = ["rt", "rt-multi-thread", "macros"] } tower = "0.4.13" tower-http = { version = "0.5.2", features = [ "compression-full", + "cors", "fs", "trace", ] } diff --git a/chat_core/src/lib.rs b/chat_core/src/lib.rs index 8a7be84..965ea18 100644 --- a/chat_core/src/lib.rs +++ b/chat_core/src/lib.rs @@ -10,9 +10,12 @@ pub use utils::*; use utoipa::ToSchema; #[derive(Debug, Clone, FromRow, ToSchema, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] pub struct User { pub id: i64, pub ws_id: i64, + #[sqlx(default)] + pub ws_name: String, pub fullname: String, pub email: String, #[sqlx(default)] @@ -71,6 +74,7 @@ impl User { Self { id, ws_id: 0, + ws_name: "".to_string(), fullname: fullname.to_string(), email: email.to_string(), password_hash: None, diff --git a/chat_server/src/lib.rs b/chat_server/src/lib.rs index 916ce22..dbc9a1a 100644 --- a/chat_server/src/lib.rs +++ b/chat_server/src/lib.rs @@ -16,11 +16,13 @@ use openapi::OpenApiRouter; use sqlx::PgPool; use std::{fmt, ops::Deref, sync::Arc}; use tokio::fs; +use tower_http::cors::{self, CorsLayer}; pub use error::{AppError, ErrorOutput}; pub use models::*; use axum::{ + http::Method, middleware::from_fn_with_state, routing::{get, post}, Router, @@ -54,6 +56,17 @@ pub async fn get_router(state: AppState) -> Result { .layer(from_fn_with_state(state.clone(), verify_chat)) .route("/", get(list_chat_handler).post(create_chat_handler)); + let cors = CorsLayer::new() + // allow `GET` and `POST` when accessing the resource + .allow_methods([ + Method::GET, + Method::POST, + Method::PATCH, + Method::DELETE, + Method::PUT, + ]) + .allow_origin(cors::Any) + .allow_headers(cors::Any); let api = Router::new() .route("/users", get(list_chat_users_handler)) .nest("/chats", chat) @@ -62,7 +75,8 @@ pub async fn get_router(state: AppState) -> Result { .layer(from_fn_with_state(state.clone(), verify_token::)) // routes doesn't need token verification .route("/signin", post(signin_handler)) - .route("/signup", post(signup_handler)); + .route("/signup", post(signup_handler)) + .layer(cors); let app = Router::new() .openapi() diff --git a/chat_server/src/models/user.rs b/chat_server/src/models/user.rs index 92b3d8d..ff602da 100644 --- a/chat_server/src/models/user.rs +++ b/chat_server/src/models/user.rs @@ -67,7 +67,7 @@ impl AppState { }; let password_hash = hash_password(&input.password)?; - let user: User = sqlx::query_as( + let mut user: User = sqlx::query_as( r#" INSERT INTO users (ws_id, email, fullname, password_hash) VALUES ($1, $2, $3, $4) @@ -81,6 +81,8 @@ impl AppState { .fetch_one(&self.pool) .await?; + user.ws_name = ws.name.clone(); + if ws.owner_id == 0 { self.update_workspace_owner(ws.id as _, user.id as _) .await?; @@ -103,6 +105,9 @@ impl AppState { let is_valid = verify_password(&input.password, &password_hash.unwrap_or_default())?; if is_valid { + // load ws_name, ws should exist + let ws = self.find_workspace_by_id(user.ws_id as _).await?.unwrap(); + user.ws_name = ws.name; Ok(Some(user)) } else { Ok(None)