Fixes Patches Creation & More
Working with files / Paths fixed Websocket PingPongs (There is no data behind this just PingPong) Storing User Profiles correctly Added necessary dependencies and initial code support for: - X.509 certificate handling via x509/pkcs8 crates - Key generation and crypto operations via x448/sha2 - Structured hex encoding and base64 encoding
This commit is contained in:
parent
bba3f548ab
commit
0d07ddf851
23 changed files with 887 additions and 266 deletions
214
Cargo.lock
generated
214
Cargo.lock
generated
|
|
@ -12,20 +12,27 @@ dependencies = [
|
||||||
"cmake",
|
"cmake",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"crossterm 0.29.0",
|
"crossterm 0.29.0",
|
||||||
|
"der",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"hex",
|
||||||
"json",
|
"json",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"pkcs8",
|
||||||
"rand",
|
"rand",
|
||||||
|
"rand_core 0.6.4",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rustls",
|
"rustls",
|
||||||
"serde",
|
"serde",
|
||||||
|
"sha2",
|
||||||
"sys-info",
|
"sys-info",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-tungstenite",
|
"tokio-tungstenite",
|
||||||
"uuid",
|
"uuid",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
|
"x448",
|
||||||
|
"x509",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -49,6 +56,15 @@ version = "0.2.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
|
@ -136,6 +152,12 @@ version = "0.22.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64ct"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.4"
|
version = "2.9.4"
|
||||||
|
|
@ -200,6 +222,19 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link 0.2.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cmake"
|
name = "cmake"
|
||||||
version = "0.1.54"
|
version = "0.1.54"
|
||||||
|
|
@ -250,6 +285,12 @@ dependencies = [
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-oid"
|
||||||
|
version = "0.9.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
|
@ -259,6 +300,15 @@ dependencies = [
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie-factory"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2"
|
||||||
|
dependencies = [
|
||||||
|
"futures",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
|
@ -378,6 +428,16 @@ version = "2.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "der"
|
||||||
|
version = "0.7.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||||
|
dependencies = [
|
||||||
|
"const-oid",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deranged"
|
name = "deranged"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
|
@ -438,6 +498,17 @@ dependencies = [
|
||||||
"litrs",
|
"litrs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ed448-goldilocks"
|
||||||
|
version = "0.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87b5fa9e9e3dd5fe1369f380acd3dcdfa766dbd0a1cd5b048fb40e38a6a78e79"
|
||||||
|
dependencies = [
|
||||||
|
"fiat-crypto",
|
||||||
|
"hex",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
|
|
@ -485,6 +556,12 @@ version = "2.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fiat-crypto"
|
||||||
|
version = "0.1.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -527,6 +604,21 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-io",
|
||||||
|
"futures-sink",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
|
|
@ -534,6 +626,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -542,6 +635,23 @@ version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-executor"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-task",
|
||||||
|
"futures-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-io"
|
||||||
|
version = "0.3.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.31"
|
version = "0.3.31"
|
||||||
|
|
@ -571,10 +681,13 @@ version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
"futures-macro",
|
"futures-macro",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
"slab",
|
"slab",
|
||||||
|
|
@ -655,6 +768,12 @@ version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
|
@ -782,6 +901,30 @@ dependencies = [
|
||||||
"windows-registry",
|
"windows-registry",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone-haiku"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
|
@ -1120,6 +1263,15 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_threads"
|
name = "num_threads"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
|
@ -1260,6 +1412,16 @@ version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkcs8"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
|
||||||
|
dependencies = [
|
||||||
|
"der",
|
||||||
|
"spki",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
|
|
@ -1322,7 +1484,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1332,9 +1494,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.6.4"
|
version = "0.6.4"
|
||||||
|
|
@ -1619,6 +1787,17 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.10.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
|
@ -1686,6 +1865,16 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spki"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"der",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
|
@ -2645,6 +2834,27 @@ version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x448"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80139292cd89162e90853c1474945705aeb6b18073e857a8155f186aece9e456"
|
||||||
|
dependencies = [
|
||||||
|
"ed448-goldilocks",
|
||||||
|
"hex",
|
||||||
|
"rand_core 0.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "x509"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3cec94c3999f31341553f358ef55f65fc031291a022cd42ec0ce7219560c76"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"cookie-factory",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,14 @@ bytes = "*"
|
||||||
crossterm = "*"
|
crossterm = "*"
|
||||||
color-eyre = "*"
|
color-eyre = "*"
|
||||||
sys-info = "*"
|
sys-info = "*"
|
||||||
rand = "0.8.5"
|
rand = "0.8"
|
||||||
|
rand_core = { version = "0.6", features = ["getrandom", "std"] }
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
once_cell = "1.21.3"
|
once_cell = "1.21.3"
|
||||||
reqwest = "0.12.23"
|
reqwest = "0.12.23"
|
||||||
|
x448 = { version = "*" }
|
||||||
|
hex = "*"
|
||||||
|
x509 = "*"
|
||||||
|
sha2 = "*"
|
||||||
|
der = "*"
|
||||||
|
pkcs8 = { version = "*", features = ["alloc"] }
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
use std::time::Duration;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use uuid::Uuid;
|
|
||||||
use reqwest::header::CONTENT_TYPE;
|
|
||||||
use json::JsonValue;
|
|
||||||
use reqwest::{Client, Response};
|
|
||||||
use crate::users::user_profile::UserProfile;
|
|
||||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||||
|
use crate::users::user_profile::UserProfile;
|
||||||
|
use hex;
|
||||||
|
use json::JsonValue;
|
||||||
|
use reqwest::header::CONTENT_TYPE;
|
||||||
|
use reqwest::{Client, Response};
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::time::Duration;
|
||||||
|
use uuid::Uuid;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AuthUser {
|
pub struct AuthUser {
|
||||||
pub created_at: i64,
|
pub created_at: i64,
|
||||||
|
|
@ -32,23 +33,29 @@ impl AuthConnector {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn unregister_user(user_id: Uuid, reset_token: &str) -> Option<bool> {
|
pub async fn unregister_user(user_id: Uuid, reset_token: &str) -> Option<bool> {
|
||||||
let url = format!("https:/auth.tensamin.methanium.net//api/delete/{}/", user_id);
|
let url = format!("https:/auth.tensamin.methanium.net/api/delete/{}/", user_id);
|
||||||
let client = Self::client();
|
let client = Self::client();
|
||||||
|
|
||||||
let mut payload = JsonValue::new_object();
|
let mut payload = JsonValue::new_object();
|
||||||
payload["reset_token"] = reset_token.into();
|
payload["reset_token"] = reset_token.into();
|
||||||
|
|
||||||
let res = client.post(&url)
|
let res = client
|
||||||
|
.post(&url)
|
||||||
.header(CONTENT_TYPE, "application/json")
|
.header(CONTENT_TYPE, "application/json")
|
||||||
.body(payload.dump()).send().await.ok()?;
|
.body(payload.dump())
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.ok()?;
|
||||||
let json = res.text().await.ok()?;
|
let json = res.text().await.ok()?;
|
||||||
let cv = CommunicationValue::from_json(&json);
|
let cv = CommunicationValue::from_json(&json);
|
||||||
Option::from(cv.is_type(CommunicationType::Success))
|
Option::from(cv.is_type(CommunicationType::Success))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_uuid(username: &str) -> Option<Uuid> {
|
pub async fn get_uuid(username: &str) -> Option<Uuid> {
|
||||||
let url = format!("https://auth.tensamin.methanium.net/api/get/uuid/{}/", username);
|
let url = format!(
|
||||||
|
"https://auth.tensamin.methanium.net/api/get/uuid/{}/",
|
||||||
|
username
|
||||||
|
);
|
||||||
let client = Self::client();
|
let client = Self::client();
|
||||||
let res = client.get(&url).send().await.ok()?;
|
let res = client.get(&url).send().await.ok()?;
|
||||||
let json = res.text().await.ok()?;
|
let json = res.text().await.ok()?;
|
||||||
|
|
@ -71,15 +78,30 @@ impl AuthConnector {
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(AuthUser {
|
Some(AuthUser {
|
||||||
created_at: cv.get_data(DataTypes::CreatedAt).unwrap().to_string().parse::<i64>().unwrap_or(-1),
|
created_at: cv
|
||||||
|
.get_data(DataTypes::CreatedAt)
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
.parse::<i64>()
|
||||||
|
.unwrap_or(-1),
|
||||||
username: cv.get_data(DataTypes::Username).unwrap().to_string(),
|
username: cv.get_data(DataTypes::Username).unwrap().to_string(),
|
||||||
display: cv.get_data(DataTypes::Display).unwrap().to_string(),
|
display: cv.get_data(DataTypes::Display).unwrap().to_string(),
|
||||||
avatar: cv.get_data(DataTypes::Avatar).unwrap().to_string(),
|
avatar: cv.get_data(DataTypes::Avatar).unwrap().to_string(),
|
||||||
about: cv.get_data(DataTypes::About).unwrap().to_string(),
|
about: cv.get_data(DataTypes::About).unwrap().to_string(),
|
||||||
status: cv.get_data(DataTypes::Status).unwrap().to_string(),
|
status: cv.get_data(DataTypes::Status).unwrap().to_string(),
|
||||||
public_key: cv.get_data(DataTypes::PublicKey).unwrap().to_string(),
|
public_key: cv.get_data(DataTypes::PublicKey).unwrap().to_string(),
|
||||||
sub_level: cv.get_data(DataTypes::SubLevel).unwrap().to_string().parse::<i32>().unwrap_or(-1),
|
sub_level: cv
|
||||||
sub_end: cv.get_data(DataTypes::SubEnd).unwrap().to_string().parse::<i32>().unwrap_or(-1),
|
.get_data(DataTypes::SubLevel)
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
.parse::<i32>()
|
||||||
|
.unwrap_or(-1),
|
||||||
|
sub_end: cv
|
||||||
|
.get_data(DataTypes::SubEnd)
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
.parse::<i32>()
|
||||||
|
.unwrap_or(-1),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,14 +130,16 @@ impl AuthConnector {
|
||||||
let res = client
|
let res = client
|
||||||
.post(url)
|
.post(url)
|
||||||
.header(CONTENT_TYPE, "application/json")
|
.header(CONTENT_TYPE, "application/json")
|
||||||
.body(payload.dump())
|
.body(payload.to_string())
|
||||||
.send()
|
.send()
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
match res {
|
println!("Status: {}", res.status());
|
||||||
Ok(resp) => Self::handle_response(resp).await,
|
let body = res.text().await.unwrap();
|
||||||
Err(_) => false,
|
println!("Response body:\n{}", body);
|
||||||
}
|
|
||||||
|
CommunicationValue::from_json(&body).is_type(CommunicationType::Success)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn migrate_user(user_profile: &mut UserProfile, iota_id: &str) -> bool {
|
pub async fn migrate_user(user_profile: &mut UserProfile, iota_id: &str) -> bool {
|
||||||
|
|
@ -152,6 +176,4 @@ impl AuthConnector {
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
use axum::Json;
|
||||||
|
use json::number::Number;
|
||||||
|
use json::{JsonValue, object, parse, stringify};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use json::{object, parse, stringify, JsonValue};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::env::VarsOs;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use axum::Json;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Eq, Hash, PartialEq, Debug)]
|
#[derive(Eq, Hash, PartialEq, Debug)]
|
||||||
|
|
@ -81,71 +83,71 @@ impl DataTypes {
|
||||||
let normalized = p0.to_lowercase().replace('_', "");
|
let normalized = p0.to_lowercase().replace('_', "");
|
||||||
|
|
||||||
match normalized.as_str() {
|
match normalized.as_str() {
|
||||||
"errortype" => DataTypes::ErrorType,
|
"errortype" => DataTypes::ErrorType,
|
||||||
"chatpartnerid" => DataTypes::ChatPartnerId,
|
"chatpartnerid" => DataTypes::ChatPartnerId,
|
||||||
"iotaid" => DataTypes::IotaId,
|
"iotaid" => DataTypes::IotaId,
|
||||||
"userid" => DataTypes::UserId,
|
"userid" => DataTypes::UserId,
|
||||||
"userids" => DataTypes::UserIds,
|
"userids" => DataTypes::UserIds,
|
||||||
"userstate" => DataTypes::UserState,
|
"userstate" => DataTypes::UserState,
|
||||||
"userstates" => DataTypes::UserStates,
|
"userstates" => DataTypes::UserStates,
|
||||||
"userpings" => DataTypes::UserPings,
|
"userpings" => DataTypes::UserPings,
|
||||||
"callstate" => DataTypes::CallState,
|
"callstate" => DataTypes::CallState,
|
||||||
"screenshare" => DataTypes::ScreenShare,
|
"screenshare" => DataTypes::ScreenShare,
|
||||||
"privatekeyhash" => DataTypes::PrivateKeyHash,
|
"privatekeyhash" => DataTypes::PrivateKeyHash,
|
||||||
"accepted" => DataTypes::Accepted,
|
"accepted" => DataTypes::Accepted,
|
||||||
"acceptedprofiles" => DataTypes::AcceptedProfiles,
|
"acceptedprofiles" => DataTypes::AcceptedProfiles,
|
||||||
"deniedprofiles" => DataTypes::DeniedProfiles,
|
"deniedprofiles" => DataTypes::DeniedProfiles,
|
||||||
"messagecontent" => DataTypes::MessageContent,
|
"messagecontent" => DataTypes::MessageContent,
|
||||||
"messagechunk" => DataTypes::MessageChunk,
|
"messagechunk" => DataTypes::MessageChunk,
|
||||||
"sendtime" => DataTypes::SendTime,
|
"sendtime" => DataTypes::SendTime,
|
||||||
"gettime" => DataTypes::GetTime,
|
"gettime" => DataTypes::GetTime,
|
||||||
"getvariant" => DataTypes::GetVariant,
|
"getvariant" => DataTypes::GetVariant,
|
||||||
"sharedsecretown" => DataTypes::SharedSecretOwn,
|
"sharedsecretown" => DataTypes::SharedSecretOwn,
|
||||||
"sharedsecretother"=> DataTypes::SharedSecretOther,
|
"sharedsecretother" => DataTypes::SharedSecretOther,
|
||||||
"sharedsecretsign" => DataTypes::SharedSecretSign,
|
"sharedsecretsign" => DataTypes::SharedSecretSign,
|
||||||
"sharedsecret" => DataTypes::SharedSecret,
|
"sharedsecret" => DataTypes::SharedSecret,
|
||||||
"callid" => DataTypes::CallId,
|
"callid" => DataTypes::CallId,
|
||||||
"callname" => DataTypes::CallName,
|
"callname" => DataTypes::CallName,
|
||||||
"callsecretsha" => DataTypes::CallSecretSha,
|
"callsecretsha" => DataTypes::CallSecretSha,
|
||||||
"callsecret" => DataTypes::CallSecret,
|
"callsecret" => DataTypes::CallSecret,
|
||||||
"sharedcallsecret" => DataTypes::SharedCallSecret,
|
"sharedcallsecret" => DataTypes::SharedCallSecret,
|
||||||
"startdate" => DataTypes::StartDate,
|
"startdate" => DataTypes::StartDate,
|
||||||
"enddate" => DataTypes::EndDate,
|
"enddate" => DataTypes::EndDate,
|
||||||
"receiverid" => DataTypes::ReceiverId,
|
"receiverid" => DataTypes::ReceiverId,
|
||||||
"senderid" => DataTypes::SenderId,
|
"senderid" => DataTypes::SenderId,
|
||||||
"signature" => DataTypes::Signature,
|
"signature" => DataTypes::Signature,
|
||||||
"signed" => DataTypes::Signed,
|
"signed" => DataTypes::Signed,
|
||||||
"message" => DataTypes::Message,
|
"message" => DataTypes::Message,
|
||||||
"lastping" => DataTypes::LastPing,
|
"lastping" => DataTypes::LastPing,
|
||||||
"pingiota" => DataTypes::PingIota,
|
"pingiota" => DataTypes::PingIota,
|
||||||
"pingclients" => DataTypes::PingClients,
|
"pingclients" => DataTypes::PingClients,
|
||||||
"matches" => DataTypes::Matches,
|
"matches" => DataTypes::Matches,
|
||||||
"omikron" => DataTypes::Omikron,
|
"omikron" => DataTypes::Omikron,
|
||||||
"loadedmessages" => DataTypes::LoadedMessages,
|
"loadedmessages" => DataTypes::LoadedMessages,
|
||||||
"messageamount" => DataTypes::MessageAmount,
|
"messageamount" => DataTypes::MessageAmount,
|
||||||
"position" => DataTypes::Position,
|
"position" => DataTypes::Position,
|
||||||
"name" => DataTypes::Name,
|
"name" => DataTypes::Name,
|
||||||
"path" => DataTypes::Path,
|
"path" => DataTypes::Path,
|
||||||
"codec" => DataTypes::Codec,
|
"codec" => DataTypes::Codec,
|
||||||
"function" => DataTypes::Function,
|
"function" => DataTypes::Function,
|
||||||
"payload" => DataTypes::Payload,
|
"payload" => DataTypes::Payload,
|
||||||
"result" => DataTypes::Result,
|
"result" => DataTypes::Result,
|
||||||
"interactables" => DataTypes::Interactables,
|
"interactables" => DataTypes::Interactables,
|
||||||
"wanttowatch" => DataTypes::WantToWatch,
|
"wanttowatch" => DataTypes::WantToWatch,
|
||||||
"watcher" => DataTypes::Watcher,
|
"watcher" => DataTypes::Watcher,
|
||||||
"createdat" => DataTypes::CreatedAt,
|
"createdat" => DataTypes::CreatedAt,
|
||||||
"username" => DataTypes::Username,
|
"username" => DataTypes::Username,
|
||||||
"display" => DataTypes::Display,
|
"display" => DataTypes::Display,
|
||||||
"avatar" => DataTypes::Avatar,
|
"avatar" => DataTypes::Avatar,
|
||||||
"about" => DataTypes::About,
|
"about" => DataTypes::About,
|
||||||
"status" => DataTypes::Status,
|
"status" => DataTypes::Status,
|
||||||
"publickey" => DataTypes::PublicKey,
|
"publickey" => DataTypes::PublicKey,
|
||||||
"sublevel" => DataTypes::SubLevel,
|
"sublevel" => DataTypes::SubLevel,
|
||||||
"subend" => DataTypes::SubEnd,
|
"subend" => DataTypes::SubEnd,
|
||||||
"communityaddress" => DataTypes::CommunityAddress,
|
"communityaddress" => DataTypes::CommunityAddress,
|
||||||
"challenge" => DataTypes::Challenge,
|
"challenge" => DataTypes::Challenge,
|
||||||
"communitytitle" => DataTypes::CommunityTitle,
|
"communitytitle" => DataTypes::CommunityTitle,
|
||||||
"communities" => DataTypes::Communities,
|
"communities" => DataTypes::Communities,
|
||||||
_ => DataTypes::ErrorType, // fallback if unknown
|
_ => DataTypes::ErrorType, // fallback if unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +155,7 @@ impl DataTypes {
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub enum CommunicationType {
|
pub enum CommunicationType {
|
||||||
Error,
|
Error,
|
||||||
Success,
|
Success,
|
||||||
Message,
|
Message,
|
||||||
MessageLive,
|
MessageLive,
|
||||||
|
|
@ -284,8 +286,8 @@ pub struct CommunicationValue {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub comm_type: CommunicationType,
|
pub comm_type: CommunicationType,
|
||||||
pub log_value: Option<LogValue>,
|
pub log_value: Option<LogValue>,
|
||||||
pub sender: Option<Uuid>,
|
pub sender: Uuid,
|
||||||
pub receiver: Option<Uuid>,
|
pub receiver: Uuid,
|
||||||
pub data: HashMap<DataTypes, JsonValue>,
|
pub data: HashMap<DataTypes, JsonValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,16 +297,16 @@ impl CommunicationValue {
|
||||||
id: Uuid::new_v4(),
|
id: Uuid::new_v4(),
|
||||||
comm_type,
|
comm_type,
|
||||||
log_value: None,
|
log_value: None,
|
||||||
sender: None,
|
sender: Uuid::new_v4(),
|
||||||
receiver: None,
|
receiver: Uuid::new_v4(),
|
||||||
data: HashMap::new(),
|
data: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn with_id(mut self, p0: Uuid) -> Self{
|
pub fn with_id(mut self, p0: Uuid) -> Self {
|
||||||
self.id = p0;
|
self.id = p0;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn get_id(&self) -> Uuid{
|
pub fn get_id(&self) -> Uuid {
|
||||||
self.id.clone()
|
self.id.clone()
|
||||||
}
|
}
|
||||||
pub fn with_log(mut self, log: LogValue) -> Self {
|
pub fn with_log(mut self, log: LogValue) -> Self {
|
||||||
|
|
@ -315,19 +317,23 @@ impl CommunicationValue {
|
||||||
&self.log_value
|
&self.log_value
|
||||||
}
|
}
|
||||||
pub fn with_sender(mut self, sender: Uuid) -> Self {
|
pub fn with_sender(mut self, sender: Uuid) -> Self {
|
||||||
self.sender = Some(sender);
|
self.sender = sender;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn get_sender(&self) -> Option<Uuid> {
|
pub fn get_sender(&self) -> Uuid {
|
||||||
self.sender.clone()
|
self.sender.clone()
|
||||||
}
|
}
|
||||||
pub fn with_receiver(mut self, receiver: Uuid) -> Self {
|
pub fn with_receiver(mut self, receiver: Uuid) -> Self {
|
||||||
self.receiver = Some(receiver);
|
self.receiver = receiver;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn get_receiver(&self) -> Option<Uuid> {
|
pub fn get_receiver(&self) -> Uuid {
|
||||||
self.receiver.clone()
|
self.receiver.clone()
|
||||||
}
|
}
|
||||||
|
pub fn add_data_num(mut self, key: DataTypes, value: Number) -> Self {
|
||||||
|
self.data.insert(key, JsonValue::Number(value));
|
||||||
|
self
|
||||||
|
}
|
||||||
pub fn add_data_str(mut self, key: DataTypes, value: String) -> Self {
|
pub fn add_data_str(mut self, key: DataTypes, value: String) -> Self {
|
||||||
self.data.insert(key, JsonValue::String(value));
|
self.data.insert(key, JsonValue::String(value));
|
||||||
self
|
self
|
||||||
|
|
@ -344,7 +350,7 @@ impl CommunicationValue {
|
||||||
self.comm_type == p0
|
self.comm_type == p0
|
||||||
}
|
}
|
||||||
pub fn to_json(&self) -> JsonValue {
|
pub fn to_json(&self) -> JsonValue {
|
||||||
let mut jdata = object!{};
|
let mut jdata = object! {};
|
||||||
for (k, v) in &self.data {
|
for (k, v) in &self.data {
|
||||||
jdata[&format!("{:?}", k)] = JsonValue::from(v.clone());
|
jdata[&format!("{:?}", k)] = JsonValue::from(v.clone());
|
||||||
}
|
}
|
||||||
|
|
@ -352,8 +358,8 @@ impl CommunicationValue {
|
||||||
object! {
|
object! {
|
||||||
id: self.id.to_string(),
|
id: self.id.to_string(),
|
||||||
type: format!("{:?}", self.comm_type),
|
type: format!("{:?}", self.comm_type),
|
||||||
sender: self.sender.map(|u| u.to_string()).unwrap_or_default(),
|
sender: self.sender.to_string(),
|
||||||
receiver: self.receiver.map(|u| u.to_string()).unwrap_or_default(),
|
receiver: self.receiver.to_string(),
|
||||||
log: self.log_value.as_ref().map(|l| l.clone().to_json()).unwrap_or(JsonValue::Null),
|
log: self.log_value.as_ref().map(|l| l.clone().to_json()).unwrap_or(JsonValue::Null),
|
||||||
data: jdata
|
data: jdata
|
||||||
}
|
}
|
||||||
|
|
@ -364,8 +370,14 @@ impl CommunicationValue {
|
||||||
|
|
||||||
let comm_type = CommunicationType::parse(parsed["type"].to_string());
|
let comm_type = CommunicationType::parse(parsed["type"].to_string());
|
||||||
|
|
||||||
let sender = parsed["sender"].as_str().and_then(|s| Uuid::parse_str(s).ok());
|
let sender: Uuid = parsed["sender"]
|
||||||
let receiver = parsed["receiver"].as_str().and_then(|s| Uuid::parse_str(s).ok());
|
.as_str()
|
||||||
|
.and_then(|s| Uuid::parse_str(s).ok())
|
||||||
|
.unwrap_or(Uuid::new_v4());
|
||||||
|
let receiver: Uuid = parsed["receiver"]
|
||||||
|
.as_str()
|
||||||
|
.and_then(|s| Uuid::parse_str(s).ok())
|
||||||
|
.unwrap_or(Uuid::new_v4());
|
||||||
|
|
||||||
let log_value = if parsed["log"].is_object() {
|
let log_value = if parsed["log"].is_object() {
|
||||||
Some(LogValue::new(
|
Some(LogValue::new(
|
||||||
|
|
@ -393,34 +405,45 @@ impl CommunicationValue {
|
||||||
data,
|
data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn ack_message(message_id: Uuid, sender: Option<Uuid>) -> CommunicationValue {
|
pub fn ack_message(message_id: Uuid, sender: Uuid) -> CommunicationValue {
|
||||||
let mut cv = CommunicationValue::new(CommunicationType::Message)
|
let mut cv = CommunicationValue::new(CommunicationType::Message).with_id(message_id);
|
||||||
.with_id(message_id);
|
|
||||||
|
|
||||||
if let Some(s) = sender {
|
if let s = sender {
|
||||||
cv = cv.add_data(DataTypes::SenderId, JsonValue::String(s.to_string()));
|
cv = cv.add_data(DataTypes::SenderId, JsonValue::String(s.to_string()));
|
||||||
}
|
}
|
||||||
cv
|
cv
|
||||||
}
|
}
|
||||||
pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue {
|
pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue {
|
||||||
let receiver = Uuid::from_str(&*original.get_data(DataTypes::ReceiverId).unwrap().to_string()).ok()
|
let receiver = Uuid::from_str(
|
||||||
.or(Option::from(Uuid::nil()));
|
&*original
|
||||||
|
.get_data(DataTypes::ReceiverId)
|
||||||
|
.unwrap()
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
.or(Option::from(Uuid::nil()));
|
||||||
|
|
||||||
let now_ms = SystemTime::now()
|
let now_ms = SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis() as i64;
|
.as_millis() as i64;
|
||||||
|
|
||||||
let mut cv = CommunicationValue::new(CommunicationType::MessageOtherIota)
|
let cv = CommunicationValue::new(CommunicationType::MessageOtherIota)
|
||||||
.with_id(original.get_id())
|
.with_id(original.get_id())
|
||||||
.with_receiver(receiver.unwrap())
|
.with_receiver(receiver.unwrap())
|
||||||
.add_data(DataTypes::SendTime, JsonValue::String(now_ms.to_string()))
|
.add_data(DataTypes::SendTime, JsonValue::String(now_ms.to_string()))
|
||||||
.add_data(DataTypes::MessageContent, JsonValue::String(original.get_data(DataTypes::MessageContent).unwrap().to_string()));
|
.add_data(
|
||||||
|
DataTypes::MessageContent,
|
||||||
|
JsonValue::String(
|
||||||
|
original
|
||||||
|
.get_data(DataTypes::MessageContent)
|
||||||
|
.unwrap()
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
// include sender_id if the original had one
|
// include sender_id if the original had one
|
||||||
if let Some(sender) = original.get_sender() {
|
let sender = original.get_sender();
|
||||||
cv = cv.add_data(DataTypes::SenderId, JsonValue::String(sender.to_string()));
|
cv.add_data(DataTypes::SenderId, JsonValue::String(sender.to_string()))
|
||||||
}
|
|
||||||
cv
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0
src/gui/log_panel.rs
Normal file
0
src/gui/log_panel.rs
Normal file
0
src/gui/settings_panel.rs
Normal file
0
src/gui/settings_panel.rs
Normal file
0
src/gui/user_panel.rs
Normal file
0
src/gui/user_panel.rs
Normal file
58
src/langu/language_creator.rs
Normal file
58
src/langu/language_creator.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
use crate::util::file_util::{self, save_file};
|
||||||
|
use json::{self, JsonValue};
|
||||||
|
|
||||||
|
pub fn create_languages() {
|
||||||
|
let mut frontend_messages = JsonValue::new_object();
|
||||||
|
let mut omikron_messages = JsonValue::new_object();
|
||||||
|
let mut button_texts = JsonValue::new_object();
|
||||||
|
let mut general_texts = JsonValue::new_object();
|
||||||
|
let mut debug_messages = JsonValue::new_object();
|
||||||
|
|
||||||
|
// FRONTEND
|
||||||
|
frontend_messages.insert(
|
||||||
|
"USER_CONTEXT_GET_CONVERSATIONS",
|
||||||
|
"User {} is loading conversations",
|
||||||
|
);
|
||||||
|
frontend_messages.insert(
|
||||||
|
"USER_CONTEXT_GET_COMMUNITIES",
|
||||||
|
"User {} is loading communities",
|
||||||
|
);
|
||||||
|
frontend_messages.insert("ADD_CONVERSATION", "User {} added {}");
|
||||||
|
|
||||||
|
// OMIKRON
|
||||||
|
omikron_messages.insert(
|
||||||
|
"IdentificationResponse",
|
||||||
|
"IOTA identified on Omikron, {} users!",
|
||||||
|
);
|
||||||
|
|
||||||
|
// BUTTONS
|
||||||
|
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: {}");
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
debug_messages.insert("", "");
|
||||||
|
save_file(
|
||||||
|
"languages/en_INT",
|
||||||
|
"frontend.json",
|
||||||
|
&frontend_messages.to_string(),
|
||||||
|
);
|
||||||
|
save_file(
|
||||||
|
"languages/en_INT",
|
||||||
|
"omikron.json",
|
||||||
|
&omikron_messages.to_string(),
|
||||||
|
);
|
||||||
|
save_file(
|
||||||
|
"languages/en_INT",
|
||||||
|
"buttons.json",
|
||||||
|
&button_texts.to_string(),
|
||||||
|
);
|
||||||
|
save_file(
|
||||||
|
"languages/en_INT",
|
||||||
|
"debug.json",
|
||||||
|
&debug_messages.to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
66
src/langu/language_manager.rs
Normal file
66
src/langu/language_manager.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
use crate::util::file_util::{self, load_file};
|
||||||
|
use json::{JsonValue, parse};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct LanguagePack {
|
||||||
|
languages: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Language packs need to have formatting
|
||||||
|
// Variables need to be provided
|
||||||
|
|
||||||
|
pub static LANGUAGE_PACK: Lazy<Mutex<LanguagePack>> =
|
||||||
|
Lazy::new(|| Mutex::new(LanguagePack::new("en_INT")));
|
||||||
|
|
||||||
|
pub fn get_language() -> LanguagePack {
|
||||||
|
LANGUAGE_PACK.lock().unwrap().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LanguagePack {
|
||||||
|
pub fn new(language: &str) -> Self {
|
||||||
|
let mut pack = LanguagePack {
|
||||||
|
languages: HashMap::new(),
|
||||||
|
};
|
||||||
|
pack.load_language(language);
|
||||||
|
pack
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_language(&mut self, language: &str) {
|
||||||
|
let path = format!("languages/{}/", language);
|
||||||
|
|
||||||
|
let frontend_messages = file_util::load_file(&path, "frontend.json");
|
||||||
|
let frontend_messages = parse(&frontend_messages).unwrap();
|
||||||
|
for (key, value) in frontend_messages.entries() {
|
||||||
|
self.languages
|
||||||
|
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let omikron_messages = file_util::load_file(&path, "omikron.json");
|
||||||
|
let omikron_messages = parse(&omikron_messages).unwrap();
|
||||||
|
for (key, value) in omikron_messages.entries() {
|
||||||
|
self.languages
|
||||||
|
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let button_texts = file_util::load_file(&path, "buttons.json");
|
||||||
|
let button_texts = parse(&button_texts).unwrap();
|
||||||
|
for (key, value) in button_texts.entries() {
|
||||||
|
self.languages
|
||||||
|
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let debug_messages = file_util::load_file(&path, "debug.json");
|
||||||
|
let debug_messages = parse(&debug_messages).unwrap();
|
||||||
|
for (key, value) in debug_messages.entries() {
|
||||||
|
self.languages
|
||||||
|
.insert(key.to_string(), value.as_str().unwrap().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_translation(&self, key: &str) -> &String {
|
||||||
|
self.languages.get(key).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/langu/mod.rs
Normal file
2
src/langu/mod.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod language_creator;
|
||||||
|
pub mod language_manager;
|
||||||
100
src/main.rs
100
src/main.rs
|
|
@ -1,59 +1,99 @@
|
||||||
|
use base64::Engine;
|
||||||
|
use base64::engine::general_purpose;
|
||||||
|
use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
|
||||||
use futures_util::SinkExt;
|
use futures_util::SinkExt;
|
||||||
use json::{self, JsonValue};
|
|
||||||
use json::JsonValue::String;
|
use json::JsonValue::String;
|
||||||
|
use json::{self, JsonValue};
|
||||||
|
use rand::Rng;
|
||||||
|
use rand_core::OsRng;
|
||||||
|
use rand_core::RngCore;
|
||||||
|
use reqwest::header::PUBLIC_KEY_PINS_REPORT_ONLY;
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::sync::Arc;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
use x448::{PublicKey, Secret};
|
||||||
|
|
||||||
mod data;
|
mod data;
|
||||||
mod omikron;
|
|
||||||
mod util;
|
|
||||||
mod users;
|
|
||||||
mod eula;
|
mod eula;
|
||||||
|
mod omikron;
|
||||||
|
mod users;
|
||||||
|
mod util;
|
||||||
mod gui {
|
mod gui {
|
||||||
pub mod ratatui_interface;
|
pub mod ratatui_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod auth;
|
mod auth;
|
||||||
|
mod langu;
|
||||||
|
use crate::auth::auth_connector::AuthConnector;
|
||||||
|
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||||
use crate::eula::*;
|
use crate::eula::*;
|
||||||
use crate::omikron::omikron_connection::{OmikronConnection};
|
use crate::langu::language_creator;
|
||||||
use crate::data::communication::{CommunicationValue, CommunicationType, DataTypes};
|
use crate::langu::language_manager;
|
||||||
|
use crate::omikron::omikron_connection::OmikronConnection;
|
||||||
|
use crate::omikron::ping_pong_task::PingPongTask;
|
||||||
use crate::users::user_manager::UserManager;
|
use crate::users::user_manager::UserManager;
|
||||||
use crate::util::config_util::ConfigUtil;
|
use crate::users::user_profile::UserProfile;
|
||||||
|
use crate::users::user_profile_full::UserProfileFull;
|
||||||
|
use crate::util::config_util::{self, CONFIG, ConfigUtil};
|
||||||
|
use crate::util::file_util;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
if(!eula_checker::check_eula()){
|
// EULA
|
||||||
println!("Please accept the end user license agreement before launching!");
|
//if !eula_checker::check_eula() {
|
||||||
return;
|
// println!("Please accept the end user license agreement before launching!");
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// LANGUAGE PACK
|
||||||
|
language_creator::create_languages();
|
||||||
|
|
||||||
|
// 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut c_util = ConfigUtil::new();
|
// USER MANAGEMENT
|
||||||
c_util.load();
|
|
||||||
if !c_util.config.has_key("iota_id") {
|
|
||||||
c_util.change("iota_id", Uuid::new_v4());
|
|
||||||
c_util.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UserManager::load_users().await;
|
UserManager::load_users().await;
|
||||||
|
|
||||||
let mut sb = "".to_string();
|
let mut sb = "".to_string();
|
||||||
for up in UserManager::get_users() {
|
for up in UserManager::get_users() {
|
||||||
sb = sb + "," + &*up.user_id.to_string();
|
sb = sb + "," + &up.user_id.to_string().as_str();
|
||||||
}
|
}
|
||||||
|
sb.remove(0);
|
||||||
|
println!(
|
||||||
|
"IOTA ID: {}-####-####-####-############",
|
||||||
|
CONFIG
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_iota_id()
|
||||||
|
.to_string()
|
||||||
|
.split("-")
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
);
|
||||||
|
println!("User ID: {}", sb);
|
||||||
|
|
||||||
UserManager::save_users();
|
// IDENTIFICATION ON OMIKRON
|
||||||
let omikron: OmikronConnection = OmikronConnection::new();
|
let omikron: OmikronConnection = OmikronConnection::new();
|
||||||
omikron.connect().await;
|
omikron.connect().await;
|
||||||
omikron.send_message(
|
let _ping_pong_task = PingPongTask::new(Arc::new(OmikronConnection::new()));
|
||||||
CommunicationValue::new(
|
omikron
|
||||||
CommunicationType::Identification
|
.send_message(
|
||||||
|
CommunicationValue::new(CommunicationType::Identification)
|
||||||
|
.add_data(DataTypes::UserIds, String(sb.to_string()))
|
||||||
|
.add_data(
|
||||||
|
DataTypes::IotaId,
|
||||||
|
String(CONFIG.lock().unwrap().get_iota_id().to_string()),
|
||||||
|
)
|
||||||
|
.to_json()
|
||||||
|
.to_string()
|
||||||
|
.as_mut()
|
||||||
|
.to_string(),
|
||||||
)
|
)
|
||||||
.add_data(DataTypes::UserIds, String(sb.to_string()))
|
.await;
|
||||||
.add_data(DataTypes::IotaId, String(c_util.config["iota_id"].to_string()))
|
|
||||||
.to_json()
|
|
||||||
.to_string()
|
|
||||||
.as_mut()
|
|
||||||
.to_string()
|
|
||||||
).await;
|
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
pub mod omikron_connection;
|
pub mod omikron_connection;
|
||||||
|
pub mod ping_pong_task;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||||
|
use crate::omikron::ping_pong_task::PingPongTask;
|
||||||
use crate::users::contact::Contact;
|
use crate::users::contact::Contact;
|
||||||
use crate::users::user_community_util::UserCommunityUtil;
|
use crate::users::user_community_util::UserCommunityUtil;
|
||||||
use crate::util::chat_files::ChatFiles;
|
use crate::util::chat_files::ChatFiles;
|
||||||
use crate::util::chats_util::{get_user, get_users, mod_user};
|
use crate::util::chats_util::{get_user, get_users, mod_user};
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
|
use json::number::Number;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
@ -50,6 +52,7 @@ impl OmikronConnection {
|
||||||
let (write_half, read_half) = ws_stream.split();
|
let (write_half, read_half) = ws_stream.split();
|
||||||
*self.writer.lock().await = Some(write_half);
|
*self.writer.lock().await = Some(write_half);
|
||||||
self.spawn_listener(read_half);
|
self.spawn_listener(read_half);
|
||||||
|
self.start_ping_pong_task().await;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -59,8 +62,22 @@ impl OmikronConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gracefully close connection
|
// Start the PingPongTask
|
||||||
pub async fn close(&self) {
|
pub async fn start_ping_pong_task(&self) {
|
||||||
|
let ping_pong_task = PingPongTask::new(Arc::new(self.clone()));
|
||||||
|
|
||||||
|
// Store the task handle in `pingpong` so we can manage it
|
||||||
|
let mut pingpong_handle = self.pingpong.lock().await;
|
||||||
|
*pingpong_handle = Some(tokio::spawn(async move {
|
||||||
|
ping_pong_task.run_ping_loop();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_message(&self, msg: String) {
|
||||||
|
Self::send_message_static(&self.writer, msg).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn disconnect(&self) {
|
||||||
if let Some(handle) = self.pingpong.lock().await.take() {
|
if let Some(handle) = self.pingpong.lock().await.take() {
|
||||||
handle.abort();
|
handle.abort();
|
||||||
}
|
}
|
||||||
|
|
@ -88,14 +105,14 @@ impl OmikronConnection {
|
||||||
}
|
}
|
||||||
Ok(Message::Text(text)) => {
|
Ok(Message::Text(text)) => {
|
||||||
let mut cv = CommunicationValue::from_json(&text); // needs CommunicationValue parser
|
let mut cv = CommunicationValue::from_json(&text); // needs CommunicationValue parser
|
||||||
println!("[Omikron] Received message: {:?}", cv);
|
|
||||||
if cv.is_type(CommunicationType::Pong) {
|
if cv.is_type(CommunicationType::Pong) {
|
||||||
println!("[Omikron] Pong received");
|
|
||||||
// handle pingpong reset here
|
// handle pingpong reset here
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
// ************************************************ //
|
// ************************************************ //
|
||||||
// Direct messages //
|
// Direct messages //
|
||||||
// ************************************************ //
|
// ************************************************ //
|
||||||
|
println!("[Omikron] Received message: {:?}", cv);
|
||||||
if cv.is_type(CommunicationType::MessageOtherIota) {
|
if cv.is_type(CommunicationType::MessageOtherIota) {
|
||||||
let sender_id = &cv.get_sender();
|
let sender_id = &cv.get_sender();
|
||||||
let receiver_id = &cv.get_receiver();
|
let receiver_id = &cv.get_receiver();
|
||||||
|
|
@ -105,8 +122,8 @@ impl OmikronConnection {
|
||||||
.as_i64()
|
.as_i64()
|
||||||
.unwrap_or(-1),
|
.unwrap_or(-1),
|
||||||
false,
|
false,
|
||||||
receiver_id.unwrap(),
|
*receiver_id,
|
||||||
sender_id.unwrap(),
|
*sender_id,
|
||||||
cv.get_data(DataTypes::MessageContent)
|
cv.get_data(DataTypes::MessageContent)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_str()
|
.as_str()
|
||||||
|
|
@ -114,7 +131,7 @@ impl OmikronConnection {
|
||||||
);
|
);
|
||||||
let response = CommunicationValue::new(CommunicationType::MessageLive)
|
let response = CommunicationValue::new(CommunicationType::MessageLive)
|
||||||
.with_id(cv.get_id())
|
.with_id(cv.get_id())
|
||||||
.with_receiver(cv.get_receiver().unwrap())
|
.with_receiver(cv.get_receiver())
|
||||||
.add_data(
|
.add_data(
|
||||||
DataTypes::SendTime,
|
DataTypes::SendTime,
|
||||||
cv.get_data(DataTypes::SendTime).unwrap().clone(),
|
cv.get_data(DataTypes::SendTime).unwrap().clone(),
|
||||||
|
|
@ -125,7 +142,7 @@ impl OmikronConnection {
|
||||||
)
|
)
|
||||||
.add_data(
|
.add_data(
|
||||||
DataTypes::SenderId,
|
DataTypes::SenderId,
|
||||||
JsonValue::String(cv.get_sender().unwrap().clone().to_string()),
|
JsonValue::String(cv.get_sender().clone().to_string()),
|
||||||
);
|
);
|
||||||
Self::send_message_static(
|
Self::send_message_static(
|
||||||
&writer.clone(),
|
&writer.clone(),
|
||||||
|
|
@ -143,7 +160,7 @@ impl OmikronConnection {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis() as i64,
|
.as_millis() as i64,
|
||||||
true,
|
true,
|
||||||
my_id.unwrap(),
|
my_id,
|
||||||
Uuid::from_str(
|
Uuid::from_str(
|
||||||
&*cv.get_data(DataTypes::ReceiverId).unwrap().to_string(),
|
&*cv.get_data(DataTypes::ReceiverId).unwrap().to_string(),
|
||||||
)
|
)
|
||||||
|
|
@ -165,23 +182,23 @@ impl OmikronConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
if cv.is_type(CommunicationType::MessageGet) {
|
if cv.is_type(CommunicationType::MessageGet) {
|
||||||
let my_id = cv.get_sender().unwrap();
|
let my_id = cv.get_sender();
|
||||||
let partner_id = Uuid::from_str(
|
let partner_id = Uuid::from_str(
|
||||||
&*cv.get_data(DataTypes::ChatPartnerId).unwrap().to_string(),
|
&*cv.get_data(DataTypes::ChatPartnerId).unwrap().to_string(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let offset = cv
|
let offset = cv
|
||||||
.get_data(DataTypes::LoadedMessages)
|
.get_data(DataTypes::LoadedMessages)
|
||||||
.unwrap()
|
.unwrap_or(&JsonValue::Null)
|
||||||
.to_string()
|
.to_string()
|
||||||
.parse::<i64>()
|
.parse::<i64>()
|
||||||
.unwrap();
|
.unwrap_or(0);
|
||||||
let amount = cv
|
let amount = cv
|
||||||
.get_data(DataTypes::MessageAmount)
|
.get_data(DataTypes::MessageAmount)
|
||||||
.unwrap()
|
.unwrap_or(&JsonValue::Null)
|
||||||
.to_string()
|
.to_string()
|
||||||
.parse::<i64>()
|
.parse::<i64>()
|
||||||
.unwrap();
|
.unwrap_or(0);
|
||||||
|
|
||||||
let messages =
|
let messages =
|
||||||
ChatFiles::get_messages(my_id, partner_id, offset, amount); // needs ChatFiles
|
ChatFiles::get_messages(my_id, partner_id, offset, amount); // needs ChatFiles
|
||||||
|
|
@ -198,11 +215,12 @@ impl OmikronConnection {
|
||||||
|
|
||||||
if cv.is_type(CommunicationType::GetChats) {
|
if cv.is_type(CommunicationType::GetChats) {
|
||||||
let user_id = cv.get_sender();
|
let user_id = cv.get_sender();
|
||||||
let users = get_users(user_id.unwrap()); // needs ChatsUtil
|
let users = get_users(user_id); // needs ChatsUtil
|
||||||
let resp = CommunicationValue::new(CommunicationType::GetChats)
|
let resp = CommunicationValue::new(CommunicationType::GetChats)
|
||||||
.with_id(cv.get_id())
|
.with_id(cv.get_id())
|
||||||
.with_receiver(user_id.unwrap())
|
.with_receiver(user_id)
|
||||||
.add_data(DataTypes::UserIds, users);
|
.add_data(DataTypes::UserIds, users);
|
||||||
|
println!("ALARM: {}", resp.to_json().to_string());
|
||||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||||
.await;
|
.await;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -214,18 +232,18 @@ impl OmikronConnection {
|
||||||
&*cv.get_data(DataTypes::UserId).unwrap().to_string(),
|
&*cv.get_data(DataTypes::UserId).unwrap().to_string(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut contact = get_user(user_id.unwrap(), other_id)
|
let mut contact =
|
||||||
.unwrap_or(Contact::new(other_id)); // needs ChatsUtil + Contact
|
get_user(user_id, other_id).unwrap_or(Contact::new(other_id)); // needs ChatsUtil + Contact
|
||||||
contact.set_last_message_at(
|
contact.set_last_message_at(
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis() as i64,
|
.as_millis() as i64,
|
||||||
);
|
);
|
||||||
mod_user(user_id.unwrap(), &contact);
|
mod_user(user_id, &contact);
|
||||||
let resp = CommunicationValue::new(CommunicationType::AddChat)
|
let resp = CommunicationValue::new(CommunicationType::AddChat)
|
||||||
.with_id(cv.get_id())
|
.with_id(cv.get_id())
|
||||||
.with_receiver(user_id.unwrap());
|
.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;
|
.await;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -233,7 +251,7 @@ impl OmikronConnection {
|
||||||
|
|
||||||
if cv.is_type(CommunicationType::AddCommunity) {
|
if cv.is_type(CommunicationType::AddCommunity) {
|
||||||
UserCommunityUtil::add_community(
|
UserCommunityUtil::add_community(
|
||||||
cv.get_sender().unwrap(),
|
cv.get_sender(),
|
||||||
cv.get_data(DataTypes::CommunityAddress)
|
cv.get_data(DataTypes::CommunityAddress)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
|
|
@ -242,7 +260,7 @@ impl OmikronConnection {
|
||||||
);
|
);
|
||||||
let resp = CommunicationValue::new(CommunicationType::AddCommunity)
|
let resp = CommunicationValue::new(CommunicationType::AddCommunity)
|
||||||
.with_id(cv.get_id())
|
.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())
|
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||||
.await;
|
.await;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -251,10 +269,10 @@ impl OmikronConnection {
|
||||||
if cv.is_type(CommunicationType::GetCommunities) {
|
if cv.is_type(CommunicationType::GetCommunities) {
|
||||||
let resp = CommunicationValue::new(CommunicationType::GetCommunities)
|
let resp = CommunicationValue::new(CommunicationType::GetCommunities)
|
||||||
.with_id(cv.get_id())
|
.with_id(cv.get_id())
|
||||||
.with_receiver(cv.get_sender().unwrap())
|
.with_receiver(cv.get_sender())
|
||||||
.add_data(
|
.add_data(
|
||||||
DataTypes::Communities,
|
DataTypes::Communities,
|
||||||
UserCommunityUtil::get_communities(cv.get_sender().unwrap()),
|
UserCommunityUtil::get_communities(cv.get_sender()),
|
||||||
); // needs UserCommunityUtil
|
); // needs UserCommunityUtil
|
||||||
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||||
.await;
|
.await;
|
||||||
|
|
@ -263,14 +281,14 @@ impl OmikronConnection {
|
||||||
|
|
||||||
if cv.is_type(CommunicationType::RemoveCommunity) {
|
if cv.is_type(CommunicationType::RemoveCommunity) {
|
||||||
UserCommunityUtil::remove_community(
|
UserCommunityUtil::remove_community(
|
||||||
cv.get_sender().unwrap(),
|
cv.get_sender(),
|
||||||
cv.get_data(DataTypes::CommunityAddress)
|
cv.get_data(DataTypes::CommunityAddress)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string(),
|
.to_string(),
|
||||||
); // needs UserCommunityUtil
|
); // needs UserCommunityUtil
|
||||||
let resp = CommunicationValue::new(CommunicationType::RemoveCommunity)
|
let resp = CommunicationValue::new(CommunicationType::RemoveCommunity)
|
||||||
.with_id(cv.get_id())
|
.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())
|
Self::send_message_static(&writer.clone(), resp.to_json().to_string())
|
||||||
.await;
|
.await;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -285,9 +303,6 @@ impl OmikronConnection {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
pub async fn send_message(&self, msg: String) {
|
|
||||||
Self::send_message_static(&self.writer, msg).await;
|
|
||||||
}
|
|
||||||
pub async fn send_message_static(
|
pub async fn send_message_static(
|
||||||
writer: &Arc<
|
writer: &Arc<
|
||||||
Mutex<
|
Mutex<
|
||||||
|
|
@ -322,10 +337,18 @@ impl OmikronConnection {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
pub async fn send_ping_message(&self, uuid: Uuid) {
|
||||||
async fn main() {
|
// Send the ping message over the connection
|
||||||
let conn = OmikronConnection::new();
|
let ping_message = CommunicationValue::new(CommunicationType::Ping)
|
||||||
conn.connect().await;
|
.with_id(uuid)
|
||||||
|
.add_data_num(DataTypes::LastPing, Number::from(2))
|
||||||
|
.to_json()
|
||||||
|
.to_string();
|
||||||
|
self.send_message(ping_message).await;
|
||||||
|
}
|
||||||
|
pub async fn reconnect(&self) {
|
||||||
|
self.disconnect().await;
|
||||||
|
self.connect().await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
116
src/omikron/ping_pong_task.rs
Normal file
116
src/omikron/ping_pong_task.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||||
|
use crate::omikron::omikron_connection::OmikronConnection;
|
||||||
|
use color_eyre::owo_colors::OwoColorize;
|
||||||
|
use futures_util::{SinkExt, StreamExt};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use tokio::time::{Duration, Instant, sleep};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct PingPongTask {
|
||||||
|
pub parent: Arc<OmikronConnection>, // assuming OmikronConnection is your connection type
|
||||||
|
pub message_send_times: Arc<Mutex<HashMap<Uuid, Instant>>>,
|
||||||
|
pub no_ping_in: Arc<Mutex<i32>>,
|
||||||
|
pub last_ping: Arc<Mutex<Option<u64>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PingPongTask {
|
||||||
|
pub fn new(parent: Arc<OmikronConnection>) -> Self {
|
||||||
|
let message_send_times = Arc::new(Mutex::new(HashMap::new()));
|
||||||
|
let no_ping_in = Arc::new(Mutex::new(-1));
|
||||||
|
let last_ping = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
|
let task = PingPongTask {
|
||||||
|
parent: parent.clone(),
|
||||||
|
message_send_times: message_send_times.clone(),
|
||||||
|
no_ping_in: no_ping_in.clone(),
|
||||||
|
last_ping: last_ping.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Spawn the periodic ping task
|
||||||
|
tokio::spawn({
|
||||||
|
let task = task.clone(); // Clone the task (Arc) so that it lives long enough for the async task
|
||||||
|
async move {
|
||||||
|
task.run_ping_loop().await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
task
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn run_ping_loop(&self) {
|
||||||
|
loop {
|
||||||
|
sleep(Duration::from_secs(5)).await;
|
||||||
|
self.send_ping().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_ping(&self) {
|
||||||
|
let uuid = Uuid::new_v4();
|
||||||
|
let send_time = Instant::now();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut message_send_times = self.message_send_times.lock().await;
|
||||||
|
message_send_times.insert(uuid, send_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
let no_ping_in = {
|
||||||
|
let no_ping_in = self.no_ping_in.lock().await;
|
||||||
|
*no_ping_in
|
||||||
|
};
|
||||||
|
|
||||||
|
if no_ping_in != -1 {
|
||||||
|
// Connection slow or disconnected
|
||||||
|
self.handle_slow_connection(no_ping_in).await;
|
||||||
|
} else {
|
||||||
|
// Connection is fine
|
||||||
|
self.parent.send_ping_message(uuid).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn handle_slow_connection(&self, no_ping_in: i32) {
|
||||||
|
if no_ping_in > 8 {
|
||||||
|
// Attempt reconnection if ping times out
|
||||||
|
self.parent.reconnect().await;
|
||||||
|
self.reconnect().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn reconnect(&self) {
|
||||||
|
let mut no_ping_in = self.no_ping_in.lock().await;
|
||||||
|
*no_ping_in = -1; // Reset slow count
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn handle_pong(&self, cv: &CommunicationValue) {
|
||||||
|
let send_time = {
|
||||||
|
let message_send_times = self.message_send_times.lock().await;
|
||||||
|
message_send_times.get(&cv.get_id()).cloned()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(send_time) = send_time {
|
||||||
|
let receive_time = Instant::now();
|
||||||
|
let ping = receive_time.duration_since(send_time).as_millis() as u64;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut last_ping = self.last_ping.lock().await;
|
||||||
|
*last_ping = Some(ping);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut no_ping_in = self.no_ping_in.lock().await;
|
||||||
|
*no_ping_in = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn cancel(&self) {
|
||||||
|
// Cancel or stop the task
|
||||||
|
let mut no_ping_in = self.no_ping_in.lock().await;
|
||||||
|
*no_ping_in = -1; // Reset the counter
|
||||||
|
|
||||||
|
// Example of stopping the ping task gracefully
|
||||||
|
// If using a task join handle or similar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,11 +14,11 @@ pub struct Contact {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum UserStatus {
|
pub enum UserStatus {
|
||||||
Online,
|
Online,
|
||||||
DoNotDisturb,
|
Do_Not_Disturb,
|
||||||
WC,
|
WC,
|
||||||
Away,
|
Away,
|
||||||
UserOffline,
|
User_Offline,
|
||||||
IotaOffline,
|
Iota_Offline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Contact {
|
impl Default for Contact {
|
||||||
|
|
@ -31,7 +31,7 @@ impl Default for Contact {
|
||||||
user_id: None,
|
user_id: None,
|
||||||
user_name: None,
|
user_name: None,
|
||||||
last_message_at: Some(now),
|
last_message_at: Some(now),
|
||||||
user_status: UserStatus::UserOffline,
|
user_status: UserStatus::User_Offline,
|
||||||
about: None,
|
about: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +43,7 @@ impl Contact {
|
||||||
user_id: Some(user_id),
|
user_id: Some(user_id),
|
||||||
user_name: None,
|
user_name: None,
|
||||||
last_message_at: Some(last_message_at),
|
last_message_at: Some(last_message_at),
|
||||||
user_status: UserStatus::UserOffline,
|
user_status: UserStatus::User_Offline,
|
||||||
about: None,
|
about: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,7 @@ impl Contact {
|
||||||
user_id: Some(user_id),
|
user_id: Some(user_id),
|
||||||
user_name: None,
|
user_name: None,
|
||||||
last_message_at: None,
|
last_message_at: None,
|
||||||
user_status: UserStatus::UserOffline,
|
user_status: UserStatus::User_Offline,
|
||||||
about: None,
|
about: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,13 +64,13 @@ impl Contact {
|
||||||
pub fn to_json(&self) -> JsonValue {
|
pub fn to_json(&self) -> JsonValue {
|
||||||
let mut obj = JsonValue::new_object();
|
let mut obj = JsonValue::new_object();
|
||||||
if let Some(id) = &self.user_id {
|
if let Some(id) = &self.user_id {
|
||||||
obj["userID"] = JsonValue::from(id.to_string());
|
obj["user_id"] = JsonValue::from(id.to_string());
|
||||||
}
|
}
|
||||||
if let Some(name) = &self.user_name {
|
if let Some(name) = &self.user_name {
|
||||||
obj["userName"] = JsonValue::from(name.as_str());
|
obj["user_name"] = JsonValue::from(name.as_str());
|
||||||
}
|
}
|
||||||
if let Some(ts) = &self.last_message_at {
|
if let Some(ts) = &self.last_message_at {
|
||||||
obj["lastMessageAt"] = JsonValue::from(ts.to_string());
|
obj["last_message_at"] = JsonValue::from(ts.to_string());
|
||||||
}
|
}
|
||||||
obj
|
obj
|
||||||
}
|
}
|
||||||
|
|
@ -81,29 +81,27 @@ impl Contact {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_json(o: &JsonValue) -> Contact {
|
pub fn from_json(o: &JsonValue) -> Contact {
|
||||||
let user_id = o["userID"]
|
let user_id = o["user_id"].as_str().and_then(|s| Uuid::parse_str(s).ok());
|
||||||
.as_str()
|
|
||||||
.and_then(|s| Uuid::parse_str(s).ok());
|
|
||||||
|
|
||||||
let user_name = o["userName"].as_str().map(|s| s.to_string());
|
let user_name = o["user_name"].as_str().map(|s| s.to_string());
|
||||||
|
|
||||||
let last_message_at = o["lastMessageAt"].as_i64();
|
let last_message_at = o["last_message_at"].as_i64();
|
||||||
|
|
||||||
Contact {
|
Contact {
|
||||||
user_id,
|
user_id,
|
||||||
user_name,
|
user_name,
|
||||||
last_message_at,
|
last_message_at,
|
||||||
user_status: UserStatus::UserOffline, // default
|
user_status: UserStatus::User_Offline, // default
|
||||||
about: None,
|
about: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn info(&self) -> JsonValue {
|
pub fn info(&self) -> JsonValue {
|
||||||
let mut obj = self.to_json();
|
let mut obj = self.to_json();
|
||||||
if let Some(id) = &self.user_id {
|
if let Some(id) = &self.user_id {
|
||||||
obj["userID"] = JsonValue::from(id.to_string());
|
obj["user_id"] = JsonValue::from(id.to_string());
|
||||||
}
|
}
|
||||||
if let Some(name) = &self.user_name {
|
if let Some(name) = &self.user_name {
|
||||||
obj["userName"] = JsonValue::from(name.as_str());
|
obj["user_name"] = JsonValue::from(name.as_str());
|
||||||
}
|
}
|
||||||
obj
|
obj
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
pub mod contact;
|
pub mod contact;
|
||||||
pub mod user_manager;
|
|
||||||
pub mod user_profile_full;
|
|
||||||
pub mod user_profile;
|
|
||||||
pub mod user_community_util;
|
pub mod user_community_util;
|
||||||
|
pub mod user_manager;
|
||||||
|
pub mod user_profile;
|
||||||
|
pub mod user_profile_full;
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,7 @@ use uuid::Uuid;
|
||||||
pub struct UserCommunityUtil;
|
pub struct UserCommunityUtil;
|
||||||
|
|
||||||
impl UserCommunityUtil {
|
impl UserCommunityUtil {
|
||||||
pub fn add_community(
|
pub fn add_community(storage_owner: Uuid, address: String, title: String, position: String) {
|
||||||
storage_owner: Uuid,
|
|
||||||
address: String,
|
|
||||||
title: String,
|
|
||||||
position: String,
|
|
||||||
) {
|
|
||||||
let path = format!("users/{}/communities.json", storage_owner);
|
let path = format!("users/{}/communities.json", storage_owner);
|
||||||
let mut communities: JsonValue = Self::load_array(&path);
|
let mut communities: JsonValue = Self::load_array(&path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,26 @@
|
||||||
use std::fs;
|
use crate::auth::auth_connector::AuthConnector;
|
||||||
use std::sync::Mutex;
|
|
||||||
use std::io;
|
|
||||||
use std::path::Path;
|
|
||||||
use uuid::Uuid;
|
|
||||||
use rand::Rng;
|
|
||||||
use rand::rngs::OsRng;
|
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
|
||||||
use json::{JsonValue};
|
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use crate::users::user_profile::UserProfile;
|
use crate::users::user_profile::UserProfile;
|
||||||
use crate::users::user_profile_full::UserProfileFull;
|
use crate::users::user_profile_full::UserProfileFull;
|
||||||
|
use crate::util::config_util::CONFIG;
|
||||||
use crate::util::file_util::{load_file, save_file};
|
use crate::util::file_util::{load_file, save_file};
|
||||||
|
use base64::{Engine as _, engine::general_purpose};
|
||||||
|
use der::DerOrd;
|
||||||
|
use hex;
|
||||||
|
use json::JsonValue;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use pkcs8::EncodePublicKey;
|
||||||
|
use pkcs8::spki::SubjectPublicKeyInfoOwned;
|
||||||
|
use pkcs8::{ObjectIdentifier, PrivateKeyInfo, SubjectPublicKeyInfo, der::Encode};
|
||||||
|
use rand::Rng;
|
||||||
|
use rand_core::OsRng;
|
||||||
|
use rand_core::RngCore;
|
||||||
|
use rustls::pki_types::SubjectPublicKeyInfoDer;
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
use std::io;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use uuid::Uuid;
|
||||||
|
use x448::{PublicKey, Secret};
|
||||||
|
use x509::AlgorithmIdentifier;
|
||||||
|
|
||||||
pub struct UserManager;
|
pub struct UserManager;
|
||||||
|
|
||||||
|
|
@ -18,14 +28,22 @@ static USERS: Lazy<Mutex<Vec<UserProfile>>> = Lazy::new(|| Mutex::new(Vec::new()
|
||||||
static UNIQUE: Lazy<Mutex<bool>> = Lazy::new(|| Mutex::new(false));
|
static UNIQUE: Lazy<Mutex<bool>> = Lazy::new(|| Mutex::new(false));
|
||||||
|
|
||||||
impl UserManager {
|
impl UserManager {
|
||||||
pub fn create_user(username: &str) -> Option<UserProfileFull> {
|
pub async fn create_user(username: &str) -> Option<UserProfileFull> {
|
||||||
// Stub: normally AuthConnector.getRegister() returns a UUID
|
let user_id = AuthConnector::get_register().await.unwrap();
|
||||||
let user_id = Uuid::new_v4();
|
let mut buf = [0u8; 56];
|
||||||
|
let mut rng = OsRng;
|
||||||
|
rng.fill_bytes(&mut buf);
|
||||||
|
let private_key = Secret::from_bytes(&buf).unwrap();
|
||||||
|
let public_key = PublicKey::from(&private_key);
|
||||||
|
|
||||||
// Stubbed: CryptoHelper.generateKeyPair()
|
let mut hasher = Sha256::new();
|
||||||
let public_key = general_purpose::STANDARD.encode(b"dummy-public");
|
hasher.update(
|
||||||
let private_key = general_purpose::STANDARD.encode(b"dummy-private");
|
&general_purpose::STANDARD
|
||||||
let private_key_hash = format!("hash-{}", &private_key);
|
.encode(&private_key.as_bytes())
|
||||||
|
.as_bytes(),
|
||||||
|
);
|
||||||
|
let result = hasher.finalize();
|
||||||
|
let private_key_hash = hex::encode(result);
|
||||||
|
|
||||||
let mut bytes = [0u8; 192];
|
let mut bytes = [0u8; 192];
|
||||||
OsRng.fill(bytes.as_mut());
|
OsRng.fill(bytes.as_mut());
|
||||||
|
|
@ -35,12 +53,27 @@ impl UserManager {
|
||||||
user_id,
|
user_id,
|
||||||
username.to_string(),
|
username.to_string(),
|
||||||
None,
|
None,
|
||||||
public_key,
|
general_purpose::STANDARD.encode(&public_key.as_bytes()),
|
||||||
private_key_hash,
|
private_key_hash,
|
||||||
reset_token,
|
reset_token,
|
||||||
);
|
);
|
||||||
|
|
||||||
let up_full = UserProfileFull { user_profile: up.clone(), private_key };
|
let up_full = UserProfileFull {
|
||||||
|
user_profile: up.clone(),
|
||||||
|
private_key: general_purpose::STANDARD.encode(&private_key.as_bytes()),
|
||||||
|
};
|
||||||
|
|
||||||
|
AuthConnector::complete_register(&up, &CONFIG.lock().unwrap().get_iota_id().to_string())
|
||||||
|
.await;
|
||||||
|
save_file(
|
||||||
|
"",
|
||||||
|
&format!("{}.tu", username),
|
||||||
|
&format!(
|
||||||
|
"{}::{}",
|
||||||
|
user_id,
|
||||||
|
general_purpose::STANDARD.encode(&private_key.as_bytes())
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
USERS.lock().unwrap().push(up);
|
USERS.lock().unwrap().push(up);
|
||||||
Self::save_users().ok();
|
Self::save_users().ok();
|
||||||
|
|
@ -48,7 +81,12 @@ impl UserManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_user(user_id: Uuid) -> Option<UserProfile> {
|
pub fn get_user(user_id: Uuid) -> Option<UserProfile> {
|
||||||
USERS.lock().unwrap().iter().cloned().find(|u| u.user_id == user_id)
|
USERS
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.find(|u| u.user_id == user_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_users() -> Vec<UserProfile> {
|
pub fn get_users() -> Vec<UserProfile> {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
use std::fs;
|
use crate::auth::auth_connector::AuthConnector;
|
||||||
use std::sync::Mutex;
|
use crate::users::user_manager::UserManager;
|
||||||
use std::collections::HashMap;
|
use base64::{Engine as _, engine::general_purpose};
|
||||||
use std::io;
|
use json::{JsonValue, object, stringify};
|
||||||
use std::path::Path;
|
|
||||||
use uuid::Uuid;
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use std::collections::HashMap;
|
||||||
use json::{JsonValue, object, stringify};
|
use std::fs;
|
||||||
use crate::users::user_manager::UserManager;
|
use std::io;
|
||||||
use crate::auth::auth_connector::AuthConnector;
|
use std::path::Path;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
// --- UserProfile ---
|
// --- UserProfile ---
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -43,34 +43,42 @@ impl UserProfile {
|
||||||
|
|
||||||
pub fn to_json(&self) -> JsonValue {
|
pub fn to_json(&self) -> JsonValue {
|
||||||
let mut obj = object! {
|
let mut obj = object! {
|
||||||
"UUID" => self.user_id.to_string(),
|
"uuid" => self.user_id.to_string(),
|
||||||
"username" => self.username.clone(),
|
"username" => self.username.clone(),
|
||||||
"publicKey" => self.public_key.clone(),
|
"public_key" => self.public_key.clone(),
|
||||||
"privateKeyHash" => self.private_key_hash.clone(),
|
"private_key_hash" => self.private_key_hash.clone(),
|
||||||
"resetToken" => self.reset_token.clone()
|
"reset_token" => self.reset_token.clone()
|
||||||
};
|
};
|
||||||
if let Some(d) = &self.display_name {
|
if let Some(d) = &self.display_name {
|
||||||
obj["displayName"] = d.clone().into();
|
obj["display_name"] = d.clone().into();
|
||||||
}
|
}
|
||||||
obj
|
obj
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn from_json(j: &JsonValue) -> Option<Self> {
|
pub async fn from_json(j: &JsonValue) -> Option<Self> {
|
||||||
let uuid = Uuid::parse_str(j["UUID"].as_str()?).ok()?;
|
let uuid = Uuid::parse_str(j["uuid"].as_str()?).ok()?;
|
||||||
let username = j["username"].as_str()?.to_string();
|
let username = j["username"].as_str()?.to_string();
|
||||||
let public_key = j["publicKey"].as_str()?.to_string();
|
let public_key = j["public_key"].as_str()?.to_string();
|
||||||
let private_key_hash = j["privateKeyHash"].as_str()?.to_string();
|
let private_key_hash = j["private_key_hash"].as_str()?.to_string();
|
||||||
let reset_token = j["resetToken"].as_str()?.to_string();
|
let reset_token = j["reset_token"].as_str()?.to_string();
|
||||||
let display_name = j["displayName"].as_str().map(|s| s.to_string());
|
let display_name = j["display_name"].as_str().map(|s| s.to_string());
|
||||||
|
|
||||||
let mut up = UserProfile::new(uuid, username, display_name, public_key, private_key_hash, reset_token);
|
let mut up = UserProfile::new(
|
||||||
|
uuid,
|
||||||
|
username,
|
||||||
|
display_name,
|
||||||
|
public_key,
|
||||||
|
private_key_hash,
|
||||||
|
reset_token,
|
||||||
|
);
|
||||||
|
|
||||||
// Migration hook (stubbed, since AuthConnector isn’t implemented here)
|
// Migration hook (stubbed, since AuthConnector isn’t implemented here)
|
||||||
if j.has_key("migrate")
|
if j.has_key("migrate")
|
||||||
|| j.has_key("migrating")
|
|| j.has_key("migrating")
|
||||||
|| j.has_key("changing")
|
|| j.has_key("changing")
|
||||||
|| j.has_key("move")
|
|| j.has_key("move")
|
||||||
|| j.has_key("moving") {
|
|| j.has_key("moving")
|
||||||
|
{
|
||||||
if AuthConnector::migrate_user(&mut up, stringify!("{}", Uuid::new_v4())).await {
|
if AuthConnector::migrate_user(&mut up, stringify!("{}", Uuid::new_v4())).await {
|
||||||
println!("[INFO] Migration triggered for {}", up.username);
|
println!("[INFO] Migration triggered for {}", up.username);
|
||||||
UserManager::set_unique(true);
|
UserManager::set_unique(true);
|
||||||
|
|
@ -90,6 +98,8 @@ impl UserProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_display_name(&self) -> String {
|
pub fn get_display_name(&self) -> String {
|
||||||
self.display_name.clone().unwrap_or_else(|| self.username.clone())
|
self.display_name
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| self.username.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18,8 +18,8 @@ pub fn mod_user(storage_owner: Uuid, contact: &Contact) {
|
||||||
};
|
};
|
||||||
|
|
||||||
for i in 0..contacts.len() {
|
for i in 0..contacts.len() {
|
||||||
if contacts[i]["userID"].as_str() == Some(&contact.user_id.unwrap().to_string()) {
|
if contacts[i]["user_id"].as_str() == Some(&contact.user_id.unwrap().to_string()) {
|
||||||
contacts.remove(stringify!("{}", i));
|
contacts.array_remove(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -37,7 +37,7 @@ pub fn get_user(storage_owner: Uuid, user_id: Uuid) -> Option<Contact> {
|
||||||
|
|
||||||
if let Ok(contacts) = json::parse(&s) {
|
if let Ok(contacts) = json::parse(&s) {
|
||||||
for i in 0..contacts.len() {
|
for i in 0..contacts.len() {
|
||||||
if let Some(uid) = contacts[i]["userID"].as_str() {
|
if let Some(uid) = contacts[i]["user_id"].as_str() {
|
||||||
if Uuid::parse_str(uid).ok()? == user_id {
|
if Uuid::parse_str(uid).ok()? == user_id {
|
||||||
return Option::from(Contact::from_json(&contacts[i]));
|
return Option::from(Contact::from_json(&contacts[i]));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
use crate::util::file_util::{load_file, save_file};
|
use crate::util::file_util::{load_file, save_file};
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::sync::Mutex;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
pub static CONFIG: Lazy<Mutex<ConfigUtil>> = Lazy::new(|| Mutex::new(ConfigUtil::new()));
|
||||||
|
|
||||||
pub struct ConfigUtil {
|
pub struct ConfigUtil {
|
||||||
pub config: JsonValue,
|
pub config: JsonValue,
|
||||||
pub unique: bool,
|
pub unique: bool,
|
||||||
|
|
@ -24,6 +28,14 @@ impl ConfigUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_iota_id(&self) -> Uuid {
|
||||||
|
self.config["iota_id"]
|
||||||
|
.as_str()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.parse()
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn change(&mut self, key: &str, value: Uuid) {
|
pub fn change(&mut self, key: &str, value: Uuid) {
|
||||||
self.config[key] = JsonValue::String(value.to_string());
|
self.config[key] = JsonValue::String(value.to_string());
|
||||||
self.unique = true;
|
self.unique = true;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
pub mod file_util;
|
|
||||||
pub mod chat_files;
|
pub mod chat_files;
|
||||||
pub mod config_util;
|
|
||||||
pub mod chats_util;
|
pub mod chats_util;
|
||||||
|
pub mod config_util;
|
||||||
|
pub mod file_util;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue