diff --git a/assets/styles/theme.css b/assets/styles/theme.css index 6032a6a..a099eee 100644 --- a/assets/styles/theme.css +++ b/assets/styles/theme.css @@ -105,3 +105,7 @@ --fg-selected: #f8fafc; --bg-selected: #1a1a1a; } + +.error { + color: rgb(211, 56, 48); +} \ No newline at end of file diff --git a/src/backend/auth.rs b/src/backend/auth.rs new file mode 100644 index 0000000..770f9d7 --- /dev/null +++ b/src/backend/auth.rs @@ -0,0 +1,23 @@ +use dioxus::prelude::*; + +#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub struct User { + username: String, + password: String, +} + +#[server] +pub async fn login(username: String, password: String) -> Result { + let users = crate::backend::get_mongo::("users").await?; + + match users + .find_one(mongodb::bson::doc! { + "username": username, + "password": password, + }) + .await? + { + Some(v) => Ok(String::new()), + None => Err(ServerFnError::new(format!("Invalid credentials"))), + } +} diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 224f417..79f62c6 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,3 +1,5 @@ +pub mod auth; + use crate::components::server::Server; use dioxus::prelude::*; @@ -45,11 +47,6 @@ fn build_or_filter(input: &str, fields: &[&str]) -> mongodb::bson::Document { mongodb::bson::doc! { "$or": or_clauses } } -#[server] -pub async fn log_in(username: String, password: String) -> Result { - Ok(format!("{username}@{password}")) -} - #[server] pub async fn get_servers(search: String) -> Result, ServerFnError> { let servers = get_mongo::("servers").await?; diff --git a/src/login.rs b/src/login.rs index 288b617..3150020 100644 --- a/src/login.rs +++ b/src/login.rs @@ -8,6 +8,7 @@ const LOGIN_CSS: Asset = asset!("/assets/styles/login.css"); pub fn Login() -> Element { let username = use_signal(|| String::new()); let password = use_signal(|| String::new()); + let error: Signal> = use_signal(|| None); let is_disabled = { let username = username.clone(); @@ -18,16 +19,20 @@ pub fn Login() -> Element { let log_in = { let username = username.clone(); let password = password.clone(); + let mut error = error.clone(); move || async move { if username().is_empty() || password().is_empty() { return; } - match backend::log_in(username.read().clone(), password.read().clone()).await { + error.set(None); + match backend::auth::login(username.read().clone(), password.read().clone()).await { Ok(id) => { utils::set_cookie("session_id", &id); utils::redirect("/dashboard"); } - Err(_) => {} + Err(e) => error.set(Some( + e.to_string().replace("error running server function: ", ""), + )), } } }; @@ -68,6 +73,10 @@ pub fn Login() -> Element { } } + if let Some(e) = &*error.read() { + p { class: "error", "{e}" } + } + button { disabled: is_disabled(), onclick: move |_| log_in(), diff --git a/src/utils.rs b/src/utils.rs index 8caa3bd..c9fd497 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,3 @@ -use dioxus::prelude::use_navigator; use wasm_bindgen::JsCast; use web_sys::{window, HtmlDocument}; @@ -38,5 +37,5 @@ pub fn get_cookie(name: &str) -> Option { } pub fn redirect(target: &str) { - use_navigator().push(target); + web_sys::window().unwrap().location().set_href(target).unwrap(); }