Swap to UNIX timestamps as user ID's

This commit is contained in:
Alex Emmet 2025-12-07 16:10:31 +01:00
commit 9d43687f8b
18 changed files with 234 additions and 276 deletions

View file

@ -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<bool> {
pub async fn unregister_user(user_id: i64, reset_token: &str) -> Option<bool> {
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<bool> {
Option::from(cv.is_type(CommunicationType::success))
}
pub async fn get_uuid(username: &str) -> Option<Uuid> {
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<AuthUser> {
pub async fn get_user(user_id: i64) -> Option<AuthUser> {
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<AuthUser> {
})
}
pub async fn get_register() -> Option<Uuid> {
pub async fn get_register() -> Option<i64> {
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();

View file

@ -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();

View file

@ -33,7 +33,7 @@ pub struct Community {
private_key: Secret,
public_key: PublicKey,
pub interactables: Arc<RwLock<Vec<Arc<Box<dyn Interactable>>>>>,
pub connections: Arc<RwLock<HashMap<Uuid, Vec<Arc<CommunityConnection>>>>>,
pub connections: Arc<RwLock<HashMap<i64, Vec<Arc<CommunityConnection>>>>>,
}
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<Self>, other: Arc<CommunityConnection>) {
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<Uuid, Vec<Arc<CommunityConnection>>> {
pub async fn get_connections(&self) -> HashMap<i64, Vec<Arc<CommunityConnection>>> {
self.connections.read().await.clone()
}
pub async fn get_connections_for_user(&self, user_id: Uuid) -> Vec<Arc<CommunityConnection>> {
pub async fn get_connections_for_user(&self, user_id: i64) -> Vec<Arc<CommunityConnection>> {
self.connections
.read()
.await
@ -166,7 +166,7 @@ impl Community {
}
pub async fn get_interactables(
&self,
user_id: Uuid,
user_id: i64,
) -> Vec<Arc<Box<dyn Interactable + 'static>>> {
self.interactables.read().await.clone()
}
@ -191,7 +191,7 @@ impl Community {
}
pub async fn run_function(
self: &mut Arc<Self>,
user_id: Uuid,
user_id: i64,
name: &str,
path: &str,
function: &str,

View file

@ -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<RwLock<SplitSink<WebSocketStream<TokioIo<Upgraded>>, Message>>>,
pub receiver: Arc<RwLock<SplitStream<WebSocketStream<TokioIo<Upgraded>>>>>,
pub user_id: Arc<RwLock<Option<Uuid>>>,
pub user_id: Arc<RwLock<i64>>,
pub community: Arc<RwLock<Option<Arc<Community>>>>,
identified: Arc<RwLock<bool>>,
challenged: Arc<RwLock<bool>>,
@ -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<Arc<Community>> {
self.community.read().await.clone()
}
pub async fn get_user_id(&self) -> Option<Uuid> {
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<Self>, message: String) {
let mut cv = CommunicationValue::from_json(&message);
if let Some(user_id) = self.get_user_id().await {
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<Self>) {
if self.is_identified().await {
if let Some(_) = self.get_user_id().await {
if self.get_user_id().await != 0 {
self.community
.read()
.await

View file

@ -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<Uuid, Vec<Arc<CommunityConnection>>> =
let connections: HashMap<i64, Vec<Arc<CommunityConnection>>> =
self.get_community().get_connections().await.clone();
for con in connections.values() {

View file

@ -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<Uuid>,
pub receiver: Option<Uuid>,
pub sender: i64,
pub receiver: i64,
pub data: HashMap<DataTypes, JsonValue>,
}
@ -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<Uuid> {
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<Uuid> {
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,29 +383,19 @@ impl CommunicationValue {
}
pub fn from_json(json_str: &str) -> Self {
let parsed = parse(json_str).unwrap();
if let Ok(parsed) = parse(json_str) {
let comm_type = CommunicationType::parse(parsed["type"].to_string());
let mut sender: Option<Uuid> = None;
let mut sender: i64 = 0;
if parsed.has_key("sender") {
sender = Some(
parsed["sender"]
.as_str()
.and_then(|s| Uuid::parse_str(s).ok())
.unwrap_or(Uuid::new_v4()),
);
sender = parsed["sender"].as_i64().unwrap_or(0);
}
let mut receiver: Option<Uuid> = None;
let mut receiver: i64 = 0;
if parsed.has_key("receiver") {
receiver = Some(
parsed["receiver"]
.as_str()
.and_then(|s| Uuid::parse_str(s).ok())
.unwrap_or(Uuid::new_v4()),
);
receiver = parsed["receiver"].as_i64().unwrap_or(0);
}
let uuid = Uuid::parse_str(parsed["id"].as_str().unwrap_or("")).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() {
@ -420,16 +410,22 @@ impl CommunicationValue {
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
let receiver = original
.get_data(DataTypes::receiver_id)
.unwrap()
.to_string(),
)
.ok()
.or(Option::from(Uuid::nil()));
.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,

View file

@ -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;
}

View file

@ -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")?;

View file

@ -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()

View file

@ -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<RwLock<ConnectionVariant>>,
pub user_id: Arc<RwLock<Option<Uuid>>>,
pub user_id: Arc<RwLock<i64>>,
pub(crate) writer:
Arc<Mutex<Option<Box<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin>>>>,
waiting: Arc<Mutex<HashMap<Uuid, Box<dyn Fn(CommunicationValue) + Send + Sync>>>>, // 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<Self> {
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<dyn Sink<Message, Error = tungstenite::Error> + Send + Unpin>))),
waiting: Arc::new(Mutex::new(HashMap::new())),
@ -143,8 +143,8 @@ impl OmikronConnection {
pub async fn set_variant(self: &Arc<Self>, variant: ConnectionVariant) {
*self.variant.write().await = variant;
}
pub async fn set_user_id(self: &Arc<Self>, user_id: Uuid) {
*self.user_id.write().await = Some(user_id);
pub async fn set_user_id(self: &Arc<Self>, user_id: i64) {
*self.user_id.write().await = user_id;
}
/// Listener for all incoming messages
@ -193,23 +193,12 @@ 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 => {
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(
@ -222,7 +211,6 @@ impl OmikronConnection {
.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 {

View file

@ -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,

View file

@ -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<Uuid>,
pub user_id: Option<i64>,
pub user_name: Option<String>,
pub last_message_at: Option<i64>,
}
@ -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());

View file

@ -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)
}

View file

@ -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<Mutex<Vec<UserProfile>>> = Lazy::new(|| Mutex::new(Vec::new()));
@ -25,7 +23,7 @@ static UNIQUE: Lazy<Mutex<bool>> = 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::<Vec<&str>>();
let uuid = Uuid::from_str(segments[0]).unwrap();
let uuid = segments[0].parse::<i64>().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<UserProfile>, Option<String>
(Some(up), Some(STANDARD.encode(&private_key.as_bytes())))
}
pub fn get_user(user_id: Uuid) -> Option<UserProfile> {
pub fn get_user(user_id: i64) -> Option<UserProfile> {
USERS
.lock()
.unwrap()
@ -99,7 +97,7 @@ pub fn get_users() -> Vec<UserProfile> {
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;

View file

@ -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<String>,
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<Self> {
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();

View file

@ -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 {

View file

@ -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<Contact> {
pub fn get_user(storage_owner: i64, user_id: i64) -> Option<Contact> {
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<Contact> {
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<Contact> {
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");

View file

@ -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;
}