async sockets
This commit is contained in:
commit
4170b9f387
23 changed files with 544 additions and 479 deletions
208
Cargo.lock
generated
208
Cargo.lock
generated
|
|
@ -8,6 +8,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"aes-gcm",
|
||||
"async-trait",
|
||||
"async-tungstenite",
|
||||
"axum",
|
||||
"base64",
|
||||
"bytes",
|
||||
|
|
@ -20,10 +21,12 @@ dependencies = [
|
|||
"hex",
|
||||
"hkdf",
|
||||
"hmac",
|
||||
"hyper",
|
||||
"json",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"pkcs8",
|
||||
"rand",
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"ratatui",
|
||||
"reactive-rs",
|
||||
|
|
@ -35,9 +38,11 @@ dependencies = [
|
|||
"sysinfo",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"tokio-util",
|
||||
"tungstenite",
|
||||
"uuid",
|
||||
"walkdir",
|
||||
"warp",
|
||||
"x448",
|
||||
"x509",
|
||||
]
|
||||
|
|
@ -118,6 +123,22 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-tungstenite"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6f89c129ab749940f95509d84950c62092c8b4bc6e386ddb162229037a6ec91"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tungstenite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
|
|
@ -166,9 +187,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.5.2"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
|
||||
checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
|
|
@ -177,7 +198,6 @@ dependencies = [
|
|||
"http-body-util",
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
|
|
@ -232,12 +252,6 @@ version = "3.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
|
|
@ -871,6 +885,30 @@ dependencies = [
|
|||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers-core"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
||||
dependencies = [
|
||||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
|
|
@ -1355,6 +1393,16 @@ version = "0.3.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
|
|
@ -1532,6 +1580,26 @@ version = "2.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
|
|
@ -1627,10 +1695,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
|
|
@ -1641,6 +1719,16 @@ dependencies = [
|
|||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
|
|
@ -1656,6 +1744,15 @@ dependencies = [
|
|||
"getrandom 0.2.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom 0.3.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui"
|
||||
version = "0.29.0"
|
||||
|
|
@ -1866,6 +1963,12 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
|
|
@ -2197,18 +2300,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
version = "2.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
version = "2.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -2308,18 +2411,16 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-tungstenite"
|
||||
version = "0.23.1"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6989540ced10490aaf14e6bad2e3d33728a2813310a0c71d1574304c49631cd"
|
||||
checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-native-tls",
|
||||
"tungstenite",
|
||||
"webpki-roots 0.26.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2330,8 +2431,12 @@ checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"hashbrown",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
|
@ -2431,19 +2536,17 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
|||
|
||||
[[package]]
|
||||
name = "tungstenite"
|
||||
version = "0.23.0"
|
||||
version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8"
|
||||
checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"data-encoding",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"native-tls",
|
||||
"rand 0.9.2",
|
||||
"sha1",
|
||||
"thiserror",
|
||||
"utf-8",
|
||||
|
|
@ -2455,6 +2558,12 @@ version = "1.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
|
|
@ -2578,6 +2687,33 @@ dependencies = [
|
|||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "warp"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
|
|
@ -2675,24 +2811,6 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
|
||||
dependencies = [
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
|||
69
Cargo.toml
69
Cargo.toml
|
|
@ -4,41 +4,42 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "*"
|
||||
json = "*"
|
||||
axum = "*"
|
||||
futures-util = "*"
|
||||
rustls = { version = "*", default-features = false, features = ["ring"] }
|
||||
tokio-tungstenite = { version = "0.23.1", default-features = false, features = [
|
||||
"connect",
|
||||
"rustls-tls-webpki-roots",
|
||||
"tokio-rustls"
|
||||
] }
|
||||
cmake = "*"
|
||||
tokio = { version = "*", features = ["full"] }
|
||||
uuid = { version = "*", features = ["v4"] }
|
||||
walkdir = "2.5.0"
|
||||
sysinfo = "0.30"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
ratatui = { version = "*", features = ["all-widgets"]}
|
||||
bytes = "*"
|
||||
crossterm = "*"
|
||||
color-eyre = "*"
|
||||
sys-info = "*"
|
||||
rand = "0.8"
|
||||
rand_core = { version = "0.6", features = ["getrandom", "std"] }
|
||||
base64 = "0.22.1"
|
||||
once_cell = "1.21.3"
|
||||
reqwest = "0.12.23"
|
||||
x448 = { version = "*" }
|
||||
hex = "*"
|
||||
x509 = "*"
|
||||
sha2 = "*"
|
||||
der = "*"
|
||||
pkcs8 = { version = "*", features = ["alloc"] }
|
||||
tungstenite = "*"
|
||||
futures = "*"
|
||||
aes-gcm = "*"
|
||||
async-trait = "*"
|
||||
async-tungstenite = { version = "*" }
|
||||
axum = "*"
|
||||
base64 = "0.22.1"
|
||||
bytes = "*"
|
||||
cmake = "*"
|
||||
color-eyre = "*"
|
||||
crossterm = "*"
|
||||
der = "*"
|
||||
futures = "*"
|
||||
futures-util = "*"
|
||||
hex = "*"
|
||||
hkdf = "*"
|
||||
hmac = "*"
|
||||
hyper = { version = "*", features = ["full"] }
|
||||
json = "*"
|
||||
native-tls = { version = "*", default-features = false }
|
||||
once_cell = "1.21.3"
|
||||
pkcs8 = { version = "*", features = ["alloc"] }
|
||||
rand = "0.8"
|
||||
rand_core = { version = "0.6", features = ["getrandom", "std"] }
|
||||
ratatui = { version = "*", features = ["all-widgets"]}
|
||||
reactive-rs = "*"
|
||||
reqwest = "0.12.23"
|
||||
rustls = { version = "*", default-features = false, features = ["ring"] }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
sha2 = "*"
|
||||
sys-info = "*"
|
||||
sysinfo = "0.30"
|
||||
tokio = { version = "*", features = ["full"] }
|
||||
tokio-util = { version = "*", features = ["full"] }
|
||||
tokio-tungstenite = { version = "*", features = ["native-tls"] }
|
||||
tungstenite = "*"
|
||||
uuid = { version = "*", features = ["v4"] }
|
||||
walkdir = "2.5.0"
|
||||
warp = "*"
|
||||
x448 = { version = "*" }
|
||||
x509 = "*"
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ pub async fn get_uuid(username: &str) -> Option<Uuid> {
|
|||
let client = client();
|
||||
let res = client.get(&url).send().await.ok()?;
|
||||
let json = res.text().await.ok()?;
|
||||
let mut cv = CommunicationValue::from_json(&json);
|
||||
let cv = CommunicationValue::from_json(&json);
|
||||
if !cv.is_type(CommunicationType::success) {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ pub async fn get_user(user_id: Uuid) -> Option<AuthUser> {
|
|||
let res = client.get(&url).send().await.ok()?;
|
||||
let json = res.text().await.ok()?;
|
||||
|
||||
let mut cv = CommunicationValue::from_json(&json);
|
||||
let cv = CommunicationValue::from_json(&json);
|
||||
if cv.comm_type != CommunicationType::success {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ pub async fn get_register() -> Option<Uuid> {
|
|||
let res = client.get(&url).send().await.ok()?;
|
||||
let json = res.text().await.ok()?;
|
||||
|
||||
let mut cv = CommunicationValue::from_json(&json);
|
||||
let cv = CommunicationValue::from_json(&json);
|
||||
Uuid::parse_str(&*cv.get_data(DataTypes::user_id).unwrap().to_string()).ok()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,16 +4,8 @@ use aes_gcm::{
|
|||
aead::{Aead, KeyInit, OsRng},
|
||||
};
|
||||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||
use base64::{decode as b64_decode, encode as b64_encode};
|
||||
use hex;
|
||||
use json::JsonValue;
|
||||
use once_cell::sync::Lazy;
|
||||
use rand::Rng;
|
||||
use rand_core::RngCore;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::io;
|
||||
use std::sync::Mutex;
|
||||
use uuid::Uuid;
|
||||
use x448::{PublicKey, Secret, SharedSecret}; // from the `x448` crate
|
||||
|
||||
/// Errors for crypto operations
|
||||
|
|
@ -47,20 +39,20 @@ pub fn generate_keypair() -> KeyPair {
|
|||
}
|
||||
|
||||
pub fn public_key_to_base64(pubkey: &PublicKey) -> String {
|
||||
b64_encode(pubkey.as_bytes().as_ref())
|
||||
STANDARD.encode(pubkey.as_bytes().as_ref())
|
||||
}
|
||||
|
||||
pub fn secret_key_to_base64(secret: &Secret) -> String {
|
||||
b64_encode(secret.as_bytes().as_ref())
|
||||
STANDARD.encode(secret.as_bytes().as_ref())
|
||||
}
|
||||
|
||||
pub fn load_public_key(base64_pub: &str) -> Option<PublicKey> {
|
||||
let bytes = b64_decode(base64_pub).unwrap();
|
||||
let bytes = STANDARD.decode(base64_pub).unwrap();
|
||||
PublicKey::from_bytes(&bytes)
|
||||
}
|
||||
|
||||
pub fn load_secret_key(base64_secret: &str) -> Option<Secret> {
|
||||
let bytes = b64_decode(base64_secret).unwrap();
|
||||
let bytes = STANDARD.decode(base64_secret).unwrap();
|
||||
Secret::from_bytes(&bytes)
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +87,7 @@ pub fn encrypt(
|
|||
let mut out = Vec::with_capacity(nonce_bytes.len() + ciphertext.len());
|
||||
out.extend_from_slice(&nonce_bytes);
|
||||
out.extend_from_slice(&ciphertext);
|
||||
Ok(b64_encode(&out))
|
||||
Ok(STANDARD.encode(&out))
|
||||
}
|
||||
|
||||
pub fn decrypt(
|
||||
|
|
@ -111,7 +103,7 @@ pub fn decrypt(
|
|||
let key_bytes = derive_aes_key(&shared);
|
||||
let cipher = Aes256Gcm::new_from_slice(&key_bytes).expect("Key length should be correct");
|
||||
|
||||
let encrypted = b64_decode(encrypted_base64)?;
|
||||
let encrypted = STANDARD.decode(encrypted_base64)?;
|
||||
if encrypted.len() < 12 {
|
||||
return Err(CryptoError::DecryptionError(aes_gcm::Error));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use crate::communities::interactables::category::Category;
|
||||
use crate::communities::interactables::registry;
|
||||
use crate::communities::interactables::text_chat::TextChat;
|
||||
use crate::communities::interactables::voice_chat::VoiceChat;
|
||||
use crate::communities::{
|
||||
community_connection::CommunityConnection, interactables::interactable::Interactable,
|
||||
};
|
||||
|
|
@ -12,8 +10,6 @@ use json::JsonValue;
|
|||
use json::object::Object;
|
||||
use rand::RngCore;
|
||||
use rand_core::OsRng;
|
||||
use ratatui::text;
|
||||
use serde::de::value::StringDeserializer;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
|
@ -200,10 +196,10 @@ impl Community {
|
|||
|
||||
let mut permissions = JsonValue::new_array();
|
||||
for perm in self.permissions.get(user).unwrap() {
|
||||
permissions.push(perm.to_string());
|
||||
if let Ok(_) = permissions.push(perm.to_string()) {}
|
||||
}
|
||||
|
||||
data.insert("permissions", permissions);
|
||||
if let Ok(_) = data.insert("permissions", permissions) {}
|
||||
user_data.insert(&user.to_string(), data);
|
||||
}
|
||||
file_util::save_file(
|
||||
|
|
@ -230,7 +226,7 @@ pub async fn load(name: &String) -> Option<Arc<Community>> {
|
|||
let (str, json): (&str, &JsonValue) = user;
|
||||
let perms_j = &json["permissions"];
|
||||
let perms = Vec::new();
|
||||
for i in perms_j.entries() {
|
||||
for _ in perms_j.entries() {
|
||||
// let perm_j = i.as_str().unwrap();
|
||||
// perms.push(perm_j.to_string());
|
||||
}
|
||||
|
|
@ -242,11 +238,12 @@ pub async fn load(name: &String) -> Option<Arc<Community>> {
|
|||
}
|
||||
|
||||
let role_data = file_util::load_file(&format!("communities/{}/", name), "roles.json");
|
||||
if let Ok(user_json) = json::parse(&role_data) {
|
||||
let roles: HashMap<String, Vec<String>> = HashMap::new();
|
||||
if let Ok(_) = json::parse(&role_data) {
|
||||
// Fill roles
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
let mut roles: HashMap<String, Vec<String>> = HashMap::new();
|
||||
|
||||
let community = Community {
|
||||
name: json_content["name"].as_str().unwrap().to_string(),
|
||||
|
|
@ -283,15 +280,5 @@ pub async fn load(name: &String) -> Option<Arc<Community>> {
|
|||
comarc.add_interactable(Arc::new(interactable)).await;
|
||||
}
|
||||
}
|
||||
let mut text_chat: TextChat = TextChat::new();
|
||||
text_chat.load(
|
||||
comarc.clone(),
|
||||
String::new(),
|
||||
String::from("a"),
|
||||
&JsonValue::Null,
|
||||
);
|
||||
|
||||
comarc.add_interactable(Arc::new(Box::new(text_chat))).await;
|
||||
|
||||
Some(comarc)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ use crate::communities::community::Community;
|
|||
use crate::communities::interactables::interactable::Interactable;
|
||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||
use aes_gcm::{Aes256Gcm, KeyInit, Nonce, aead::Aead};
|
||||
use async_tungstenite::WebSocketReceiver;
|
||||
use async_tungstenite::WebSocketSender;
|
||||
use async_tungstenite::tungstenite::Utf8Bytes;
|
||||
use async_tungstenite::{WebSocketStream, tungstenite::Message};
|
||||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||
use futures::SinkExt;
|
||||
use hkdf::Hkdf;
|
||||
|
|
@ -13,11 +17,12 @@ use sha2::Sha256;
|
|||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio_tungstenite::{WebSocketStream, tungstenite::Message};
|
||||
use tokio_util::compat::Compat;
|
||||
use uuid::Uuid;
|
||||
use x448::PublicKey;
|
||||
pub struct CommunityConnection {
|
||||
pub session: Arc<Mutex<WebSocketStream<tokio::net::TcpStream>>>,
|
||||
pub sender: Arc<RwLock<WebSocketSender<Compat<tokio::net::TcpStream>>>>,
|
||||
pub receiver: Arc<RwLock<WebSocketReceiver<Compat<tokio::net::TcpStream>>>>,
|
||||
pub user_id: Arc<RwLock<Option<Uuid>>>,
|
||||
pub community: Arc<RwLock<Option<Arc<Community>>>>,
|
||||
identified: Arc<RwLock<bool>>,
|
||||
|
|
@ -28,11 +33,13 @@ pub struct CommunityConnection {
|
|||
}
|
||||
impl CommunityConnection {
|
||||
pub fn new(
|
||||
session: WebSocketStream<tokio::net::TcpStream>,
|
||||
sender: WebSocketSender<Compat<tokio::net::TcpStream>>,
|
||||
receiver: WebSocketReceiver<Compat<tokio::net::TcpStream>>,
|
||||
community: Arc<Community>,
|
||||
) -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
session: Arc::new(Mutex::new(session)),
|
||||
sender: Arc::new(RwLock::new(sender)),
|
||||
receiver: Arc::new(RwLock::new(receiver)),
|
||||
user_id: Arc::new(RwLock::new(None)),
|
||||
community: Arc::new(RwLock::new(Some(community))),
|
||||
identified: Arc::new(RwLock::new(false)),
|
||||
|
|
@ -43,9 +50,11 @@ impl CommunityConnection {
|
|||
})
|
||||
}
|
||||
pub async fn send_message(&self, message: &CommunicationValue) {
|
||||
let mut session = self.session.lock().await;
|
||||
let mut session = self.sender.write().await;
|
||||
session
|
||||
.send(Message::Text(message.to_json().to_string()))
|
||||
.send(Message::Text(Utf8Bytes::from(
|
||||
message.to_json().to_string(),
|
||||
)))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
|
@ -60,7 +69,8 @@ impl CommunityConnection {
|
|||
}
|
||||
|
||||
pub async fn handle_message(self: Arc<Self>, message: String) {
|
||||
let cv = CommunicationValue::from_json(&message);
|
||||
let cv =
|
||||
CommunicationValue::from_json(&message).with_sender(self.get_user_id().await.unwrap());
|
||||
|
||||
if cv.is_type(CommunicationType::identification) && !self.is_identified().await {
|
||||
self.handle_identification(cv).await;
|
||||
|
|
@ -388,7 +398,7 @@ impl CommunityConnection {
|
|||
self.send_message(&error).await;
|
||||
}
|
||||
pub async fn close(&self) {
|
||||
let mut session = self.session.lock().await;
|
||||
let mut session = self.sender.write().await;
|
||||
let _ = session.close(None).await;
|
||||
}
|
||||
pub async fn handle_close(self: Arc<Self>) {
|
||||
|
|
|
|||
|
|
@ -98,11 +98,11 @@ impl Interactable for Category {
|
|||
let mut v = JsonValue::new_object();
|
||||
v["children"] = JsonValue::new_array();
|
||||
for child in &self.children {
|
||||
v["children"].push(child.to_json());
|
||||
let _ = v["children"].push(child.to_json());
|
||||
}
|
||||
v
|
||||
}
|
||||
fn load(&mut self, community: Arc<Community>, path: String, name: String, json: &JsonValue) {
|
||||
fn load(&mut self, community: Arc<Community>, path: String, name: String, _json: &JsonValue) {
|
||||
self.community = community;
|
||||
self.name = name;
|
||||
self.path = path;
|
||||
|
|
|
|||
|
|
@ -11,13 +11,9 @@ use aes_gcm::aead::Payload;
|
|||
use async_trait::async_trait;
|
||||
use axum::Json;
|
||||
use json::{JsonValue, array, object};
|
||||
use rustls::ClientConnection;
|
||||
use std::sync::Arc;
|
||||
use std::{any::Any, collections::HashMap};
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
pin::Pin,
|
||||
};
|
||||
use std::{fs, pin::Pin};
|
||||
use uuid::Uuid;
|
||||
pub struct TextChat {
|
||||
name: String,
|
||||
|
|
@ -246,10 +242,9 @@ impl Interactable for TextChat {
|
|||
CommunicationValue::new(CommunicationType::error).with_id(cv.get_id())
|
||||
}
|
||||
fn to_json(&self) -> JsonValue {
|
||||
let mut v = JsonValue::new_object();
|
||||
v
|
||||
JsonValue::new_object()
|
||||
}
|
||||
fn load(&mut self, community: Arc<Community>, path: String, name: String, json: &JsonValue) {
|
||||
fn load(&mut self, community: Arc<Community>, path: String, name: String, _: &JsonValue) {
|
||||
self.community = community;
|
||||
self.name = name;
|
||||
self.path = path;
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ impl Interactable for VoiceChat {
|
|||
let v = JsonValue::new_object();
|
||||
v
|
||||
}
|
||||
fn load(&mut self, community: Arc<Community>, path: String, name: String, _: &JsonValue) {
|
||||
fn load(&mut self, community: Arc<Community>, path: String, name: String, _json: &JsonValue) {
|
||||
self.community = community;
|
||||
self.name = name;
|
||||
self.path = path;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
pub mod community_manager;
|
||||
pub mod community_socket;
|
||||
pub mod interactables {
|
||||
pub mod category;
|
||||
pub mod interactable;
|
||||
|
|
|
|||
|
|
@ -393,14 +393,6 @@ impl CommunicationValue {
|
|||
data,
|
||||
}
|
||||
}
|
||||
pub fn ack_message(message_id: Uuid, sender: Uuid) -> CommunicationValue {
|
||||
let mut cv = CommunicationValue::new(CommunicationType::message).with_id(message_id);
|
||||
|
||||
if let s = sender {
|
||||
cv = cv.add_data(DataTypes::send_time, JsonValue::String(s.to_string()));
|
||||
}
|
||||
cv
|
||||
}
|
||||
pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue {
|
||||
let receiver = Uuid::from_str(
|
||||
&*original
|
||||
|
|
@ -420,7 +412,8 @@ impl CommunicationValue {
|
|||
CommunicationValue::new(CommunicationType::message_other_iota)
|
||||
.with_id(original.get_id())
|
||||
.with_receiver(receiver.unwrap())
|
||||
.add_data( DataTypes::receiver_id,
|
||||
.add_data(
|
||||
DataTypes::receiver_id,
|
||||
JsonValue::String(receiver.unwrap().to_string()),
|
||||
)
|
||||
.with_sender(sender.unwrap())
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
|
||||
use crate::util::file_util::{load_file, save_file};
|
||||
|
||||
pub fn check_eula() -> bool {
|
||||
let eula = "By changing the value to \"true\" you agree to our end user license agreement and our terms of service!\
|
||||
\nYou can find our Terms of service on https://docs.tensamin.methanium.net/legal/terms-of-service/.\
|
||||
\nYou can find our Terms of service on https://docs.tensamin.net/legal/terms-of-service/.\
|
||||
\neula=false";
|
||||
let file = load_file("", "eula.txt");
|
||||
if(file.is_empty()){
|
||||
if file.is_empty() {
|
||||
save_file("", "eula.txt", eula);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -20,8 +19,8 @@ pub fn check_eula() -> bool{
|
|||
}
|
||||
}
|
||||
pub fn accept_eula() {
|
||||
let eula = "By changing the value to \"true\" you agree to some shit we say on our website IDK this shouldn't be public yet!\
|
||||
\nYou also give us all rights to your soul, and we own your dog now.\
|
||||
let eula = "By changing the value to \"true\" you agree to our end user license agreement and our terms of service!\
|
||||
\nYou can find our Terms of service on https://docs.tensamin.net/legal/terms-of-service/.\
|
||||
\neula=true";
|
||||
save_file("", "eula.txt", eula);
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ use crate::langu::language_manager::format;
|
|||
use crate::langu::language_manager::from_key;
|
||||
|
||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||
use json::Array;
|
||||
use ratatui::widgets::canvas::{Canvas, Line};
|
||||
use ratatui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
|
|
@ -66,7 +65,7 @@ fn downsample_to_fit_width(data: &[(f64, f64)], width: u16) -> Vec<(f64, f64)> {
|
|||
.first()
|
||||
.map(|(x, _)| x - (dx * pad_len as f64))
|
||||
.unwrap_or(0.0);
|
||||
let y = data.first().map(|(_, y)| *y).unwrap_or(0.0);
|
||||
let _ = data.first().map(|(_, y)| *y).unwrap_or(0.0);
|
||||
|
||||
// Fill padding with increasing x positions so they're visible
|
||||
for i in 0..pad_len {
|
||||
|
|
@ -96,8 +95,8 @@ pub fn setup() {
|
|||
}
|
||||
let ram = (sys.used_memory() as f64 / sys.total_memory() as f64) * 100.0;
|
||||
|
||||
let mut total_received = 0u64;
|
||||
let mut total_transmitted = 0u64;
|
||||
let total_received = 0u64;
|
||||
let total_transmitted = 0u64;
|
||||
|
||||
let delta_received = if last_total_received == 0 {
|
||||
0
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::util::file_util::{self, save_file};
|
||||
use json::{self, JsonValue};
|
||||
use crate::util::file_util::save_file;
|
||||
use json::{self, JsonError, JsonValue};
|
||||
|
||||
pub fn create_languages() {
|
||||
pub fn create_languages() -> Result<(), JsonError> {
|
||||
let mut frontend_messages = JsonValue::new_object();
|
||||
let mut omikron_messages = JsonValue::new_object();
|
||||
let mut button_texts = JsonValue::new_object();
|
||||
|
|
@ -9,40 +9,44 @@ pub fn create_languages() {
|
|||
let mut debug_messages = JsonValue::new_object();
|
||||
|
||||
// FRONTEND
|
||||
frontend_messages.insert("get_chats", "User {} is loading conversations");
|
||||
frontend_messages.insert("message_get", "User {} is loading messages");
|
||||
frontend_messages.insert("get_communities", "User {} is loading communities");
|
||||
frontend_messages.insert("client_connected", "Client {} connected");
|
||||
frontend_messages.insert("add_conversation", "User {} added {}");
|
||||
frontend_messages.insert("get_chats", "User {} is loading conversations")?;
|
||||
frontend_messages.insert("message_get", "User {} is loading messages")?;
|
||||
frontend_messages.insert("get_communities", "User {} is loading communities")?;
|
||||
frontend_messages.insert("client_connected", "Client {} connected")?;
|
||||
frontend_messages.insert("add_conversation", "User {} added {}")?;
|
||||
frontend_messages.insert("message_send", "User {} sent a message")?;
|
||||
|
||||
// OMIKRON
|
||||
omikron_messages.insert(
|
||||
"identification_response",
|
||||
"IOTA identified on Omikron, {} users!",
|
||||
);
|
||||
)?;
|
||||
omikron_messages.insert("send_message_failed", "Failed to send message to Omikron")?;
|
||||
omikron_messages.insert("connection_failed", "Failed to connect to Omikron: {}")?;
|
||||
|
||||
// BUTTONS
|
||||
button_texts.insert("exit", "Exit");
|
||||
button_texts.insert("exit", "Exit")?;
|
||||
|
||||
// GENERAL
|
||||
general_texts.insert("iota_id", "IOTA ID: {}-####-####-####-############");
|
||||
general_texts.insert("user_id", "USER ID: {}");
|
||||
general_texts.insert("user_ids", "USER IDS: {}");
|
||||
general_texts.insert("setup_completed", "Launched");
|
||||
general_texts.insert("iota_id", "IOTA ID: {}-####-####-####-############")?;
|
||||
general_texts.insert("user_id", "USER ID: {}")?;
|
||||
general_texts.insert("user_ids", "USER IDS: {}")?;
|
||||
general_texts.insert("user_load_failed", "Failed to load user data")?;
|
||||
general_texts.insert("setup_completed", "Launched")?;
|
||||
general_texts.insert(
|
||||
"community_active",
|
||||
"Communities active on ws://0.0.0.0:{}/community/...",
|
||||
);
|
||||
)?;
|
||||
general_texts.insert(
|
||||
"community_start_error",
|
||||
"Failed to start community socket on port {}!",
|
||||
);
|
||||
)?;
|
||||
general_texts.insert(
|
||||
"community_start_error_admin",
|
||||
"Failed to start community socket on port {}! Run with admin privileges",
|
||||
);
|
||||
)?;
|
||||
// DEBUG
|
||||
debug_messages.insert("", "");
|
||||
debug_messages.insert("", "")?;
|
||||
save_file(
|
||||
"languages/en_INT",
|
||||
"frontend.json",
|
||||
|
|
@ -68,4 +72,5 @@ pub fn create_languages() {
|
|||
"general.json",
|
||||
&general_texts.to_string(),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ pub fn from_key(key: &str) -> String {
|
|||
pub fn format(key: &str, args: &[&str]) -> String {
|
||||
let message = from_key(key);
|
||||
let mut formatted = String::new();
|
||||
let mut parts = message.split("{}");
|
||||
let parts = message.split("{}");
|
||||
for (i, part) in parts.enumerate() {
|
||||
formatted.push_str(part);
|
||||
if i < args.len() {
|
||||
|
|
|
|||
31
src/main.rs
31
src/main.rs
|
|
@ -12,11 +12,12 @@ mod eula;
|
|||
mod gui;
|
||||
mod langu;
|
||||
mod omikron;
|
||||
mod server;
|
||||
mod users;
|
||||
mod util;
|
||||
|
||||
use crate::communities::community_manager;
|
||||
use crate::communities::interactables::registry;
|
||||
use crate::communities::{community_manager, community_socket};
|
||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||
use crate::gui::app_state::AppState;
|
||||
use crate::gui::log_panel::{log_message, log_message_trans};
|
||||
|
|
@ -24,13 +25,14 @@ use crate::gui::{log_panel, ratatui_interface};
|
|||
use crate::langu::language_creator;
|
||||
use crate::langu::language_manager::format;
|
||||
use crate::omikron::omikron_connection::OmikronConnection;
|
||||
use crate::server::socket::start;
|
||||
use crate::users::user_manager;
|
||||
use crate::util::config_util::CONFIG;
|
||||
|
||||
pub static APP_STATE: LazyLock<Arc<Mutex<AppState>>> =
|
||||
LazyLock::new(|| Arc::new(Mutex::new(AppState::new())));
|
||||
|
||||
#[tokio::main]
|
||||
#[tokio::main(flavor = "multi_thread", worker_threads = 8)]
|
||||
#[allow(unused_must_use, dead_code)]
|
||||
async fn main() {
|
||||
// EULA
|
||||
//if !eula_checker::check_eula() {
|
||||
|
|
@ -38,22 +40,33 @@ async fn main() {
|
|||
// return;
|
||||
//}
|
||||
|
||||
// LANGUAGE PACK
|
||||
if let Err(e) = language_creator::create_languages() {
|
||||
println!("Language pack creation failed: {}", e);
|
||||
return;
|
||||
}
|
||||
|
||||
// UI
|
||||
log_panel::setup();
|
||||
ratatui_interface::launch();
|
||||
// LANGUAGE PACK
|
||||
language_creator::create_languages();
|
||||
if let Err(e) = ratatui_interface::launch() {
|
||||
println!("Ui launch failed: {}", &e.to_string());
|
||||
return;
|
||||
}
|
||||
|
||||
// BASIC CONFIGURATION
|
||||
CONFIG.lock().unwrap().load();
|
||||
if !CONFIG.lock().unwrap().config.has_key("iota_id") {
|
||||
CONFIG.lock().unwrap().change("iota_id", Uuid::new_v4());
|
||||
CONFIG.lock().unwrap().save();
|
||||
CONFIG.lock().unwrap().update();
|
||||
}
|
||||
|
||||
// USER MANAGEMENT
|
||||
let _ = user_manager::load_users().await;
|
||||
if let Err(_) = user_manager::load_users().await {
|
||||
log_message_trans("user_load_failed");
|
||||
}
|
||||
|
||||
let mut sb = "".to_string();
|
||||
|
||||
for up in user_manager::get_users() {
|
||||
sb = sb + "," + &up.user_id.to_string().as_str();
|
||||
}
|
||||
|
|
@ -91,7 +104,7 @@ async fn main() {
|
|||
}
|
||||
log_message(format!("Community IDS: {}", sb1));
|
||||
let port = CONFIG.lock().unwrap().get_port();
|
||||
if community_socket::start(port).await {
|
||||
if start(port).await {
|
||||
log_message(format("community_active", &[&port.to_string()]));
|
||||
} else {
|
||||
if port < 1024 {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||
use crate::gui::log_panel::{log_cv, log_message};
|
||||
use crate::gui::log_panel::{log_cv, log_message, log_message_trans};
|
||||
use crate::langu::language_manager::format;
|
||||
use crate::users::contact::Contact;
|
||||
use crate::users::user_community_util::UserCommunityUtil;
|
||||
use crate::util::chat_files;
|
||||
|
|
@ -16,6 +17,7 @@ use tokio::time::{Duration, Instant, sleep};
|
|||
use tokio_tungstenite::{
|
||||
MaybeTlsStream, WebSocketStream, connect_async, tungstenite::protocol::Message,
|
||||
};
|
||||
use tungstenite::Utf8Bytes;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -71,8 +73,8 @@ impl OmikronConnection {
|
|||
*self.pingpong.lock().await = Some(handle);
|
||||
break;
|
||||
}
|
||||
Err(_) => {
|
||||
log_message("CONNECTION FAILED");
|
||||
Err(e) => {
|
||||
log_message(format("connection_failed", &[&e.to_string().as_str()]));
|
||||
*self.is_connected.lock().await = false;
|
||||
sleep(Duration::from_secs(2)).await;
|
||||
}
|
||||
|
|
@ -80,7 +82,7 @@ impl OmikronConnection {
|
|||
}
|
||||
}
|
||||
pub async fn send_message(&self, msg: String) {
|
||||
Self::send_message_static(&self.writer, msg).await;
|
||||
Self::send_message_static(&self.writer, msg).await
|
||||
}
|
||||
|
||||
/// Listener for all incoming messages
|
||||
|
|
@ -90,28 +92,37 @@ impl OmikronConnection {
|
|||
WebSocketStream<MaybeTlsStream<TcpStream>>,
|
||||
>,
|
||||
) {
|
||||
let waiting = self.waiting.clone();
|
||||
let writer = self.writer.clone();
|
||||
let is_connected = self.is_connected.clone();
|
||||
let sel = self.clone();
|
||||
let waiting_out = self.waiting.clone();
|
||||
let writer_out = self.writer.clone();
|
||||
let is_connected_out = self.is_connected.clone();
|
||||
let sel_out = self.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some(msg) = read_half.next().await {
|
||||
let waiting = waiting_out.clone();
|
||||
let writer = writer_out.clone();
|
||||
let is_connected = is_connected_out.clone();
|
||||
let sel = sel_out.clone();
|
||||
tokio::spawn(async move {
|
||||
match msg {
|
||||
Ok(Message::Close(Some(frame))) => {
|
||||
log_message(format!("[Omikron] Closed: {:?}", frame));
|
||||
*is_connected.lock().await = false;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
Ok(Message::Text(text)) => {
|
||||
let mut cv = CommunicationValue::from_json(&text);
|
||||
if cv.is_type(CommunicationType::pong) {
|
||||
sel.handle_pong(&cv, true).await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
// ************************************************ //
|
||||
// Direct messages //
|
||||
// ************************************************ //
|
||||
log_cv(&cv);
|
||||
if let Some(x) = waiting.lock().await.remove(&cv.get_id()) {
|
||||
x(cv);
|
||||
return;
|
||||
}
|
||||
if cv.is_type(CommunicationType::message_other_iota) {
|
||||
let sender_id = &cv.get_sender().unwrap();
|
||||
let receiver_id = &cv.get_receiver().unwrap();
|
||||
|
|
@ -126,7 +137,8 @@ impl OmikronConnection {
|
|||
*sender_id,
|
||||
cv.get_data(DataTypes::content).unwrap().as_str().unwrap(),
|
||||
);
|
||||
let response = CommunicationValue::new(CommunicationType::message_live)
|
||||
let response =
|
||||
CommunicationValue::new(CommunicationType::message_live)
|
||||
.with_id(cv.get_id())
|
||||
.with_receiver(cv.get_receiver().unwrap())
|
||||
.add_data(
|
||||
|
|
@ -146,22 +158,10 @@ impl OmikronConnection {
|
|||
response.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::message_send) {
|
||||
/* DATA CONTAINER:
|
||||
"sent_by_self": true,
|
||||
"timestamp": unixTimestamp,
|
||||
"files": [ // wenn keine files dann weglassen
|
||||
{
|
||||
"name": "<name>",
|
||||
"id": "<uuid>",
|
||||
"type": "[ image | image_top_right | file ]"
|
||||
}
|
||||
],
|
||||
"content": "<enc markdown>"
|
||||
*/
|
||||
let my_id = cv.get_sender().unwrap();
|
||||
let other_id = Uuid::from_str(
|
||||
&*cv.get_data(DataTypes::receiver_id).unwrap().to_string(),
|
||||
|
|
@ -177,8 +177,13 @@ impl OmikronConnection {
|
|||
other_id,
|
||||
&*cv.get_data(DataTypes::content).unwrap().to_string(),
|
||||
);
|
||||
let ack = CommunicationValue::ack_message(cv.get_id(), my_id);
|
||||
Self::send_message_static(&writer.clone(), ack.to_json().to_string())
|
||||
let ack = CommunicationValue::new(CommunicationType::message)
|
||||
.with_id(cv.get_id())
|
||||
.with_receiver(my_id);
|
||||
Self::send_message_static(
|
||||
&writer.clone(),
|
||||
ack.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
let forward = CommunicationValue::forward_to_other_iota(&mut cv);
|
||||
Self::send_message_static(
|
||||
|
|
@ -186,7 +191,7 @@ impl OmikronConnection {
|
|||
forward.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::messages_get) {
|
||||
|
|
@ -214,9 +219,12 @@ impl OmikronConnection {
|
|||
.with_receiver(my_id)
|
||||
.add_data(DataTypes::messages, messages);
|
||||
|
||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||
Self::send_message_static(
|
||||
&writer.clone(),
|
||||
resp.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::get_chats) {
|
||||
|
|
@ -226,9 +234,12 @@ impl OmikronConnection {
|
|||
.with_id(cv.get_id())
|
||||
.with_receiver(user_id)
|
||||
.add_data(DataTypes::user_ids, users);
|
||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||
Self::send_message_static(
|
||||
&writer.clone(),
|
||||
resp.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::add_chat) {
|
||||
|
|
@ -249,9 +260,12 @@ impl OmikronConnection {
|
|||
let resp = CommunicationValue::new(CommunicationType::add_chat)
|
||||
.with_id(cv.get_id())
|
||||
.with_receiver(user_id);
|
||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||
Self::send_message_static(
|
||||
&writer.clone(),
|
||||
resp.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::add_community) {
|
||||
|
|
@ -263,25 +277,35 @@ impl OmikronConnection {
|
|||
cv.get_data(DataTypes::community_title).unwrap().to_string(),
|
||||
cv.get_data(DataTypes::position).unwrap().to_string(),
|
||||
);
|
||||
let resp = CommunicationValue::new(CommunicationType::add_community)
|
||||
let resp =
|
||||
CommunicationValue::new(CommunicationType::add_community)
|
||||
.with_id(cv.get_id())
|
||||
.with_receiver(cv.get_sender().unwrap());
|
||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||
Self::send_message_static(
|
||||
&writer.clone(),
|
||||
resp.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::get_communities) {
|
||||
let resp = CommunicationValue::new(CommunicationType::get_communities)
|
||||
let resp =
|
||||
CommunicationValue::new(CommunicationType::get_communities)
|
||||
.with_id(cv.get_id())
|
||||
.with_receiver(cv.get_sender().unwrap())
|
||||
.add_array(
|
||||
DataTypes::communities,
|
||||
UserCommunityUtil::get_communities(cv.get_sender().unwrap()),
|
||||
UserCommunityUtil::get_communities(
|
||||
cv.get_sender().unwrap(),
|
||||
),
|
||||
);
|
||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||
Self::send_message_static(
|
||||
&writer.clone(),
|
||||
resp.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if cv.is_type(CommunicationType::remove_community) {
|
||||
|
|
@ -291,21 +315,26 @@ impl OmikronConnection {
|
|||
.unwrap()
|
||||
.to_string(),
|
||||
); // needs UserCommunityUtil
|
||||
let resp = CommunicationValue::new(CommunicationType::remove_community)
|
||||
let resp =
|
||||
CommunicationValue::new(CommunicationType::remove_community)
|
||||
.with_id(cv.get_id())
|
||||
.with_receiver(cv.get_sender().unwrap());
|
||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||
Self::send_message_static(
|
||||
&writer.clone(),
|
||||
resp.to_json().to_string(),
|
||||
)
|
||||
.await;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log_message(format!("[Omikron] Error: {}", e));
|
||||
*is_connected.lock().await = false;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -324,8 +353,12 @@ impl OmikronConnection {
|
|||
) {
|
||||
let mut guard = writer.lock().await;
|
||||
if let Some(writer) = guard.as_mut() {
|
||||
writer.send(Message::Text(msg)).await;
|
||||
writer.flush().await;
|
||||
if let Ok(_) = writer.send(Message::Text(Utf8Bytes::from(msg))).await {
|
||||
if let Ok(_) = writer.flush().await {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
log_message_trans("send_message_failed");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
use crate::APP_STATE;
|
||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||
use crate::omikron::omikron_connection::OmikronConnection;
|
||||
use json::JsonValue;
|
||||
use json::number::Number;
|
||||
use std::sync::Arc;
|
||||
use tokio::time::Instant;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
|
|
|||
1
src/server/mod.rs
Normal file
1
src/server/mod.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod socket;
|
||||
|
|
@ -1,9 +1,15 @@
|
|||
use crate::communities::{community_connection::CommunityConnection, community_manager};
|
||||
use futures::StreamExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_tungstenite::{WebSocketStream, accept_hdr_async, tungstenite::protocol::Message};
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tungstenite::accept_hdr_async;
|
||||
use tungstenite::handshake::server::{Request, Response};
|
||||
use tokio_util::compat::{Compat, TokioAsyncReadCompatExt};
|
||||
use tungstenite::connect;
|
||||
use tungstenite::{
|
||||
Utf8Bytes,
|
||||
handshake::server::{Request, Response},
|
||||
};
|
||||
|
||||
pub async fn start(port: u16) -> bool {
|
||||
let listener = TcpListener::bind(format!("0.0.0.0:{}", port)).await;
|
||||
|
|
@ -19,20 +25,21 @@ pub async fn start(port: u16) -> bool {
|
|||
path = format!("{}", &req.uri().path());
|
||||
Ok(response)
|
||||
};
|
||||
let ws_stream = match accept_hdr_async(stream, callback).await {
|
||||
let ws_stream = match accept_hdr_async(stream.compat(), callback).await {
|
||||
Ok(ws) => ws,
|
||||
Err(e) => {
|
||||
Err(_) => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let (reader, writer) = ws_stream.split();
|
||||
if path.starts_with("/community/") {
|
||||
let community_id = path.split("/").nth(2).unwrap();
|
||||
if let Some(community) = community_manager::get_community(community_id).await {
|
||||
let community_conn: Arc<CommunityConnection> =
|
||||
Arc::from(CommunityConnection::new(ws_stream, community));
|
||||
Arc::from(CommunityConnection::new(reader, writer, community));
|
||||
loop {
|
||||
let msg_result = {
|
||||
let mut session_lock = community_conn.session.lock().await;
|
||||
let mut session_lock = community_conn.receiver.write().await;
|
||||
session_lock.next().await
|
||||
};
|
||||
|
||||
|
|
@ -40,13 +47,16 @@ pub async fn start(port: u16) -> bool {
|
|||
Some(Ok(msg)) => {
|
||||
if msg.is_text() {
|
||||
let text = msg.into_text().unwrap();
|
||||
community_conn.clone().handle_message(text).await;
|
||||
community_conn
|
||||
.clone()
|
||||
.handle_message(text.to_string())
|
||||
.await;
|
||||
} else if msg.is_close() {
|
||||
community_conn.handle_close().await;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
Some(Err(_)) => {
|
||||
community_conn.handle_close().await;
|
||||
return;
|
||||
}
|
||||
|
|
@ -7,18 +7,6 @@ pub struct Contact {
|
|||
pub user_id: Option<Uuid>,
|
||||
pub user_name: Option<String>,
|
||||
pub last_message_at: Option<i64>,
|
||||
pub user_status: UserStatus,
|
||||
pub about: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum UserStatus {
|
||||
Online,
|
||||
Do_Not_Disturb,
|
||||
WC,
|
||||
Away,
|
||||
User_Offline,
|
||||
Iota_Offline,
|
||||
}
|
||||
|
||||
impl Default for Contact {
|
||||
|
|
@ -31,30 +19,16 @@ impl Default for Contact {
|
|||
user_id: None,
|
||||
user_name: None,
|
||||
last_message_at: Some(now),
|
||||
user_status: UserStatus::User_Offline,
|
||||
about: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Contact {
|
||||
pub fn new_with_time(last_message_at: i64, user_id: Uuid) -> Self {
|
||||
Contact {
|
||||
user_id: Some(user_id),
|
||||
user_name: None,
|
||||
last_message_at: Some(last_message_at),
|
||||
user_status: UserStatus::User_Offline,
|
||||
about: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(user_id: Uuid) -> Self {
|
||||
Contact {
|
||||
user_id: Some(user_id),
|
||||
user_name: None,
|
||||
last_message_at: None,
|
||||
user_status: UserStatus::User_Offline,
|
||||
about: None,
|
||||
}
|
||||
}
|
||||
pub fn set_last_message_at(&mut self, p0: i64) {
|
||||
|
|
@ -74,12 +48,6 @@ impl Contact {
|
|||
}
|
||||
obj
|
||||
}
|
||||
|
||||
pub fn from_string(s: &str) -> Contact {
|
||||
let parsed: JsonValue = JsonValue::from(s);
|
||||
Self::from_json(&parsed)
|
||||
}
|
||||
|
||||
pub fn from_json(o: &JsonValue) -> Contact {
|
||||
let user_id = o["user_id"].as_str().and_then(|s| Uuid::parse_str(s).ok());
|
||||
|
||||
|
|
@ -91,51 +59,6 @@ impl Contact {
|
|||
user_id,
|
||||
user_name,
|
||||
last_message_at,
|
||||
user_status: UserStatus::User_Offline, // default
|
||||
about: None,
|
||||
}
|
||||
}
|
||||
pub fn info(&self) -> JsonValue {
|
||||
let mut obj = self.to_json();
|
||||
if let Some(id) = &self.user_id {
|
||||
obj["user_id"] = JsonValue::from(id.to_string());
|
||||
}
|
||||
if let Some(name) = &self.user_name {
|
||||
obj["user_name"] = JsonValue::from(name.as_str());
|
||||
}
|
||||
obj
|
||||
}
|
||||
|
||||
// getters & setters
|
||||
pub fn get_about(&self) -> Option<&String> {
|
||||
self.about.as_ref()
|
||||
}
|
||||
|
||||
pub fn set_about(&mut self, about: String) {
|
||||
self.about = Some(about);
|
||||
}
|
||||
|
||||
pub fn get_user_id(&self) -> Option<Uuid> {
|
||||
self.user_id
|
||||
}
|
||||
|
||||
pub fn set_user_id(&mut self, id: Uuid) {
|
||||
self.user_id = Some(id);
|
||||
}
|
||||
|
||||
pub fn get_user_name(&self) -> Option<&String> {
|
||||
self.user_name.as_ref()
|
||||
}
|
||||
|
||||
pub fn set_user_name(&mut self, name: String) {
|
||||
self.user_name = Some(name);
|
||||
}
|
||||
|
||||
pub fn get_user_status(&self) -> &UserStatus {
|
||||
&self.user_status
|
||||
}
|
||||
|
||||
pub fn set_user_status(&mut self, status: UserStatus) {
|
||||
self.user_status = status;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,13 +75,6 @@ pub fn get_users() -> Vec<UserProfile> {
|
|||
USERS.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn add_user(up: UserProfile) {
|
||||
let mut users = USERS.lock().unwrap();
|
||||
users.retain(|u| u.user_id != up.user_id);
|
||||
users.push(up);
|
||||
*UNIQUE.lock().unwrap() = true;
|
||||
}
|
||||
|
||||
pub fn remove_user(user_id: Uuid) {
|
||||
let mut users = USERS.lock().unwrap();
|
||||
users.retain(|u| u.user_id != user_id);
|
||||
|
|
|
|||
|
|
@ -45,11 +45,7 @@ impl ConfigUtil {
|
|||
|
||||
pub fn update(&mut self) {
|
||||
if self.unique {
|
||||
let _ = self.save();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
save_file("", "config.json", &self.config.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue