diff --git a/src-tauri/.sqlx/query-e0c9c94777473a4f505ce6b86eeed179571833f8ecb9a2d42d9e46f6fd7757ba.json b/src-tauri/.sqlx/query-e0c9c94777473a4f505ce6b86eeed179571833f8ecb9a2d42d9e46f6fd7757ba.json new file mode 100644 index 00000000..9bf1d248 --- /dev/null +++ b/src-tauri/.sqlx/query-e0c9c94777473a4f505ce6b86eeed179571833f8ecb9a2d42d9e46f6fd7757ba.json @@ -0,0 +1,44 @@ +{ + "db_name": "SQLite", + "query": "SELECT \n i.id, \n i.uuid, \n i.name, \n i.url,\n CASE WHEN EXISTS (\n SELECT c.id FROM connection c\n INNER JOIN location l ON l.id = c.location_id\n WHERE l.instance_id = i.id AND c.end IS NULL\n ) THEN true ELSE false END AS \"connected: _\"\n FROM instance i", + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int64" + }, + { + "name": "uuid", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "url", + "ordinal": 3, + "type_info": "Text" + }, + { + "name": "connected: _", + "ordinal": 4, + "type_info": "Null" + } + ], + "parameters": { + "Right": 0 + }, + "nullable": [ + true, + false, + false, + false, + null + ] + }, + "hash": "e0c9c94777473a4f505ce6b86eeed179571833f8ecb9a2d42d9e46f6fd7757ba" +} diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 83c887a6..64ec1d00 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -772,6 +772,7 @@ dependencies = [ "base64 0.21.4", "chrono", "dirs", + "local-ip-address", "prost", "prost-build", "serde", @@ -1987,6 +1988,18 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +[[package]] +name = "local-ip-address" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fefe707432eb6bd4704b3dacfc87aab269d56667ad05dcd6869534e8890e767" +dependencies = [ + "libc", + "neli", + "thiserror", + "windows-sys", +] + [[package]] name = "lock_api" version = "0.4.10" @@ -2156,6 +2169,31 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "neli" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43" +dependencies = [ + "byteorder", + "libc", + "log", + "neli-proc-macros", +] + +[[package]] +name = "neli-proc-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4" +dependencies = [ + "either", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", +] + [[package]] name = "netlink-packet-core" version = "0.7.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 1869ff1c..5a2e7866 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -33,6 +33,7 @@ prost = "0.11" tauri = { version = "1.4.1", features = [ "window-all", "system-tray"] } tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } +local-ip-address = "0.5.5" [features] # this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. diff --git a/src-tauri/src/appstate.rs b/src-tauri/src/appstate.rs index 31f1648b..daaa4a09 100644 --- a/src-tauri/src/appstate.rs +++ b/src-tauri/src/appstate.rs @@ -5,7 +5,7 @@ use crate::database::{Connection, DbPool}; #[derive(Default)] pub struct AppState { pub db: Mutex>, - pub active_connections: Vec, + pub active_connections: Mutex>, } impl AppState { pub fn get_pool(&self) -> DbPool { diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index f79647ae..e39e6672 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -1,9 +1,10 @@ use crate::{ - database::{models::instance::InstanceInfo, Instance, Location, WireguardKeys}, + database::{models::instance::InstanceInfo, Connection, Instance, Location, WireguardKeys}, error::Error, utils::setup_interface, AppState, }; +use local_ip_address::local_ip; use serde::{Deserialize, Serialize}; use tauri::State; use wireguard_rs::netlink::delete_interface; @@ -13,6 +14,13 @@ use wireguard_rs::netlink::delete_interface; pub async fn connect(location_id: i64, app_state: State<'_, AppState>) -> Result<(), Error> { if let Some(location) = Location::find_by_id(&app_state.get_pool(), location_id).await? { setup_interface(location, &app_state.get_pool()).await?; + let address = local_ip()?; + let connection = Connection::new(location_id, address.to_string()); + app_state + .active_connections + .lock() + .unwrap() + .push(connection); } Ok(()) } @@ -117,6 +125,8 @@ pub async fn all_instances(app_state: State<'_, AppState>) -> Result = app_state .active_connections + .lock() + .unwrap() .iter() .map(|connection| connection.location_id) .collect(); @@ -138,12 +148,44 @@ pub async fn all_instances(app_state: State<'_, AppState>) -> Result, -) -> Result, String> { - Location::find_by_instance_id(&app_state.get_pool(), instance_id) +) -> Result, String> { + let locations = Location::find_by_instance_id(&app_state.get_pool(), instance_id) .await - .map_err(|err| err.to_string()) + .map_err(|err| err.to_string())?; + let active_locations_ids: Vec = app_state + .active_connections + .lock() + .unwrap() + .iter() + .map(|con| con.location_id) + .collect(); + let mut location_info = vec![]; + for location in locations { + let info = LocationInfo { + id: location.id.unwrap(), + instance_id: location.instance_id, + name: location.name, + address: location.address, + endpoint: location.endpoint, + active: active_locations_ids.contains(&location.id.unwrap()), + }; + location_info.push(info); + } + + Ok(location_info) } diff --git a/src-tauri/src/database/models/connection.rs b/src-tauri/src/database/models/connection.rs index f7087b7d..0c2cb94b 100644 --- a/src-tauri/src/database/models/connection.rs +++ b/src-tauri/src/database/models/connection.rs @@ -1,4 +1,4 @@ -use chrono::NaiveDateTime; +use chrono::{NaiveDateTime, Utc}; use sqlx::{query, FromRow}; use crate::{database::DbPool, error::Error}; @@ -13,7 +13,8 @@ pub struct Connection { } impl Connection { - pub fn new(location_id: i64, connected_from: String, start: NaiveDateTime) -> Self { + pub fn new(location_id: i64, connected_from: String) -> Self { + let start = Utc::now().naive_utc(); // Get the current time as NaiveDateTime in UTC Connection { id: None, location_id, diff --git a/src-tauri/src/error.rs b/src-tauri/src/error.rs index 8e880d7c..453ac784 100644 --- a/src-tauri/src/error.rs +++ b/src-tauri/src/error.rs @@ -1,6 +1,7 @@ use std::net::AddrParseError; use base64; +use local_ip_address::Error as LocalIpError; use sqlx; use thiserror::Error; use wireguard_rs::{error::WireguardError, IpAddrParseError}; @@ -23,4 +24,6 @@ pub enum Error { IpAddrMask(#[from] IpAddrParseError), #[error("IP address/mask error")] AddrParse(#[from] AddrParseError), + #[error("Local Ip Error")] + LocalIpError(#[from] LocalIpError), }