sessions
This commit is contained in:
+43
-2
@@ -6,9 +6,14 @@ pub struct User {
|
||||
password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Session {
|
||||
uuid: String,
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn login(username: String, password: String) -> Result<String, ServerFnError> {
|
||||
let users = crate::backend::get_mongo::<User>("users").await?;
|
||||
let users = crate::backend::get_mongo::<mongodb::bson::Document>("users").await?;
|
||||
|
||||
match users
|
||||
.find_one(mongodb::bson::doc! {
|
||||
@@ -17,7 +22,43 @@ pub async fn login(username: String, password: String) -> Result<String, ServerF
|
||||
})
|
||||
.await?
|
||||
{
|
||||
Some(v) => Ok(String::new()),
|
||||
Some(v) => {
|
||||
let sessions = crate::backend::get_mongo::<Session>("sessions").await?;
|
||||
if let mongodb::bson::Bson::ObjectId(id) = sessions
|
||||
.insert_one(Session {
|
||||
uuid: v.get_object_id("_id")?.to_hex(),
|
||||
})
|
||||
.await?
|
||||
.inserted_id
|
||||
{
|
||||
Ok(id.to_hex())
|
||||
} else {
|
||||
Err(ServerFnError::new(format!("Unable to extract session id")))
|
||||
}
|
||||
}
|
||||
None => Err(ServerFnError::new(format!("Invalid credentials"))),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub async fn validate_session(id: String) -> bool {
|
||||
use mongodb::bson::oid::ObjectId;
|
||||
|
||||
if let Ok(sessions) = crate::backend::get_mongo::<Session>("sessions").await {
|
||||
if let Some(obj_id) = ObjectId::parse_str(id).ok() {
|
||||
match sessions
|
||||
.find_one(mongodb::bson::doc! {
|
||||
"_id": obj_id,
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(Some(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -48,7 +48,11 @@ fn build_or_filter(input: &str, fields: &[&str]) -> mongodb::bson::Document {
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn get_servers(search: String) -> Result<Vec<Server>, ServerFnError> {
|
||||
pub async fn get_servers(session: String, search: String) -> Result<Vec<Server>, ServerFnError> {
|
||||
if !auth::validate_session(session).await {
|
||||
return Err(ServerFnError::new(format!("Invalid session")));
|
||||
}
|
||||
|
||||
let servers = get_mongo::<Server>("servers").await?;
|
||||
|
||||
let filter = if search.trim().is_empty() {
|
||||
@@ -57,7 +61,6 @@ pub async fn get_servers(search: String) -> Result<Vec<Server>, ServerFnError> {
|
||||
build_or_filter(&search, &["name", "ip"])
|
||||
};
|
||||
|
||||
|
||||
let mut cursor = servers.find(filter).await?;
|
||||
|
||||
let mut svo = Vec::new();
|
||||
|
||||
+4
-30
@@ -1,26 +1,14 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
use crate::{
|
||||
backend,
|
||||
components::{server::ServerComponent, sidebar::SideBar, LineChart, ProgressBar},
|
||||
};
|
||||
use crate::components::{server::ServerComponent, sidebar::SideBar, LineChart, ProgressBar};
|
||||
use lucide_dioxus;
|
||||
|
||||
const DASHBOARD_CSS: Asset = asset!("/assets/styles/dashboard.css");
|
||||
|
||||
#[component]
|
||||
pub fn Dashboard() -> Element {
|
||||
let mut servers = use_signal(|| Vec::new());
|
||||
let server_search = use_signal(|| String::new());
|
||||
let session_id = crate::utils::use_cookie::<String>("session_id", || "Guest".to_string());
|
||||
|
||||
use_effect(move || {
|
||||
spawn(async move {
|
||||
if let Ok(v) = backend::get_servers(String::new()).await {
|
||||
servers.set(v);
|
||||
}
|
||||
});
|
||||
});
|
||||
let session = crate::utils::use_session();
|
||||
let (servers, server_query) = session.use_servers();
|
||||
|
||||
rsx! {
|
||||
document::Link { rel: "stylesheet", href: DASHBOARD_CSS }
|
||||
@@ -106,21 +94,7 @@ pub fn Dashboard() -> Element {
|
||||
div { class: "search-input",
|
||||
lucide_dioxus::Search { size: 16, color: "currentColor" }
|
||||
input {
|
||||
onchange: {let mut server_search = server_search.clone(); move |e: Event<FormData>| {server_search.set(e.value())}},
|
||||
onkeypress: {
|
||||
let server_search = server_search.clone();
|
||||
let mut servers = servers.clone();
|
||||
move |e: Event<KeyboardData>| {
|
||||
let query = (*server_search.read()).clone();
|
||||
async move {
|
||||
if e.key() == Key::Enter {
|
||||
if let Ok(v) = backend::get_servers(query).await {
|
||||
servers.set(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onchange: {let mut server_query = server_query.clone(); move |e: Event<FormData>| {server_query.set(e.value())}},
|
||||
|
||||
placeholder: "Search servers by name, location, or IP..." }
|
||||
}
|
||||
|
||||
+30
-4
@@ -3,6 +3,8 @@ use std::str::FromStr;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{window, HtmlDocument};
|
||||
|
||||
use crate::{backend, components::server::Server};
|
||||
|
||||
pub fn set_cookie(name: &str, value: &str) {
|
||||
let Some(document) = window().and_then(|w| w.document()) else {
|
||||
return;
|
||||
@@ -38,10 +40,7 @@ pub fn get_cookie(name: &str) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn use_cookie<T: FromStr + Default + std::fmt::Display + 'static>(
|
||||
name: &str,
|
||||
default: fn() -> T,
|
||||
) -> Signal<T> {
|
||||
pub fn use_cookie<T: FromStr + 'static>(name: &str, default: fn() -> T) -> Signal<T> {
|
||||
let name = name.to_string();
|
||||
let signal = use_signal(default);
|
||||
|
||||
@@ -66,3 +65,30 @@ pub fn redirect(target: &str) {
|
||||
.set_href(target)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub struct Session(Signal<String>);
|
||||
|
||||
pub fn use_session() -> Session {
|
||||
Session(use_cookie("session_id", || String::new()))
|
||||
}
|
||||
|
||||
impl Session {
|
||||
pub fn use_servers(&self) -> (Signal<Vec<Server>>, Signal<String>) {
|
||||
let query = use_signal(|| String::new());
|
||||
let servers = use_signal(|| Vec::new());
|
||||
let id = self.0.clone();
|
||||
|
||||
use_effect(move || {
|
||||
let query_value = query.read().clone();
|
||||
let mut servers = servers.clone();
|
||||
|
||||
spawn(async move {
|
||||
if let Ok(v) = backend::get_servers(id.read().clone(), query_value).await {
|
||||
servers.set(v);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
(servers, query)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user