From 9d43687f8b512a64cf0d5fee2926df8e72a11ea2 Mon Sep 17 00:00:00 2001 From: Alex Emmet Date: Sun, 7 Dec 2025 16:10:31 +0100 Subject: [PATCH] Swap to UNIX timestamps as user ID's --- src/auth/auth_connector.rs | 26 +--- src/auth/local_auth.rs | 3 +- src/communities/community.rs | 18 +-- src/communities/community_connection.rs | 46 ++---- src/communities/interactables/text_chat.rs | 9 +- src/data/communication.rs | 172 ++++++++++----------- src/gui/input_handler.rs | 16 +- src/langu/language_creator.rs | 1 + src/main.rs | 29 ++-- src/omikron/omikron_connection.rs | 119 +++++++------- src/server/api.rs | 4 +- src/users/contact.rs | 7 +- src/users/user_community_util.rs | 7 +- src/users/user_manager.rs | 8 +- src/users/user_profile.rs | 11 +- src/util/chat_files.rs | 13 +- src/util/chats_util.rs | 11 +- src/util/config_util.rs | 12 +- 18 files changed, 235 insertions(+), 277 deletions(-) diff --git a/src/auth/auth_connector.rs b/src/auth/auth_connector.rs index ecd6c63..24de38b 100644 --- a/src/auth/auth_connector.rs +++ b/src/auth/auth_connector.rs @@ -2,10 +2,10 @@ use crate::CONFIG; use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::users::user_profile::UserProfile; use json::JsonValue; +use json::number::Number; use reqwest::header::CONTENT_TYPE; use reqwest::{Client, Response}; use std::time::Duration; -use uuid::Uuid; #[derive(Debug, Clone)] pub struct AuthUser { pub created_at: i64, @@ -27,7 +27,7 @@ fn client() -> Client { .unwrap() } -pub async fn unregister_user(user_id: Uuid, reset_token: &str) -> Option { +pub async fn unregister_user(user_id: i64, reset_token: &str) -> Option { let url = format!("https:/auth.tensamin.net/api/delete/{}", user_id); let client = client(); @@ -46,19 +46,7 @@ pub async fn unregister_user(user_id: Uuid, reset_token: &str) -> Option { Option::from(cv.is_type(CommunicationType::success)) } -pub async fn get_uuid(username: &str) -> Option { - let url = format!("https://auth.tensamin.net/api/get/uuid/{}", username); - let client = client(); - let res = client.get(&url).send().await.ok()?; - let json = res.text().await.ok()?; - let cv = CommunicationValue::from_json(&json); - if !cv.is_type(CommunicationType::success) { - return None; - } - Uuid::parse_str(&*cv.get_data(DataTypes::user_id).unwrap().to_string()).ok() -} - -pub async fn get_user(user_id: Uuid) -> Option { +pub async fn get_user(user_id: i64) -> Option { let url = format!("https://auth.tensamin.net/api/get/{}", user_id); let client = client(); let res = client.get(&url).send().await.ok()?; @@ -97,14 +85,16 @@ pub async fn get_user(user_id: Uuid) -> Option { }) } -pub async fn get_register() -> Option { +pub async fn get_register() -> Option { let url = "https://auth.tensamin.net/api/register/init".to_string(); let client = client(); let res = client.get(&url).send().await.ok()?; let json = res.text().await.ok()?; let cv = CommunicationValue::from_json(&json); - Uuid::parse_str(&*cv.get_data(DataTypes::user_id).unwrap().to_string()).ok() + cv.get_data(DataTypes::user_id) + .unwrap_or(&json::JsonValue::Number(Number::from(0))) + .as_i64() } pub async fn complete_register(user_profile: &UserProfile, iota_id: &str) -> bool { @@ -112,7 +102,7 @@ pub async fn complete_register(user_profile: &UserProfile, iota_id: &str) -> boo let client = client(); let mut payload = JsonValue::new_object(); - payload["uuid"] = user_profile.user_id.to_string().into(); + payload["id"] = user_profile.user_id.into(); payload["public_key"] = user_profile.public_key.clone().into(); payload["private_key_hash"] = user_profile.private_key_hash.clone().into(); payload["username"] = user_profile.username.clone().into(); diff --git a/src/auth/local_auth.rs b/src/auth/local_auth.rs index cdc7adb..b5fbdf3 100644 --- a/src/auth/local_auth.rs +++ b/src/auth/local_auth.rs @@ -1,9 +1,8 @@ use json::JsonValue; -use uuid::Uuid; use crate::util::file_util::load_file; -pub fn is_private_key_valid(user_id: &Uuid, key_hash: &str) -> bool { +pub fn is_private_key_valid(user_id: &i64, key_hash: &str) -> bool { let file_contents = load_file("", "users.json"); let users = json::parse(&file_contents).unwrap(); diff --git a/src/communities/community.rs b/src/communities/community.rs index e171c37..b5dd693 100644 --- a/src/communities/community.rs +++ b/src/communities/community.rs @@ -33,7 +33,7 @@ pub struct Community { private_key: Secret, public_key: PublicKey, pub interactables: Arc>>>>, - pub connections: Arc>>>>, + pub connections: Arc>>>>, } impl Community { @@ -130,33 +130,33 @@ impl Community { .connections .read() .await - .get(&other.get_user_id().await.unwrap()) + .get(&other.get_user_id().await) .cloned() .unwrap_or_default(); vec.push(other.clone()); self.connections .write() .await - .insert(other.get_user_id().await.unwrap(), vec); + .insert(other.get_user_id().await, vec); } pub async fn remove_connection(self: &Arc, other: Arc) { let mut vec = self .connections .read() .await - .get(&other.get_user_id().await.unwrap()) + .get(&other.get_user_id().await) .cloned() .unwrap_or_default(); vec.retain(|conn| !Arc::ptr_eq(conn, &other)); self.connections .write() .await - .insert(other.get_user_id().await.unwrap(), vec); + .insert(other.get_user_id().await, vec); } - pub async fn get_connections(&self) -> HashMap>> { + pub async fn get_connections(&self) -> HashMap>> { self.connections.read().await.clone() } - pub async fn get_connections_for_user(&self, user_id: Uuid) -> Vec> { + pub async fn get_connections_for_user(&self, user_id: i64) -> Vec> { self.connections .read() .await @@ -166,7 +166,7 @@ impl Community { } pub async fn get_interactables( &self, - user_id: Uuid, + user_id: i64, ) -> Vec>> { self.interactables.read().await.clone() } @@ -191,7 +191,7 @@ impl Community { } pub async fn run_function( self: &mut Arc, - user_id: Uuid, + user_id: i64, name: &str, path: &str, function: &str, diff --git a/src/communities/community_connection.rs b/src/communities/community_connection.rs index 55e9bd8..798b909 100644 --- a/src/communities/community_connection.rs +++ b/src/communities/community_connection.rs @@ -12,6 +12,7 @@ use hkdf::Hkdf; use hyper::upgrade::Upgraded; use hyper_util::rt::TokioIo; use json::JsonValue; +use json::number::Number; use rand::{Rng, distributions::Alphanumeric}; use sha2::Sha256; use std::sync::Arc; @@ -24,7 +25,7 @@ use x448::PublicKey; pub struct CommunityConnection { pub sender: Arc>, Message>>>, pub receiver: Arc>>>>, - pub user_id: Arc>>, + pub user_id: Arc>, pub community: Arc>>>, identified: Arc>, challenged: Arc>, @@ -41,7 +42,7 @@ impl CommunityConnection { Arc::new(Self { sender: Arc::new(RwLock::new(sender)), receiver: Arc::new(RwLock::new(receiver)), - user_id: Arc::new(RwLock::new(None)), + user_id: Arc::new(RwLock::new(0)), community: Arc::new(RwLock::new(Some(community))), identified: Arc::new(RwLock::new(false)), challenged: Arc::new(RwLock::new(false)), @@ -58,7 +59,7 @@ impl CommunityConnection { pub async fn get_community(&self) -> Option> { self.community.read().await.clone() } - pub async fn get_user_id(&self) -> Option { + pub async fn get_user_id(&self) -> i64 { *self.user_id.read().await } pub async fn is_identified(&self) -> bool { @@ -67,9 +68,8 @@ impl CommunityConnection { pub async fn handle_message(self: Arc, message: String) { let mut cv = CommunicationValue::from_json(&message); - if let Some(user_id) = self.get_user_id().await { - cv = cv.with_sender(user_id); - } + let user_id = self.get_user_id().await; + cv = cv.with_sender(user_id); if cv.is_type(CommunicationType::identification) && !self.is_identified().await { self.handle_identification(cv).await; @@ -109,30 +109,17 @@ impl CommunityConnection { .get_community() .await .unwrap() - .run_function(self.get_user_id().await.unwrap(), name, path, function, &cv) + .run_function(self.get_user_id().await, name, path, function, &cv) .await; self.send_message(&result).await; } async fn handle_identification(&self, cv: CommunicationValue) { - let user_id = match cv.get_data(DataTypes::user_id) { - Some(id_str) => match Uuid::parse_str(&id_str.to_string()) { - Ok(id) => id, - Err(_) => { - self.send_error_response( - &cv.get_id(), - CommunicationType::error_invalid_user_id, - ) - .await; - return; - } - }, - None => { - self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id) - .await; - return; - } - }; + let user_id = cv + .get_data(DataTypes::user_id) + .unwrap_or(&JsonValue::Number(Number::from(0))) + .as_i64() + .unwrap_or(0); let Some(user) = get_user(user_id).await else { self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_user_id) @@ -145,7 +132,7 @@ impl CommunityConnection { *auth_guard = Some(user.clone()); let mut user_id_guard = self.user_id.write().await; - *user_id_guard = Some(user_id); + *user_id_guard = user_id; let mut identified_guard = self.identified.write().await; *identified_guard = true; @@ -347,11 +334,12 @@ impl CommunityConnection { }; let arc = Arc::new(community); - let Some(user_id) = self.get_user_id().await else { + let user_id = self.get_user_id().await; + if user_id == 0 { self.send_error_response(&cv.get_id(), CommunicationType::error) .await; return; - }; + } arc.add_connection(self.clone()).await; @@ -382,7 +370,7 @@ impl CommunityConnection { } pub async fn handle_close(self: Arc) { if self.is_identified().await { - if let Some(_) = self.get_user_id().await { + if self.get_user_id().await != 0 { self.community .read() .await diff --git a/src/communities/interactables/text_chat.rs b/src/communities/interactables/text_chat.rs index 2978876..fd11e2e 100644 --- a/src/communities/interactables/text_chat.rs +++ b/src/communities/interactables/text_chat.rs @@ -28,7 +28,7 @@ impl TextChat { community: Arc::new(Community::new()), } } - pub fn add_message(&self, send_time: u128, sender: Uuid, message: &str) { + pub fn add_message(&self, send_time: u128, sender: i64, message: &str) { let user_dir = &format!( "communities/{}/interactables/{}/{}", self.get_community().get_name(), @@ -211,12 +211,11 @@ impl Interactable for TextChat { .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_millis(); - self.add_message(milliseconds_timestamp, cv.get_sender().unwrap(), message); + self.add_message(milliseconds_timestamp, cv.get_sender(), message); let mut distribution_payload = JsonValue::new_object(); distribution_payload["message"] = JsonValue::String(message.to_string()); - distribution_payload["sender_id"] = - JsonValue::String(cv.get_sender().unwrap().to_string()); + distribution_payload["sender_id"] = JsonValue::String(cv.get_sender().to_string()); distribution_payload["send_time"] = JsonValue::String(milliseconds_timestamp.to_string()); let distribution = CommunicationValue::new(CommunicationType::update) @@ -226,7 +225,7 @@ impl Interactable for TextChat { .add_data_str(DataTypes::result, "message_live".to_string()) .add_data(DataTypes::payload, distribution_payload); - let connections: HashMap>> = + let connections: HashMap>> = self.get_community().get_connections().await.clone(); for con in connections.values() { diff --git a/src/data/communication.rs b/src/data/communication.rs index 26b5767..0620c36 100644 --- a/src/data/communication.rs +++ b/src/data/communication.rs @@ -1,7 +1,6 @@ use json::number::Number; use json::{Array, JsonValue, object, parse}; use std::collections::HashMap; -use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; use uuid::Uuid; @@ -36,10 +35,7 @@ pub enum DataTypes { shared_secret_sign, shared_secret, call_id, - call_name, - call_secret_sha, - call_secret, - shared_call_secret, + call_token, start_date, end_date, receiver_id, @@ -83,7 +79,6 @@ pub enum DataTypes { impl DataTypes { pub fn parse(p0: String) -> DataTypes { - // normalize: lowercase + remove underscores let normalized = p0.to_lowercase().replace('_', ""); match normalized.as_str() { @@ -114,10 +109,7 @@ impl DataTypes { "sharedsecretsign" => DataTypes::shared_secret_sign, "sharedsecret" => DataTypes::shared_secret, "callid" => DataTypes::call_id, - "callname" => DataTypes::call_name, - "callsecretsha" => DataTypes::call_secret_sha, - "callsecret" => DataTypes::call_secret, - "sharedcallsecret" => DataTypes::shared_call_secret, + "calltoken" => DataTypes::call_token, "startdate" => DataTypes::start_date, "enddate" => DataTypes::end_date, "receiverid" => DataTypes::receiver_id, @@ -172,6 +164,9 @@ pub enum CommunicationType { error_invalid_challenge, error_invalid_secret, error_invalid_private_key, + error_no_user_id, + error_no_call_id, + error_invalid_call_id, success, settings_save, settings_load, @@ -213,13 +208,11 @@ pub enum CommunicationType { start_stream, end_stream, watch_stream, - get_call, - new_call, + call_token, call_invite, end_call, function, update, - create_user, } impl CommunicationType { @@ -227,17 +220,32 @@ impl CommunicationType { let normalized = p0.to_lowercase().replace('_', ""); match normalized.as_str() { - "error" => CommunicationType::error, + "watchstream" => CommunicationType::watch_stream, + "calltoken" => CommunicationType::call_token, + "callinvite" => CommunicationType::call_invite, + "endcall" => CommunicationType::end_call, + "function" => CommunicationType::function, + "update" => CommunicationType::update, + "createuser" => CommunicationType::create_user, + "errorinvaliduserid" => CommunicationType::error_invalid_user_id, + "errornotfound" => CommunicationType::error_not_found, + "errornoiota" => CommunicationType::error_no_iota, + "errorinvalidchallenge" => CommunicationType::error_invalid_challenge, + "errorinvalidsecret" => CommunicationType::error_invalid_secret, + "errorinvalidprivatekey" => CommunicationType::error_invalid_private_key, + "errornouserid" => CommunicationType::error_no_user_id, + "errornocallid" => CommunicationType::error_no_call_id, + "errorinvalidcallid" => CommunicationType::error_invalid_call_id, + "success" => CommunicationType::success, "settingssave" => CommunicationType::settings_save, "settingsload" => CommunicationType::settings_load, "settingslist" => CommunicationType::settings_list, - "success" => CommunicationType::success, "message" => CommunicationType::message, + "messagesend" => CommunicationType::message_send, "messagelive" => CommunicationType::message_live, - "messageotheriota" => CommunicationType::message_other_iota, + "messageother_iota" => CommunicationType::message_other_iota, "messagechunk" => CommunicationType::message_chunk, "messagesget" => CommunicationType::messages_get, - "messagesend" => CommunicationType::message_send, "changeconfirm" => CommunicationType::change_confirm, "confirmreceive" => CommunicationType::confirm_receive, "confirmread" => CommunicationType::confirm_read, @@ -268,15 +276,7 @@ impl CommunicationType { "webrtcice" => CommunicationType::webrtc_ice, "startstream" => CommunicationType::start_stream, "endstream" => CommunicationType::end_stream, - "watchstream" => CommunicationType::watch_stream, - "getcall" => CommunicationType::get_call, - "newcall" => CommunicationType::new_call, - "callinvite" => CommunicationType::call_invite, - "endcall" => CommunicationType::end_call, - "function" => CommunicationType::function, - "update" => CommunicationType::update, - "createuser" => CommunicationType::create_user, _ => CommunicationType::error, } } @@ -286,8 +286,8 @@ impl CommunicationType { pub struct CommunicationValue { pub id: Uuid, pub comm_type: CommunicationType, - pub sender: Option, - pub receiver: Option, + pub sender: i64, + pub receiver: i64, pub data: HashMap, } @@ -297,8 +297,8 @@ impl CommunicationValue { Self { id: Uuid::new_v4(), comm_type, - sender: None, - receiver: None, + sender: 0, + receiver: 0, data: HashMap::new(), } } @@ -309,18 +309,18 @@ impl CommunicationValue { pub fn get_id(&self) -> Uuid { self.id.clone() } - pub fn with_sender(mut self, sender: Uuid) -> Self { - self.sender = Some(sender); + pub fn with_sender(mut self, sender: i64) -> Self { + self.sender = sender; self } - pub fn get_sender(&self) -> Option { + pub fn get_sender(&self) -> i64 { self.sender.clone() } - pub fn with_receiver(mut self, receiver: Uuid) -> Self { - self.receiver = Some(receiver); + pub fn with_receiver(mut self, receiver: i64) -> Self { + self.receiver = receiver; self } - pub fn get_receiver(&self) -> Option { + pub fn get_receiver(&self) -> i64 { self.receiver.clone() } pub fn add_data_num(mut self, key: DataTypes, value: Number) -> Self { @@ -351,26 +351,26 @@ impl CommunicationValue { for (k, v) in &self.data { jdata[&format!("{:?}", k)] = JsonValue::from(v.clone()); } - if self.sender.is_some() && self.receiver.is_some() { + if self.sender > 0 && self.receiver > 0 { object! { id: self.id.to_string(), type: format!("{:?}", self.comm_type), - sender: self.sender.unwrap().to_string(), - receiver: self.receiver.unwrap().to_string(), + sender: self.sender.to_string(), + receiver: self.receiver.to_string(), data: jdata } - } else if self.sender.is_some() { + } else if self.sender > 0 { object! { id: self.id.to_string(), type: format!("{:?}", self.comm_type), - sender: self.sender.unwrap().to_string(), + sender: self.sender.to_string(), data: jdata } - } else if self.receiver.is_some() { + } else if self.receiver > 0 { object! { id: self.id.to_string(), type: format!("{:?}", self.comm_type), - receiver: self.receiver.unwrap().to_string(), + receiver: self.receiver.to_string(), data: jdata } } else { @@ -383,53 +383,49 @@ impl CommunicationValue { } pub fn from_json(json_str: &str) -> Self { - let parsed = parse(json_str).unwrap(); - - let comm_type = CommunicationType::parse(parsed["type"].to_string()); - let mut sender: Option = None; - if parsed.has_key("sender") { - sender = Some( - parsed["sender"] - .as_str() - .and_then(|s| Uuid::parse_str(s).ok()) - .unwrap_or(Uuid::new_v4()), - ); - } - let mut receiver: Option = None; - if parsed.has_key("receiver") { - receiver = Some( - parsed["receiver"] - .as_str() - .and_then(|s| Uuid::parse_str(s).ok()) - .unwrap_or(Uuid::new_v4()), - ); - } - - let uuid = Uuid::parse_str(parsed["id"].as_str().unwrap_or("")).unwrap_or(Uuid::new_v4()); - let mut data = HashMap::new(); - if parsed["data"].is_object() { - for (k, v) in parsed["data"].entries() { - data.insert(DataTypes::parse(k.to_string()), v.clone()); + if let Ok(parsed) = parse(json_str) { + let comm_type = CommunicationType::parse(parsed["type"].to_string()); + let mut sender: i64 = 0; + if parsed.has_key("sender") { + sender = parsed["sender"].as_i64().unwrap_or(0); + } + let mut receiver: i64 = 0; + if parsed.has_key("receiver") { + receiver = parsed["receiver"].as_i64().unwrap_or(0); } - } - Self { - id: uuid, - comm_type, - sender, - receiver, - data, + let uuid = + Uuid::parse_str(parsed["id"].as_str().unwrap_or("")).unwrap_or(Uuid::new_v4()); + let mut data = HashMap::new(); + if parsed["data"].is_object() { + for (k, v) in parsed["data"].entries() { + data.insert(DataTypes::parse(k.to_string()), v.clone()); + } + } + + Self { + id: uuid, + comm_type, + sender, + receiver, + data, + } + } else { + Self { + id: Uuid::new_v4(), + comm_type: CommunicationType::error, + sender: 0, + receiver: 0, + data: HashMap::new(), + } } } pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue { - let receiver = Uuid::from_str( - &*original - .get_data(DataTypes::receiver_id) - .unwrap() - .to_string(), - ) - .ok() - .or(Option::from(Uuid::nil())); + let receiver = original + .get_data(DataTypes::receiver_id) + .unwrap_or(&JsonValue::Number(Number::from(0))) + .as_i64() + .unwrap_or(0); let now_ms = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -439,16 +435,16 @@ impl CommunicationValue { let sender = original.get_sender(); CommunicationValue::new(CommunicationType::message_other_iota) .with_id(original.get_id()) - .with_receiver(receiver.unwrap()) + .with_receiver(receiver) .add_data( DataTypes::receiver_id, - JsonValue::String(receiver.unwrap().to_string()), + JsonValue::Number(Number::from(receiver)), ) - .with_sender(sender.unwrap()) + .with_sender(sender) .add_data(DataTypes::send_time, JsonValue::String(now_ms.to_string())) .add_data( DataTypes::sender_id, - JsonValue::String(sender.unwrap().to_string()), + JsonValue::Number(Number::from(sender)), ) .add_data( DataTypes::content, diff --git a/src/gui/input_handler.rs b/src/gui/input_handler.rs index f811427..6528bdd 100644 --- a/src/gui/input_handler.rs +++ b/src/gui/input_handler.rs @@ -1,6 +1,7 @@ use crate::{ACTIVE_TASKS, RELOAD, SHUTDOWN, gui::tui::UNIQUE, util::config_util::CONFIG}; use crossterm::event::{Event, KeyCode, read}; use crossterm::event::{KeyEvent, KeyModifiers}; +use json::JsonValue; use tokio::{self}; pub fn setup_input_handler() { @@ -55,7 +56,10 @@ pub async fn handle_input(key: KeyEvent) { None => password, }; - CONFIG.write().await.change("password", password); + CONFIG + .write() + .await + .change("password", JsonValue::String(password.to_string())); CONFIG.write().await.update(); *UNIQUE.write().await = true; } @@ -66,7 +70,10 @@ pub async fn handle_input(key: KeyEvent) { }; let password = &format!("{}{}", password, c); - CONFIG.write().await.change("password", password); + CONFIG + .write() + .await + .change("password", JsonValue::String(password.to_string())); CONFIG.write().await.update(); *UNIQUE.write().await = true; } @@ -77,7 +84,10 @@ pub async fn handle_input(key: KeyEvent) { }; let password = &format!("{}{}", password, c); - CONFIG.write().await.change("password", password); + CONFIG + .write() + .await + .change("password", JsonValue::String(password.to_string())); CONFIG.write().await.update(); *UNIQUE.write().await = true; } diff --git a/src/langu/language_creator.rs b/src/langu/language_creator.rs index ca18603..1d9ce29 100644 --- a/src/langu/language_creator.rs +++ b/src/langu/language_creator.rs @@ -8,6 +8,7 @@ pub fn create_languages() -> Result<(), JsonError> { let mut general_texts = JsonValue::new_object(); let mut debug_messages = JsonValue::new_object(); + frontend_messages.insert("error", "An error occurred")?; // FRONTEND frontend_messages.insert("get_chats", "User {} is loading conversations")?; frontend_messages.insert("message_get", "User {} is loading messages")?; diff --git a/src/main.rs b/src/main.rs index 99b27f9..fe76679 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,14 @@ use json::JsonValue; +use json::number::Number; use json::{self}; use once_cell::sync::Lazy; use pnet::datalink::NetworkInterface; use std::sync::Arc; use std::sync::LazyLock; use std::sync::Mutex; +use std::time::{SystemTime, UNIX_EPOCH}; use tokio::sync::RwLock; use tokio::time::{Duration, sleep}; -use uuid::Uuid; mod auth; mod communities; @@ -72,10 +73,15 @@ async fn main() { // BASIC CONFIGURATION &CONFIG.write().await.load(); if !CONFIG.read().await.config.has_key("iota_id") { - CONFIG - .write() - .await - .change("iota_id", &Uuid::new_v4().to_string()); + CONFIG.write().await.change( + "iota_id", + JsonValue::Number(Number::from( + (SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as i64), + )), + ); CONFIG.write().await.update(); } @@ -96,15 +102,8 @@ async fn main() { sb = sb + ","; } log_message(format!( - "IOTA ID: {}-####-####-####-############", - CONFIG - .read() - .await - .get_iota_id() - .to_string() - .split("-") - .next() - .unwrap() + "IOTA ID: {}", + CONFIG.read().await.get_iota_id().to_string() )); log_message(format!("User IDS: {}", sb)); @@ -162,7 +161,7 @@ async fn main() { .add_data(DataTypes::user_ids, JsonValue::String(sb.to_string())) .add_data( DataTypes::iota_id, - JsonValue::String(CONFIG.read().await.get_iota_id().to_string()), + JsonValue::Number(Number::from(CONFIG.read().await.get_iota_id())), ) .to_json() .to_string() diff --git a/src/omikron/omikron_connection.rs b/src/omikron/omikron_connection.rs index 93dda89..fd527be 100644 --- a/src/omikron/omikron_connection.rs +++ b/src/omikron/omikron_connection.rs @@ -14,8 +14,8 @@ use futures_util::{SinkExt, StreamExt}; use hyper::upgrade::Upgraded; use hyper_util::rt::TokioIo; use json::JsonValue; +use json::number::Number; use std::collections::HashMap; -use std::str::FromStr; use std::sync::{Arc, LazyLock}; use std::time::{SystemTime, UNIX_EPOCH}; use tokio::sync::{Mutex, RwLock}; @@ -36,7 +36,7 @@ pub enum ConnectionVariant { #[derive(Clone)] pub struct OmikronConnection { pub variant: Arc>, - pub user_id: Arc>>, + pub user_id: Arc>, pub(crate) writer: Arc + Send + Unpin>>>>, waiting: Arc>>>, // waiting for responses @@ -50,7 +50,7 @@ impl OmikronConnection { pub fn new() -> Self { Self { variant: Arc::new(RwLock::new(ConnectionVariant::Omikron)), - user_id: Arc::new(RwLock::new(None)), + user_id: Arc::new(RwLock::new(0)), writer: Arc::new(Mutex::new(None)), waiting: Arc::new(Mutex::new(HashMap::new())), pingpong: Arc::new(Mutex::new(None)), @@ -65,7 +65,7 @@ impl OmikronConnection { ) -> Arc { let connection = Arc::new(Self { variant: Arc::new(RwLock::new(ConnectionVariant::ClientUnauthenticated)), - user_id: Arc::new(RwLock::new(None)), + user_id: Arc::new(RwLock::new(0)), writer: Arc::new(Mutex::new(Some(Box::new(writer) as Box + Send + Unpin>))), waiting: Arc::new(Mutex::new(HashMap::new())), @@ -143,8 +143,8 @@ impl OmikronConnection { pub async fn set_variant(self: &Arc, variant: ConnectionVariant) { *self.variant.write().await = variant; } - pub async fn set_user_id(self: &Arc, user_id: Uuid) { - *self.user_id.write().await = Some(user_id); + pub async fn set_user_id(self: &Arc, user_id: i64) { + *self.user_id.write().await = user_id; } /// Listener for all incoming messages @@ -193,36 +193,24 @@ impl OmikronConnection { if com == ConnectionVariant::ClientUnauthenticated { if cv.is_type(CommunicationType::identification) { // Extract user ID - let user_id = match cv.get_data(DataTypes::user_id) { - Some(id_str) => { - match Uuid::parse_str(&id_str.to_string()) { - Ok(id) => id, - Err(_) => { - sel_arc.send_message( - CommunicationValue::new(CommunicationType::error_invalid_user_id) - .with_id(cv.get_id()) - .to_json() - .to_string() - ) - .await; - return; - } - } - } - None => { - sel_arc - .send_message( - CommunicationValue::new( - CommunicationType::error_invalid_user_id, - ) - .with_id(cv.get_id()) - .to_json() - .to_string(), + let user_id: i64 = cv + .get_data(DataTypes::user_id) + .unwrap_or(&JsonValue::Null) + .as_i64() + .unwrap_or(0); + if user_id == 0 { + sel_arc + .send_message( + CommunicationValue::new( + CommunicationType::error_invalid_user_id, ) - .await; - return; - } - }; + .with_id(cv.get_id()) + .to_json() + .to_string(), + ) + .await; + return; + } // Validate private key if let Some(private_key_hash) = @@ -288,8 +276,8 @@ impl OmikronConnection { return; } if cv.is_type(CommunicationType::message_other_iota) { - let sender_id = &cv.get_sender().unwrap(); - let receiver_id = &cv.get_receiver().unwrap(); + let sender_id = &cv.get_sender(); + let receiver_id = &cv.get_receiver(); chat_files::add_message( cv.get_data(DataTypes::send_time) @@ -321,7 +309,7 @@ impl OmikronConnection { ) .add_data( DataTypes::sender_id, - JsonValue::String(cv.get_sender().unwrap().to_string()), + JsonValue::Number(Number::from(cv.get_sender())), ); Self::send_message_static( &writer.clone(), @@ -332,11 +320,12 @@ impl OmikronConnection { } if cv.is_type(CommunicationType::message_send) { - let my_id = cv.get_sender().unwrap(); - let other_id = Uuid::from_str( - &*cv.get_data(DataTypes::receiver_id).unwrap().to_string(), - ) - .unwrap(); + let my_id = cv.get_sender(); + let other_id = cv + .get_data(DataTypes::receiver_id) + .unwrap_or(&JsonValue::Null) + .as_i64() + .unwrap_or(0); chat_files::add_message( SystemTime::now() .duration_since(UNIX_EPOCH) @@ -365,11 +354,12 @@ impl OmikronConnection { } if cv.is_type(CommunicationType::messages_get) { - let my_id = cv.get_sender().unwrap(); - let partner_id = Uuid::from_str( - &*cv.get_data(DataTypes::user_id).unwrap().to_string(), - ) - .unwrap(); + let my_id = cv.get_sender(); + let partner_id = cv + .get_data(DataTypes::user_id) + .unwrap_or(&JsonValue::Null) + .as_i64() + .unwrap_or(0); let offset = cv .get_data(DataTypes::offset) .unwrap_or(&JsonValue::Null) @@ -398,7 +388,7 @@ impl OmikronConnection { } if cv.is_type(CommunicationType::get_chats) { - let user_id = cv.get_sender().unwrap(); + let user_id = cv.get_sender(); let users = get_users(user_id); let resp = CommunicationValue::new(CommunicationType::get_chats) .with_id(cv.get_id()) @@ -413,11 +403,12 @@ impl OmikronConnection { } if cv.is_type(CommunicationType::add_chat) { - let user_id = cv.get_sender().unwrap(); - let other_id = Uuid::from_str( - &*cv.get_data(DataTypes::user_id).unwrap().to_string(), - ) - .unwrap(); + let user_id = cv.get_sender(); + let other_id = cv + .get_data(DataTypes::user_id) + .unwrap_or(&JsonValue::Null) + .as_i64() + .unwrap_or(0); let mut contact = get_user(user_id, other_id).unwrap_or(Contact::new(other_id)); // needs ChatsUtil + Contact contact.set_last_message_at( @@ -440,7 +431,7 @@ impl OmikronConnection { if cv.is_type(CommunicationType::add_community) { UserCommunityUtil::add_community( - cv.get_sender().unwrap(), + cv.get_sender(), cv.get_data(DataTypes::community_address) .unwrap() .to_string(), @@ -450,7 +441,7 @@ impl OmikronConnection { let resp = CommunicationValue::new(CommunicationType::add_community) .with_id(cv.get_id()) - .with_receiver(cv.get_sender().unwrap()); + .with_receiver(cv.get_sender()); Self::send_message_static( &writer.clone(), resp.to_json().to_string(), @@ -463,12 +454,10 @@ impl OmikronConnection { let resp = CommunicationValue::new(CommunicationType::get_communities) .with_id(cv.get_id()) - .with_receiver(cv.get_sender().unwrap()) + .with_receiver(cv.get_sender()) .add_array( DataTypes::communities, - UserCommunityUtil::get_communities( - cv.get_sender().unwrap(), - ), + UserCommunityUtil::get_communities(cv.get_sender()), ); Self::send_message_static( &writer.clone(), @@ -480,7 +469,7 @@ impl OmikronConnection { if cv.is_type(CommunicationType::remove_community) { UserCommunityUtil::remove_community( - cv.get_sender().unwrap(), + cv.get_sender(), cv.get_data(DataTypes::community_address) .unwrap() .to_string(), @@ -488,7 +477,7 @@ impl OmikronConnection { let resp = CommunicationValue::new(CommunicationType::remove_community) .with_id(cv.get_id()) - .with_receiver(cv.get_sender().unwrap()); + .with_receiver(cv.get_sender()); Self::send_message_static( &writer.clone(), resp.to_json().to_string(), @@ -498,7 +487,7 @@ impl OmikronConnection { } if cv.is_type(CommunicationType::settings_save) { - let my_id = cv.get_sender().unwrap(); + let my_id = cv.get_sender(); let settings_name = cv.get_data(DataTypes::settings_name).unwrap().to_string(); let settings_value = @@ -523,7 +512,7 @@ impl OmikronConnection { return; } if cv.is_type(CommunicationType::settings_load) { - let my_id = cv.get_sender().unwrap(); + let my_id = cv.get_sender(); let settings_name = cv.get_data(DataTypes::settings_name).unwrap().to_string(); let settings_value_str = load_file( @@ -546,7 +535,7 @@ impl OmikronConnection { return; } if cv.is_type(CommunicationType::settings_list) { - let my_id = cv.get_sender().unwrap(); + let my_id = cv.get_sender(); let settings = get_children(&format!("users/{}/settings/", my_id)); let mut settings_json = JsonValue::new_array(); for s in settings { diff --git a/src/server/api.rs b/src/server/api.rs index 7117777..3d5deb1 100644 --- a/src/server/api.rs +++ b/src/server/api.rs @@ -11,7 +11,6 @@ use http_body_util::Full; use hyper::body::Bytes; use hyper::{HeaderMap, Response as HttpResponse, StatusCode}; use json::JsonValue; -use uuid::Uuid; use crate::util::config_util::CONFIG; use crate::{APP_STATE, communities::community_manager, users::user_manager}; @@ -108,8 +107,7 @@ pub async fn handle( if body.is_none() { "{\"type\":\"error\"}".to_string() } else { - let uuid = Uuid::parse_str(body.unwrap()["uuid"].as_str().unwrap()) - .unwrap(); + let uuid = body.unwrap()["uuid"].as_i64().unwrap_or(0); unregister_user( uuid, &user_manager::get_user(uuid).unwrap().reset_token, diff --git a/src/users/contact.rs b/src/users/contact.rs index ea6ac47..bdfa6b2 100644 --- a/src/users/contact.rs +++ b/src/users/contact.rs @@ -1,10 +1,9 @@ use json::{self, JsonValue}; use std::time::{SystemTime, UNIX_EPOCH}; -use uuid::Uuid; #[derive(Debug, Clone)] pub struct Contact { - pub user_id: Option, + pub user_id: Option, pub user_name: Option, pub last_message_at: Option, } @@ -24,7 +23,7 @@ impl Default for Contact { } impl Contact { - pub fn new(user_id: Uuid) -> Self { + pub fn new(user_id: i64) -> Self { Contact { user_id: Some(user_id), user_name: None, @@ -49,7 +48,7 @@ impl Contact { obj } pub fn from_json(o: &JsonValue) -> Contact { - let user_id = o["user_id"].as_str().and_then(|s| Uuid::parse_str(s).ok()); + let user_id = o["user_id"].as_i64(); let user_name = o["user_name"].as_str().map(|s| s.to_string()); diff --git a/src/users/user_community_util.rs b/src/users/user_community_util.rs index f9e1d95..45b036c 100644 --- a/src/users/user_community_util.rs +++ b/src/users/user_community_util.rs @@ -2,12 +2,11 @@ use crate::util::file_util::save_file; use json::{self, Array, JsonValue}; use std::fs; use std::path::Path; -use uuid::Uuid; pub struct UserCommunityUtil; impl UserCommunityUtil { - pub fn add_community(storage_owner: Uuid, address: String, title: String, position: String) { + pub fn add_community(storage_owner: i64, address: String, title: String, position: String) { let file_path = format!("users/{}/", storage_owner); let mut communities = Self::load_array(&file_path); @@ -25,7 +24,7 @@ impl UserCommunityUtil { ); } - pub fn remove_community(storage_owner: Uuid, community_address: String) { + pub fn remove_community(storage_owner: i64, community_address: String) { let file_path = format!("users/{}/", storage_owner); let communities = Self::load_array(&file_path); @@ -41,7 +40,7 @@ impl UserCommunityUtil { ); } - pub fn get_communities(storage_owner: Uuid) -> Array { + pub fn get_communities(storage_owner: i64) -> Array { let file_path = format!("users/{}/communities.json", storage_owner); Self::load_array(&file_path) } diff --git a/src/users/user_manager.rs b/src/users/user_manager.rs index 50cb372..90fcd45 100644 --- a/src/users/user_manager.rs +++ b/src/users/user_manager.rs @@ -13,9 +13,7 @@ use rand_core::OsRng; use rand_core::RngCore; use sha2::{Digest, Sha256}; use std::io::{self}; -use std::str::FromStr; use std::sync::Mutex; -use uuid::Uuid; use x448::{PublicKey, Secret}; static USERS: Lazy>> = Lazy::new(|| Mutex::new(Vec::new())); @@ -25,7 +23,7 @@ static UNIQUE: Lazy> = Lazy::new(|| Mutex::new(false)); pub async fn load_from_tu(username: &str) -> Result<(), ()> { let file_content = load_file("", &format!("{}.tu", username)); let segments = file_content.split("::").collect::>(); - let uuid = Uuid::from_str(segments[0]).unwrap(); + let uuid = segments[0].parse::().unwrap_or(0); let b64_private_key = segments[1]; let secret: Secret = crypto_helper::load_secret_key(b64_private_key).unwrap(); @@ -86,7 +84,7 @@ pub async fn create_user(username: &str) -> (Option, Option (Some(up), Some(STANDARD.encode(&private_key.as_bytes()))) } -pub fn get_user(user_id: Uuid) -> Option { +pub fn get_user(user_id: i64) -> Option { USERS .lock() .unwrap() @@ -99,7 +97,7 @@ pub fn get_users() -> Vec { USERS.lock().unwrap().clone() } -pub fn remove_user(user_id: Uuid) { +pub fn remove_user(user_id: i64) { let mut users = USERS.lock().unwrap(); users.retain(|u| u.user_id != user_id); *UNIQUE.lock().unwrap() = true; diff --git a/src/users/user_profile.rs b/src/users/user_profile.rs index a76003f..49acfa8 100644 --- a/src/users/user_profile.rs +++ b/src/users/user_profile.rs @@ -8,12 +8,11 @@ use base64::{Engine as _, engine::general_purpose}; use json::{JsonValue, object}; use rand::Rng; use rand::rngs::OsRng; -use uuid::Uuid; // --- UserProfile --- #[derive(Clone, Debug)] pub struct UserProfile { - pub user_id: Uuid, + pub user_id: i64, pub username: String, pub public_key: String, pub private_key_hash: String, @@ -24,7 +23,7 @@ pub struct UserProfile { impl UserProfile { pub fn new( - user_id: Uuid, + user_id: i64, username: String, display_name: Option, public_key: String, @@ -47,7 +46,7 @@ impl UserProfile { pub fn to_json(&self) -> JsonValue { let mut obj = object! { - "uuid" => self.user_id.to_string(), + "uuid" => self.user_id, "username" => self.username.clone(), "public_key" => self.public_key.clone(), "private_key_hash" => self.private_key_hash.clone(), @@ -61,7 +60,7 @@ impl UserProfile { } pub fn frontend(&self) -> JsonValue { let mut obj = object! { - "uuid" => self.user_id.to_string(), + "uuid" => self.user_id, "username" => self.username.clone(), "public_key" => self.public_key.clone(), "private_key_hash" => self.private_key_hash.clone(), @@ -78,7 +77,7 @@ impl UserProfile { obj } pub async fn from_json(j: &JsonValue) -> Option { - let user_id = Uuid::parse_str(j["uuid"].as_str()?).ok()?; + let user_id = j["uuid"].as_i64()?; let username = j["username"].as_str()?.to_string(); let public_key = j["public_key"].as_str()?.to_string(); let private_key_hash = j["private_key_hash"].as_str()?.to_string(); diff --git a/src/util/chat_files.rs b/src/util/chat_files.rs index f7fd2f1..ed4e51f 100644 --- a/src/util/chat_files.rs +++ b/src/util/chat_files.rs @@ -2,7 +2,6 @@ use crate::util::file_util::{get_children, get_directory, load_file, save_file}; use json::{self, JsonValue, array, object}; use std::fs::{self}; use std::path::Path; -use uuid::Uuid; use crate::gui::log_panel::log_message; @@ -27,8 +26,8 @@ impl MessageState { pub fn add_message( send_time: u128, storage_owner_is_sender: bool, - storage_owner: Uuid, - external_user: Uuid, + storage_owner: i64, + external_user: i64, message: &str, ) { let user_dir = format!( @@ -87,8 +86,8 @@ pub fn add_message( save_file(&user_dir, &file_name, &message_chunk.dump()); } pub fn change_message_state( - storage_owner: Uuid, - external_user: Uuid, + storage_owner: i64, + external_user: i64, timestamp: i64, new_state: MessageState, ) -> std::io::Result<()> { @@ -132,8 +131,8 @@ pub fn change_message_state( } pub fn get_messages( - storage_owner: Uuid, - external_user: Uuid, + storage_owner: i64, + external_user: i64, loaded_messages: i64, amount: i64, ) -> JsonValue { diff --git a/src/util/chats_util.rs b/src/util/chats_util.rs index b824f13..a1b1833 100644 --- a/src/util/chats_util.rs +++ b/src/util/chats_util.rs @@ -1,10 +1,9 @@ use json::{self, JsonValue, array}; -use uuid::Uuid; use crate::users::contact::Contact; use crate::util::file_util::{load_file, save_file}; -pub fn mod_user(storage_owner: Uuid, contact: &Contact) { +pub fn mod_user(storage_owner: i64, contact: &Contact) { let dir: &str = &format!("users/{}/contacts/", storage_owner); let s = load_file(dir, "contacts.json"); @@ -25,7 +24,7 @@ pub fn mod_user(storage_owner: Uuid, contact: &Contact) { save_file(&dir, "contacts.json", &contacts.dump()); } -pub fn get_user(storage_owner: Uuid, user_id: Uuid) -> Option { +pub fn get_user(storage_owner: i64, user_id: i64) -> Option { let dir = format!("users/{}/contacts/", storage_owner); let s = load_file(&dir, "contacts.json"); if s.is_empty() { @@ -34,8 +33,8 @@ pub fn get_user(storage_owner: Uuid, user_id: Uuid) -> Option { if let Ok(contacts) = json::parse(&s) { for i in 0..contacts.len() { - if let Some(uid) = contacts[i]["user_id"].as_str() { - if Uuid::parse_str(uid).ok()? == user_id { + if let Some(uid) = contacts[i]["user_id"].as_i64() { + if uid == user_id { return Option::from(Contact::from_json(&contacts[i])); } } @@ -44,7 +43,7 @@ pub fn get_user(storage_owner: Uuid, user_id: Uuid) -> Option { None } -pub fn get_users(storage_owner: Uuid) -> JsonValue { +pub fn get_users(storage_owner: i64) -> JsonValue { let dir: &str = &format!("users/{}/contacts/", storage_owner); let s = load_file(dir, "contacts.json"); diff --git a/src/util/config_util.rs b/src/util/config_util.rs index 01020f5..68cad76 100644 --- a/src/util/config_util.rs +++ b/src/util/config_util.rs @@ -28,12 +28,8 @@ impl ConfigUtil { } } - pub fn get_iota_id(&self) -> Uuid { - self.config["iota_id"] - .as_str() - .unwrap_or_default() - .parse() - .unwrap_or_default() + pub fn get_iota_id(&self) -> i64 { + self.config["iota_id"].as_i64().unwrap_or(0) } pub fn get_port(&self) -> u16 { @@ -44,8 +40,8 @@ impl ConfigUtil { &self.config[key] } - pub fn change(&mut self, key: &str, value: &str) { - self.config[key] = JsonValue::String(value.to_string()); + pub fn change(&mut self, key: &str, value: JsonValue) { + self.config[key] = value; self.unique = true; }