login system

This commit is contained in:
2025-07-14 20:27:18 +02:00
parent 2da5c1e9e2
commit 1cb0b44510
5 changed files with 41 additions and 9 deletions
+4
View File
@@ -105,3 +105,7 @@
--fg-selected: #f8fafc; --fg-selected: #f8fafc;
--bg-selected: #1a1a1a; --bg-selected: #1a1a1a;
} }
.error {
color: rgb(211, 56, 48);
}
+23
View File
@@ -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<String, ServerFnError> {
let users = crate::backend::get_mongo::<User>("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"))),
}
}
+2 -5
View File
@@ -1,3 +1,5 @@
pub mod auth;
use crate::components::server::Server; use crate::components::server::Server;
use dioxus::prelude::*; use dioxus::prelude::*;
@@ -45,11 +47,6 @@ fn build_or_filter(input: &str, fields: &[&str]) -> mongodb::bson::Document {
mongodb::bson::doc! { "$or": or_clauses } mongodb::bson::doc! { "$or": or_clauses }
} }
#[server]
pub async fn log_in(username: String, password: String) -> Result<String, ServerFnError> {
Ok(format!("{username}@{password}"))
}
#[server] #[server]
pub async fn get_servers(search: String) -> Result<Vec<Server>, ServerFnError> { pub async fn get_servers(search: String) -> Result<Vec<Server>, ServerFnError> {
let servers = get_mongo::<Server>("servers").await?; let servers = get_mongo::<Server>("servers").await?;
+11 -2
View File
@@ -8,6 +8,7 @@ const LOGIN_CSS: Asset = asset!("/assets/styles/login.css");
pub fn Login() -> Element { pub fn Login() -> Element {
let username = use_signal(|| String::new()); let username = use_signal(|| String::new());
let password = use_signal(|| String::new()); let password = use_signal(|| String::new());
let error: Signal<Option<String>> = use_signal(|| None);
let is_disabled = { let is_disabled = {
let username = username.clone(); let username = username.clone();
@@ -18,16 +19,20 @@ pub fn Login() -> Element {
let log_in = { let log_in = {
let username = username.clone(); let username = username.clone();
let password = password.clone(); let password = password.clone();
let mut error = error.clone();
move || async move { move || async move {
if username().is_empty() || password().is_empty() { if username().is_empty() || password().is_empty() {
return; 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) => { Ok(id) => {
utils::set_cookie("session_id", &id); utils::set_cookie("session_id", &id);
utils::redirect("/dashboard"); 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 { button {
disabled: is_disabled(), disabled: is_disabled(),
onclick: move |_| log_in(), onclick: move |_| log_in(),
+1 -2
View File
@@ -1,4 +1,3 @@
use dioxus::prelude::use_navigator;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use web_sys::{window, HtmlDocument}; use web_sys::{window, HtmlDocument};
@@ -38,5 +37,5 @@ pub fn get_cookie(name: &str) -> Option<String> {
} }
pub fn redirect(target: &str) { pub fn redirect(target: &str) {
use_navigator().push(target); web_sys::window().unwrap().location().set_href(target).unwrap();
} }