diff --git a/visions/server/src/main.rs b/visions/server/src/main.rs index 1c7a6ff..5e2030f 100644 --- a/visions/server/src/main.rs +++ b/visions/server/src/main.rs @@ -92,17 +92,16 @@ struct UserOverview { } #[derive(Deserialize, Serialize)] -#[serde(tag = "type", content = "content", rename_all = "kebab-case")] #[typeshare] -enum AuthResponse { - Success(A), +enum AuthResponse { + Success(SessionId), PasswordReset(SessionId), } #[axum::debug_handler] async fn check_password( request: Json, -) -> (StatusCode, Json>>) { +) -> (StatusCode, Json>) { let Json(request) = request; if request.username == "vakarian" && request.password == "aoeu" { ( @@ -183,21 +182,20 @@ async fn main() { let app = Router::new() .route( "/api/test/health", - get(|| async { (StatusCode::OK, Json(None::)) }), - ) - .layer( - CorsLayer::new() - .allow_methods([Method::GET]) - .allow_origin(Any), + get(|| async { (StatusCode::OK, Json(None::)) }).layer( + CorsLayer::new() + .allow_methods([Method::GET]) + .allow_origin(Any), + ), ) .route( "/api/test/auth", - post(|req: Json| check_password(req)), - ) - .layer( - CorsLayer::new() - .allow_methods([Method::POST]) - .allow_origin(Any), + post(|req: Json| check_password(req)).layer( + CorsLayer::new() + .allow_methods([Method::POST]) + .allow_headers([CONTENT_TYPE]) + .allow_origin(Any), + ), ) .route( "/api/test/list-users", @@ -226,13 +224,13 @@ async fn main() { ]), ) }) - }), - ) - .layer( - CorsLayer::new() - .allow_headers([AUTHORIZATION]) - .allow_methods([Method::GET]) - .allow_origin(Any), + }) + .layer( + CorsLayer::new() + .allow_headers([AUTHORIZATION]) + .allow_methods([Method::GET]) + .allow_origin(Any), + ), ); let listener = tokio::net::TcpListener::bind("127.0.0.1:8001") .await diff --git a/visions/ui/Trunk.toml b/visions/ui/Trunk.toml new file mode 100644 index 0000000..4262060 --- /dev/null +++ b/visions/ui/Trunk.toml @@ -0,0 +1,3 @@ +[[proxy]] +backend = "http://localhost:8001/api" +insecure = true diff --git a/visions/ui/src/client.rs b/visions/ui/src/client.rs index 982140c..025df90 100644 --- a/visions/ui/src/client.rs +++ b/visions/ui/src/client.rs @@ -1,3 +1,6 @@ +use std::future::Future; + +use gloo_console::log; use gloo_net::http::{Request, Response}; use serde::{Deserialize, Serialize}; use wasm_bindgen_futures::wasm_bindgen::{self, JsValue}; @@ -9,15 +12,15 @@ struct AuthRequest { } #[derive(Deserialize)] -enum AuthResponse { - Ok(SessionId), +pub enum AuthResponse { + Success(SessionId), PasswordReset(SessionId), } #[derive(Deserialize)] -struct SessionId(String); +pub struct SessionId(pub String); -enum ClientError { +pub enum ClientError { Unauthorized, Err(u16), } @@ -31,9 +34,9 @@ struct UserInfo { name: String, } -trait Client { - async fn auth(username: String, password: String) -> Result; - async fn list_users(session_id: SessionId) -> Result, ClientError>; +pub trait Client { + fn auth(&self, username: String, password: String) -> impl Future>; + fn list_users(&self, session_id: SessionId) -> impl Future, ClientError>>; } pub struct Connection; @@ -43,9 +46,11 @@ impl Connection { } impl Client for Connection { - async fn auth(username: String, password: String) -> Result { - let response: Response = Request::post("http://localhost:8001") - .body(serde_wasm_bindgen::to_value(&AuthRequest{ username, password }).unwrap()) + async fn auth(&self, username: String, password: String) -> Result { + log!("authenticating: ", &username, &password); + let response: Response = Request::post("/api/test/auth") + .header("Content-Type", "application/json") + .body(serde_wasm_bindgen::to_value(&serde_json::to_string(&AuthRequest{ username, password }).unwrap()).unwrap()) .unwrap() .send() .await @@ -58,7 +63,7 @@ impl Client for Connection { } } - async fn list_users(session_id: SessionId) -> Result, ClientError> { + async fn list_users(&self, session_id: SessionId) -> Result, ClientError> { todo!() } } diff --git a/visions/ui/src/main.rs b/visions/ui/src/main.rs index e55da64..ac66b4f 100644 --- a/visions/ui/src/main.rs +++ b/visions/ui/src/main.rs @@ -27,6 +27,7 @@ impl Reducible for AuthInfo { type Action = AuthAction; fn reduce(self: Rc, action: Self::Action) -> Rc { + // log!("reduce", action); match action { AuthAction::Auth(session_id) => Self { session_id: Some(session_id), @@ -98,11 +99,25 @@ fn Login(LoginProps { on_login }: &LoginProps) -> Html { #[function_component] fn App() -> Html { let auth_info = use_reducer(AuthInfo::default); - let client = Connection::new(); let on_login = { let auth_info = auth_info.clone(); - Callback::from(move |(username, password)| auth_info.dispatch(AuthAction::Auth(username))) + Callback::from(move |(username, password)| { + let auth_info = auth_info.clone(); + wasm_bindgen_futures::spawn_local(async move { + let client = Connection::new(); + match client.auth(username, password).await { + Ok(AuthResponse::Success(session_id)) => { + auth_info.dispatch(AuthAction::Auth(session_id.0)) + } + Ok(AuthResponse::PasswordReset(session_id)) => { + auth_info.dispatch(AuthAction::Auth(session_id.0)) + } + Err(ClientError::Unauthorized) => todo!(), + Err(ClientError::Err(status)) => todo!(), + }; + }) + }) }; if auth_info.session_id.is_some() {