diff --git a/Cargo.lock b/Cargo.lock index bef464a..19b496b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,9 +8,7 @@ version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b" dependencies = [ - "actix-macros", "actix-rt", - "actix_derive", "bitflags 2.11.0", "bytes", "crossbeam-channel", @@ -44,34 +42,11 @@ dependencies = [ "tracing", ] -[[package]] -name = "actix-files" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8c4f30e3272d7c345f88ae0aac3848507ef5ba871f9cc2a41c8085a0f0523b" -dependencies = [ - "actix-http", - "actix-service", - "actix-utils", - "actix-web", - "bitflags 2.11.0", - "bytes", - "derive_more", - "futures-core", - "http-range", - "log", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "v_htmlescape", -] - [[package]] name = "actix-http" -version = "3.11.2" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7926860314cbe2fb5d1f13731e387ab43bd32bca224e82e6e2db85de0a3dba49" +checksum = "f860ee6746d0c5b682147b2f7f8ef036d4f92fe518251a3a35ffa3650eafdf0e" dependencies = [ "actix-codec", "actix-rt", @@ -114,14 +89,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] name = "actix-router" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" +checksum = "14f8c75c51892f18d9c46150c5ac7beb81c95f78c8b83a634d49f4ca32551fe7" dependencies = [ "bytestring", "cfg-if", @@ -138,7 +113,6 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92589714878ca59a7626ea19734f0e07a6a875197eec751bb5d3f99e64998c63" dependencies = [ - "actix-macros", "futures-core", "tokio", ] @@ -154,7 +128,7 @@ dependencies = [ "actix-utils", "futures-core", "futures-util", - "mio 1.1.1", + "mio", "socket2 0.5.10", "tokio", "tracing", @@ -201,9 +175,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.12.1" +version = "4.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1654a77ba142e37f049637a3e5685f864514af11fcbc51cb51eb6596afe5b8d6" +checksum = "ff87453bc3b56e9b2b23c1cc0b1be8797184accf51d2abe0f8a33ec275d316bf" dependencies = [ "actix-codec", "actix-http", @@ -237,7 +211,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.6.2", + "socket2 0.6.3", "time", "tracing", "url", @@ -270,27 +244,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.115", -] - -[[package]] -name = "actix_derive" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6ac1e58cded18cb28ddc17143c4dea5345b3ad575e14f32f66e4054a56eb271" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.115", -] - -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", + "syn 2.0.117", ] [[package]] @@ -375,9 +329,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.101" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arbitrary" @@ -388,6 +342,45 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "asn1-rs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 2.0.18", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -396,23 +389,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", -] - -[[package]] -name = "async-tungstenite" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc405d38be14342132609f06f02acaf825ddccfe76c4824a69281e0458ebd4" -dependencies = [ - "atomic-waker", - "futures-core", - "futures-io", - "futures-task", - "futures-util", - "log", - "pin-project-lite", - "tungstenite", + "syn 2.0.117", ] [[package]] @@ -438,9 +415,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.4" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" +checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" dependencies = [ "aws-lc-sys", "untrusted 0.7.1", @@ -449,9 +426,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.37.1" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b092fe214090261288111db7a2b2c2118e5a7f30dc2569f1732c4069a6840549" +checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" dependencies = [ "cc", "cmake", @@ -459,33 +436,12 @@ dependencies = [ "fs_extra", ] -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link", -] - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - [[package]] name = "bit-set" version = "0.5.3" @@ -513,12 +469,6 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block-buffer" version = "0.10.4" @@ -551,9 +501,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytemuck" @@ -561,6 +511,12 @@ version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.11.1" @@ -585,12 +541,6 @@ dependencies = [ "libbz2-rs-sys", ] -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - [[package]] name = "castaway" version = "0.2.4" @@ -612,6 +562,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.4" @@ -626,9 +582,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "js-sys", @@ -647,28 +603,6 @@ dependencies = [ "inout", ] -[[package]] -name = "clipboard" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7" -dependencies = [ - "clipboard-win", - "objc", - "objc-foundation", - "objc_id", - "x11-clipboard", -] - -[[package]] -name = "clipboard-win" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" -dependencies = [ - "winapi", -] - [[package]] name = "cmake" version = "0.1.57" @@ -679,57 +613,13 @@ dependencies = [ ] [[package]] -name = "color-eyre" -version = "0.6.5" +name = "combine" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "backtrace", - "color-spantrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", - "tracing-error", -] - -[[package]] -name = "color-spantrace" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427" -dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", -] - -[[package]] -name = "compact_str" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "ryu", - "static_assertions", -] - -[[package]] -name = "compact_str" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", + "bytes", + "memchr", ] [[package]] @@ -746,12 +636,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - [[package]] name = "constant_time_eq" version = "0.3.1" @@ -778,15 +662,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "cookie-factory" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2" -dependencies = [ - "futures", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -855,63 +730,12 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" -[[package]] -name = "crossterm" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" -dependencies = [ - "bitflags 2.11.0", - "crossterm_winapi", - "libc", - "mio 0.8.11", - "parking_lot", - "signal-hook", - "signal-hook-mio", - "winapi", -] - -[[package]] -name = "crossterm" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" -dependencies = [ - "bitflags 2.11.0", - "crossterm_winapi", - "mio 1.1.1", - "parking_lot", - "rustix 0.38.44", - "signal-hook", - "signal-hook-mio", - "winapi", -] - [[package]] name = "crossterm" version = "0.29.0" @@ -922,9 +746,9 @@ dependencies = [ "crossterm_winapi", "derive_more", "document-features", - "mio 1.1.1", + "mio", "parking_lot", - "rustix 1.1.3", + "rustix", "signal-hook", "signal-hook-mio", "winapi", @@ -989,7 +813,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -1000,7 +824,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -1025,9 +849,9 @@ checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] name = "deflate64" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26bf8fc351c5ed29b5c2f0cbbac1b209b74f60ecd62e675a998df72c49af5204" +checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2" [[package]] name = "deltae" @@ -1036,26 +860,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" [[package]] -name = "der" -version = "0.7.10" +name = "der-parser" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" dependencies = [ - "const-oid", - "zeroize", + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", ] -[[package]] -name = "der" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" - [[package]] name = "deranged" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", ] @@ -1068,7 +890,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -1090,7 +912,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.115", + "syn 2.0.117", "unicode-xid", ] @@ -1113,7 +935,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -1157,6 +979,38 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "epsilon-core" +version = "0.1.0" +source = "git+https://github.com/Tensamin/Epsilon.git#1eb12cceb70d99dded2327e0a5f215a5cd137eb3" +dependencies = [ + "byteorder", + "quinn", + "rand 0.8.5", + "strum 0.28.0", + "strum_macros 0.28.0", +] + +[[package]] +name = "epsilon-native" +version = "0.1.0" +source = "git+https://github.com/Tensamin/Epsilon.git#1eb12cceb70d99dded2327e0a5f215a5cd137eb3" +dependencies = [ + "anyhow", + "async-trait", + "aws-lc-rs", + "bytes", + "epsilon-core", + "quinn", + "rcgen", + "rustls", + "rustls-native-certs", + "thiserror 2.0.18", + "tokio", + "wtransport", + "wtransport-proto", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1182,16 +1036,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - [[package]] name = "fancy-regex" version = "0.11.0" @@ -1202,6 +1046,18 @@ dependencies = [ "regex", ] +[[package]] +name = "fastbloom" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" +dependencies = [ + "getrandom 0.3.4", + "libm", + "rand 0.9.2", + "siphasher", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -1304,9 +1160,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -1319,9 +1175,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -1329,15 +1185,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -1346,38 +1202,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -1387,7 +1243,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -1408,8 +1263,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1419,20 +1276,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", ] @@ -1447,12 +1306,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - [[package]] name = "glob" version = "0.3.3" @@ -1509,8 +1362,6 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "allocator-api2", - "equivalent", "foldhash 0.1.5", ] @@ -1579,6 +1430,12 @@ dependencies = [ "digest", ] +[[package]] +name = "httlib-huffman" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9fcbcc408c5526c3ab80d534e5c86e7967c1fb7aa0a8c76abd1edc27deb877" + [[package]] name = "http" version = "0.2.12" @@ -1623,12 +1480,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" - [[package]] name = "httparse" version = "1.10.1" @@ -1680,22 +1531,6 @@ dependencies = [ "tower-service", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.20" @@ -1713,7 +1548,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.2", + "socket2 0.6.3", "system-configuration", "tokio", "tower-service", @@ -1733,7 +1568,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core", ] [[package]] @@ -1865,12 +1700,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" -[[package]] -name = "indenter" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" - [[package]] name = "indexmap" version = "2.13.0" @@ -1911,81 +1740,59 @@ dependencies = [ "indoc", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] name = "iota" version = "0.1.0" dependencies = [ - "actix", - "actix-files", - "actix-rt", "actix-web", "actix-web-actors", "aes-gcm", "async-trait", - "async-tungstenite", - "aws-lc-rs", "base64", - "bytes", "chrono", - "cmake", - "color-eyre", - "crossterm 0.29.0", + "crossterm", "dashmap", - "der 0.8.0", + "epsilon-core", + "epsilon-native", "futures", "futures-util", "hex", "hkdf", - "hmac", - "http-body-util", "hyper", "hyper-util", "json", - "native-tls", "once_cell", "open", - "pkcs8", "pnet", "rand 0.8.5", "rand_core 0.6.4", - "ratatui 0.30.0", - "ratatui_input", - "reactive-rs", + "ratatui", "reqwest", "rustls", "rustls-pemfile", - "serde", "serde_json", - "sha1", "sha2", "strum 0.27.2", "strum_macros 0.27.2", - "sys-info", "sysinfo", "tokio", - "tokio-rustls", "tokio-tungstenite", - "tokio-util", - "tower", - "tui-input", - "tui-textarea", "tungstenite", "uuid", "walkdir", "warp", "x448", - "x509", "zip", ] [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "ipnetwork" @@ -2025,24 +1832,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.14.0" @@ -2058,6 +1847,28 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.34" @@ -2070,9 +1881,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" dependencies = [ "once_cell", "wasm-bindgen", @@ -2127,9 +1938,15 @@ checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" [[package]] name = "libc" -version = "0.2.182" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "line-clipping" @@ -2142,15 +1959,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" @@ -2196,15 +2007,6 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.5", -] - [[package]] name = "lru" version = "0.16.3" @@ -2214,6 +2016,12 @@ dependencies = [ "hashbrown 0.16.1", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "lzma-rust2" version = "0.13.0" @@ -2234,24 +2042,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "mach" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" -dependencies = [ - "libc", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "memchr" version = "2.8.0" @@ -2305,18 +2095,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "mio" version = "1.1.1" @@ -2331,9 +2109,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5d26952a508f321b4d3d2e80e78fc2603eaefcdf0c30783867f19586518bdc" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ "libc", "log", @@ -2384,6 +2162,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-conv" version = "0.2.0" @@ -2398,7 +2186,16 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", ] [[package]] @@ -2420,41 +2217,37 @@ dependencies = [ ] [[package]] -name = "objc" -version = "0.2.7" +name = "objc2-core-foundation" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "malloc_buf", + "bitflags 2.11.0", ] [[package]] -name = "objc-foundation" -version = "0.1.1" +name = "objc2-io-kit" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" dependencies = [ - "block", - "objc", - "objc_id", + "libc", + "objc2-core-foundation", ] [[package]] -name = "objc_id" -version = "0.1.1" +name = "octets" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] +checksum = "8311fa8ab7a57759b4ff1f851a3048d9ef0effaa0130726426b742d26d8a88e7" [[package]] -name = "object" -version = "0.37.3" +name = "oid-registry" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" dependencies = [ - "memchr", + "asn1-rs", ] [[package]] @@ -2503,7 +2296,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -2533,12 +2326,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "owo-colors" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" - [[package]] name = "parking_lot" version = "0.12.5" @@ -2562,12 +2349,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pathdiff" version = "0.2.3" @@ -2584,6 +2365,16 @@ dependencies = [ "hmac", ] +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64", + "serde_core", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2620,7 +2411,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -2673,7 +2464,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -2687,29 +2478,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -2717,16 +2508,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.10", - "spki", -] - [[package]] name = "pkg-config" version = "0.3.32" @@ -2778,7 +2559,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -2879,7 +2660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -2892,10 +2673,68 @@ dependencies = [ ] [[package]] -name = "quote" -version = "1.0.44" +name = "quinn" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.6.3", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "aws-lc-rs", + "bytes", + "fastbloom", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.3", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -2906,6 +2745,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.8.5" @@ -2971,47 +2816,6 @@ dependencies = [ "getrandom 0.3.4", ] -[[package]] -name = "ratatui" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44c9e68fd46eda15c646fbb85e1040b657a58cdc8c98db1d97a55930d991eef" -dependencies = [ - "bitflags 2.11.0", - "cassowary", - "compact_str 0.7.1", - "crossterm 0.27.0", - "itertools 0.12.1", - "lru 0.12.5", - "paste", - "stability", - "strum 0.26.3", - "unicode-segmentation", - "unicode-truncate 1.1.0", - "unicode-width 0.1.14", -] - -[[package]] -name = "ratatui" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" -dependencies = [ - "bitflags 2.11.0", - "cassowary", - "compact_str 0.8.1", - "crossterm 0.28.1", - "indoc", - "instability", - "itertools 0.13.0", - "lru 0.12.5", - "paste", - "strum 0.26.3", - "unicode-segmentation", - "unicode-truncate 1.1.0", - "unicode-width 0.2.0", -] - [[package]] name = "ratatui" version = "0.30.0" @@ -3033,17 +2837,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293" dependencies = [ "bitflags 2.11.0", - "compact_str 0.9.0", + "compact_str", "hashbrown 0.16.1", "indoc", - "itertools 0.14.0", + "itertools", "kasuari", - "lru 0.16.3", + "lru", "strum 0.27.2", "thiserror 2.0.18", "unicode-segmentation", - "unicode-truncate 2.0.1", - "unicode-width 0.2.0", + "unicode-truncate", + "unicode-width", ] [[package]] @@ -3053,7 +2857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3" dependencies = [ "cfg-if", - "crossterm 0.29.0", + "crossterm", "instability", "ratatui-core", ] @@ -3088,53 +2892,28 @@ dependencies = [ "hashbrown 0.16.1", "indoc", "instability", - "itertools 0.14.0", + "itertools", "line-clipping", "ratatui-core", "strum 0.27.2", "time", "unicode-segmentation", - "unicode-width 0.2.0", + "unicode-width", ] [[package]] -name = "ratatui_input" -version = "0.1.3" +name = "rcgen" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e8a34033089cf174da43769390c383c12bdc318e201f7ed667970bd99e3912b" +checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e" dependencies = [ - "clipboard", - "crossterm 0.27.0", - "ratatui 0.26.3", -] - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "reactive-rs" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee41fe079cafa6f6d12316ce44a1530aebcfb21b58e0face916dcbf19d47eab" -dependencies = [ - "slice-deque", + "aws-lc-rs", + "pem", + "ring", + "rustls-pki-types", + "time", + "x509-parser 0.18.1", + "yasna", ] [[package]] @@ -3177,15 +2956,15 @@ checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" -version = "0.12.28" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ "base64", "bytes", @@ -3197,21 +2976,19 @@ dependencies = [ "http-body-util", "hyper", "hyper-rustls", - "hyper-tls", "hyper-util", "js-sys", "log", "mime", - "native-tls", "percent-encoding", "pin-project-lite", + "quinn", + "rustls", "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", + "rustls-platform-verifier", "sync_wrapper", "tokio", - "tokio-native-tls", + "tokio-rustls", "tower", "tower-http", "tower-service", @@ -3236,10 +3013,10 @@ dependencies = [ ] [[package]] -name = "rustc-demangle" -version = "0.1.27" +name = "rustc-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -3251,46 +3028,55 @@ dependencies = [ ] [[package]] -name = "rustix" -version = "0.38.44" +name = "rusticata-macros" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" dependencies = [ - "bitflags 2.11.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "nom", ] [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ "bitflags 2.11.0", "errno", "libc", - "linux-raw-sys 0.11.0", + "linux-raw-sys", "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "aws-lc-rs", "log", "once_cell", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -3306,9 +3092,37 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ + "web-time", "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.103.9" @@ -3365,9 +3179,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.11.0", "core-foundation 0.10.1", @@ -3378,9 +3192,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.16.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -3419,7 +3233,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -3469,15 +3283,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shlex" version = "1.3.0" @@ -3501,8 +3306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", - "mio 0.8.11", - "mio 1.1.1", + "mio", "signal-hook", ] @@ -3534,17 +3338,6 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" -[[package]] -name = "slice-deque" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39fca478d10e201944a8e21f4393d6bfe38fa3b16a152050e4d097fe2bbf494" -dependencies = [ - "libc", - "mach", - "winapi", -] - [[package]] name = "smallvec" version = "1.15.1" @@ -3563,32 +3356,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.10", -] - -[[package]] -name = "stability" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" -dependencies = [ - "quote", - "syn 2.0.115", + "windows-sys 0.61.2", ] [[package]] @@ -3609,15 +3382,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros 0.26.4", -] - [[package]] name = "strum" version = "0.27.2" @@ -3628,17 +3392,10 @@ dependencies = [ ] [[package]] -name = "strum_macros" -version = "0.26.4" +name = "strum" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.115", -] +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" [[package]] name = "strum_macros" @@ -3649,7 +3406,19 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -3671,9 +3440,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.115" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -3697,31 +3466,20 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", -] - -[[package]] -name = "sys-info" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" -dependencies = [ - "cc", - "libc", + "syn 2.0.117", ] [[package]] name = "sysinfo" -version = "0.30.13" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +checksum = "d03c61d2a49c649a15c407338afe7accafde9dac869995dccb73e5f7ef7d9034" dependencies = [ - "cfg-if", - "core-foundation-sys", "libc", + "memchr", "ntapi", - "once_cell", - "rayon", + "objc2-core-foundation", + "objc2-io-kit", "windows", ] @@ -3748,14 +3506,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.25.0" +version = "3.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" dependencies = [ "fastrand", - "getrandom 0.4.1", + "getrandom 0.4.2", "once_cell", - "rustix 1.1.3", + "rustix", "windows-sys 0.61.2", ] @@ -3848,7 +3606,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -3859,16 +3617,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", + "syn 2.0.117", ] [[package]] @@ -3915,31 +3664,46 @@ dependencies = [ ] [[package]] -name = "tokio" -version = "1.49.0" +name = "tinyvec" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "bytes", "libc", - "mio 1.1.1", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -3984,12 +3748,8 @@ checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", - "futures-io", "futures-sink", - "futures-util", - "hashbrown 0.15.5", "pin-project-lite", - "slab", "tokio", ] @@ -4058,7 +3818,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -4068,28 +3828,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-error" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" -dependencies = [ - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" -dependencies = [ - "sharded-slab", - "thread_local", - "tracing-core", ] [[package]] @@ -4098,27 +3836,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tui-input" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "911e93158bf80bbc94bad533b2b16e3d711e1132d69a6a6980c3920a63422c19" -dependencies = [ - "ratatui 0.29.0", - "unicode-width 0.2.0", -] - -[[package]] -name = "tui-textarea" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5318dd619ed73c52a9417ad19046724effc1287fb75cdcc4eca1d6ac1acbae" -dependencies = [ - "crossterm 0.28.1", - "ratatui 0.29.0", - "unicode-width 0.2.0", -] - [[package]] name = "tungstenite" version = "0.28.0" @@ -4157,9 +3874,9 @@ checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" @@ -4167,39 +3884,22 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" -[[package]] -name = "unicode-truncate" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" -dependencies = [ - "itertools 0.13.0", - "unicode-segmentation", - "unicode-width 0.1.14", -] - [[package]] name = "unicode-truncate" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b380a1238663e5f8a691f9039c73e1cdae598a30e9855f541d29b08b53e9a5" dependencies = [ - "itertools 0.14.0", + "itertools", "unicode-segmentation", - "unicode-width 0.2.0", + "unicode-width", ] [[package]] name = "unicode-width" -version = "0.1.14" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -4261,28 +3961,16 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ "atomic", - "getrandom 0.4.1", + "getrandom 0.4.2", "js-sys", "wasm-bindgen", ] -[[package]] -name = "v_htmlescape" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - [[package]] name = "vcpkg" version = "0.2.15" @@ -4376,9 +4064,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" dependencies = [ "cfg-if", "once_cell", @@ -4389,9 +4077,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" dependencies = [ "cfg-if", "futures-util", @@ -4403,9 +4091,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4413,22 +4101,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" dependencies = [ "unicode-ident", ] @@ -4469,14 +4157,33 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "wezterm-bidi" version = "0.2.3" @@ -4582,21 +4289,23 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.52.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ - "windows-core 0.52.0", - "windows-targets 0.52.6", + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows-collections" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-targets 0.52.6", + "windows-core", ] [[package]] @@ -4612,6 +4321,17 @@ dependencies = [ "windows-strings", ] +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + [[package]] name = "windows-implement" version = "0.60.2" @@ -4620,7 +4340,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -4631,7 +4351,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -4640,6 +4360,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core", + "windows-link", +] + [[package]] name = "windows-registry" version = "0.6.1" @@ -4671,11 +4401,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.42.2", ] [[package]] @@ -4687,15 +4417,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.60.2" @@ -4716,17 +4437,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -4763,10 +4484,19 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" +name = "windows-threading" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" @@ -4782,9 +4512,9 @@ checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" @@ -4800,9 +4530,9 @@ checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" @@ -4830,9 +4560,9 @@ checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" @@ -4848,9 +4578,9 @@ checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" @@ -4866,9 +4596,9 @@ checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" @@ -4884,9 +4614,9 @@ checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" @@ -4930,7 +4660,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.115", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -4946,7 +4676,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -4995,12 +4725,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] -name = "x11-clipboard" -version = "0.3.3" +name = "wtransport" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea" +checksum = "e56b611f195638f3790e4e5a41e9d777643a6c324ae4ffd1f0f53f2738e7678c" dependencies = [ - "xcb", + "bytes", + "pem", + "quinn", + "rcgen", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "sha2", + "socket2 0.5.10", + "thiserror 2.0.18", + "time", + "tokio", + "tracing", + "url", + "wtransport-proto", + "x509-parser 0.17.0", +] + +[[package]] +name = "wtransport-proto" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1627c5b59450278e9771aab35275d72bfa2788128c197c5af1e4a820c8737ef4" +dependencies = [ + "httlib-huffman", + "octets", + "thiserror 2.0.18", + "url", ] [[package]] @@ -5015,23 +4772,48 @@ dependencies = [ ] [[package]] -name = "x509" -version = "0.2.0" +name = "x509-parser" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3cec94c3999f31341553f358ef55f65fc031291a022cd42ec0ce7219560c76" +checksum = "4569f339c0c402346d4a75a9e39cf8dad310e287eef1ff56d4c68e5067f53460" dependencies = [ - "chrono", - "cookie-factory", + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror 2.0.18", + "time", ] [[package]] -name = "xcb" -version = "0.8.2" +name = "x509-parser" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" +checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" dependencies = [ - "libc", - "log", + "asn1-rs", + "aws-lc-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "ring", + "rusticata-macros", + "thiserror 2.0.18", + "time", +] + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", ] [[package]] @@ -5053,28 +4835,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -5094,7 +4876,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", "synstructure", ] @@ -5115,7 +4897,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -5148,7 +4930,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.117", ] [[package]] @@ -5180,9 +4962,9 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" [[package]] name = "zmij" diff --git a/Cargo.toml b/Cargo.toml index 065eb41..8315b65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,23 +4,18 @@ version = "0.1.0" edition = "2024" [dependencies] -actix = "0.13.5" -actix-rt = "2.11.0" +epsilon-core = { git = "https://github.com/Tensamin/Epsilon.git", package = "epsilon-core" } +epsilon-native = { git = "https://github.com/Tensamin/Epsilon.git", package = "epsilon-native" } + actix-web = { version = "4", features = ["rustls-0_23"] } actix-web-actors = "4" -actix-files = "0.6" aes-gcm = "*" base64 = "0.22.1" -bytes = "*" -cmake = "*" -color-eyre = "*" crossterm = "*" -der = "*" futures = "*" futures-util = "*" hex = "*" hkdf = "*" -hmac = "*" hyper-util = { version = "*" } hyper = { version = "1.8.1", features = [ "capi", @@ -31,45 +26,29 @@ hyper = { version = "1.8.1", features = [ "nightly", "server", ] } -http-body-util = "*" 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"] } -reactive-rs = "*" -aws-lc-rs = "*" -reqwest = "0.12.23" -rustls = { version = "*", features = ["aws-lc-rs"] } -serde = { version = "1.0.219", features = ["derive"] } +reqwest = "0.13.2" +rustls = { version = "0.23.37", features = ["aws-lc-rs"] } sha2 = "*" -sys-info = "*" -sysinfo = "0.30" -tokio = { version = "1.48.0", features = ["full"] } -tokio-util = { version = "*", features = ["full"] } +sysinfo = "0.38.3" +tokio = { version = "1.50.0", features = ["full"] } tokio-tungstenite = { version = "*", features = ["native-tls"] } -tower = "*" tungstenite = "*" uuid = { version = "*", features = ["v4"] } walkdir = "2.5.0" warp = "*" x448 = { version = "*" } -x509 = "*" -tokio-rustls = "0.26.4" rustls-pemfile = "2.2.0" async-trait = "0.1.89" -sha1 = "0.10.6" -async-tungstenite = "0.32.0" zip = "6.0.0" -tui-textarea = "0.7.0" -tui-input = "0.14.0" pnet = "0.35.0" dashmap = "6.1.0" strum = "0.27.2" strum_macros = "0.27.2" ratatui = "0.30.0" -ratatui_input = "0.1.3" open = "5.3.3" chrono = "0.4.43" serde_json = "1.0.149" diff --git a/src/communities/community.rs b/src/communities/community.rs index ee623a1..835c88a 100644 --- a/src/communities/community.rs +++ b/src/communities/community.rs @@ -4,7 +4,6 @@ use crate::communities::perms::permission::Permission; use crate::communities::{ community_connection::CommunityConnection, interactables::interactable::Interactable, }; -use crate::data::communication::{CommunicationType, CommunicationValue}; use crate::util::file_util; use base64::{Engine as _, engine::general_purpose::STANDARD}; use json::JsonValue; diff --git a/src/communities/community_connection.rs b/src/communities/community_connection.rs index a08f01f..62df251 100644 --- a/src/communities/community_connection.rs +++ b/src/communities/community_connection.rs @@ -1,7 +1,6 @@ use crate::auth::auth_user::AuthUser; use crate::communities::community::Community; use crate::communities::interactables::interactable::Interactable; -use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::users::user_manager::get_user; use aes_gcm::{Aes256Gcm, KeyInit, Nonce, aead::Aead}; use base64::{Engine as _, engine::general_purpose::STANDARD}; diff --git a/src/communities/interactables/category.rs b/src/communities/interactables/category.rs index 40ca625..232ee53 100644 --- a/src/communities/interactables/category.rs +++ b/src/communities/interactables/category.rs @@ -1,8 +1,6 @@ -use crate::{ - communities::{community::Community, interactables::interactable::Interactable}, - data::communication::{CommunicationType, CommunicationValue}, -}; +use crate::communities::{community::Community, interactables::interactable::Interactable}; use async_trait::async_trait; +use epsilon_core::CommunicationValue; use json::JsonValue; use std::any::Any; use std::sync::Arc; diff --git a/src/communities/interactables/interactable.rs b/src/communities/interactables/interactable.rs index 7d581d0..bd14b83 100644 --- a/src/communities/interactables/interactable.rs +++ b/src/communities/interactables/interactable.rs @@ -1,5 +1,6 @@ -use crate::{communities::community::Community, data::communication::CommunicationValue}; +use crate::communities::community::Community; use async_trait::async_trait; +use epsilon_core::CommunicationValue; use json::JsonValue; use std::any::Any; use std::sync::Arc; diff --git a/src/communities/interactables/text_chat.rs b/src/communities/interactables/text_chat.rs index 2cb7585..16c04ae 100644 --- a/src/communities/interactables/text_chat.rs +++ b/src/communities/interactables/text_chat.rs @@ -3,11 +3,11 @@ use crate::{ community::Community, community_connection::CommunityConnection, interactables::interactable::Interactable, }, - data::communication::{CommunicationType, CommunicationValue, DataTypes}, log, util::file_util::{get_children, load_file, save_file}, }; use async_trait::async_trait; +use epsilon_core::{CommunicationType, CommunicationValue, DataTypes}; use json::{JsonValue, array, object}; use std::fs; use std::sync::Arc; @@ -190,9 +190,9 @@ impl Interactable for TextChat { JsonValue::new_object() } async fn run_function(&self, cv: CommunicationValue) -> CommunicationValue { - let payload = cv.get_data(DataTypes::payload).unwrap(); - if cv.get_data(DataTypes::function).unwrap().as_str().unwrap() == "get_messages" { - let amount = payload["amount"].as_i64().unwrap(); + let payload = cv.get_data(DataTypes::payload).as_container().unwrap(); + if cv.get_data(DataTypes::function).as_str().unwrap() == "get_messages" { + let amount = payload.get(DataTypes::amount).as_i64().unwrap(); let loaded_messages = payload["loaded_messages"].as_i64().unwrap(); let messages = self.get_messages(loaded_messages, amount).clone(); let mut payload = JsonValue::new_object(); diff --git a/src/communities/interactables/voice_chat.rs b/src/communities/interactables/voice_chat.rs index c452ea1..2a2e3a2 100644 --- a/src/communities/interactables/voice_chat.rs +++ b/src/communities/interactables/voice_chat.rs @@ -1,7 +1,4 @@ -use crate::{ - communities::{community::Community, interactables::interactable::Interactable}, - data::communication::{CommunicationType, CommunicationValue, DataTypes}, -}; +use crate::communities::{community::Community, interactables::interactable::Interactable}; use async_trait::async_trait; use json::JsonValue; use std::sync::Arc; diff --git a/src/data/communication.rs b/src/data/communication.rs deleted file mode 100644 index 99229f5..0000000 --- a/src/data/communication.rs +++ /dev/null @@ -1,403 +0,0 @@ -use json::number::Number; -use json::{Array, JsonValue, object, parse}; -use std::collections::HashMap; -use std::time::{SystemTime, UNIX_EPOCH}; -use strum::IntoEnumIterator; -use strum_macros::EnumIter; -use uuid::Uuid; - -#[derive(Eq, Hash, PartialEq, EnumIter, Clone, Debug)] -#[allow(non_camel_case_types, dead_code)] -pub enum DataTypes { - error_type, - accepted_ids, - uuid, - register_id, - - link, - - settings, - settings_name, - chat_partner_id, - chat_partner_name, - iota_id, - user_id, - user_ids, - iota_ids, - user_state, - user_states, - user_pings, - call_state, - screen_share, - private_key_hash, - accepted, - accepted_profiles, - denied_profiles, - content, - messages, - notifications, - send_time, - get_time, - get_variant, - shared_secret_own, - shared_secret_other, - shared_secret_sign, - shared_secret, - call_id, - call_token, - untill, - enabled, - start_date, - end_date, - receiver_id, - sender_id, - signature, - signed, - message, - message_state, - last_ping, - ping_iota, - ping_clients, - matches, - omikron, - offset, - amount, - position, - name, - path, - codec, - function, - payload, - result, - interactables, - want_to_watch, - watcher, - created_at, - username, - display, - avatar, - about, - status, - public_key, - sub_level, - sub_end, - community_address, - challenge, - community_title, - communities, - rho_connections, - user, - online_status, - omikron_id, - omikron_connections, - reset_token, - new_token, -} - -impl DataTypes { - pub fn parse(p0: String) -> DataTypes { - for datatype in DataTypes::iter() { - if datatype.to_string().to_lowercase().replace('_', "") - == p0.to_lowercase().replace('_', "") - { - return datatype; - } - } - DataTypes::error_type - } - pub fn to_string(&self) -> String { - return format!("{:?}", self); - } -} - -#[derive(PartialEq, Clone, EnumIter, Debug)] -#[allow(non_camel_case_types, dead_code)] -pub enum CommunicationType { - error, - error_anonymous, - error_internal, - error_invalid_data, - error_invalid_user_id, - error_invalid_omikron_id, - error_not_found, - error_not_authenticated, - error_no_iota, - error_invalid_challenge, - error_invalid_secret, - error_invalid_private_key, - error_invalid_public_key, - error_no_user_id, - error_no_call_id, - error_invalid_call_id, - success, - - shorten_link, - - settings_save, - settings_load, - settings_list, - message, - message_state, - message_send, - message_live, - message_other_iota, - message_chunk, - messages_get, - - push_notification, - read_notification, - get_notifications, - - change_confirm, - confirm_receive, - confirm_read, - get_chats, - get_states, - add_community, - remove_community, - get_communities, - challenge, - challenge_response, - register, - register_response, - identification, - identification_response, - register_iota, - register_iota_success, - ping, - pong, - add_conversation, - send_chat, - client_changed, - client_connected, - client_disconnected, - client_closed, - public_key, - private_key, - webrtc_sdp, - webrtc_ice, - start_stream, - end_stream, - watch_stream, - call_token, - call_invite, - call_disconnect_user, - call_timeout_user, - call_set_anonymous_joining, - end_call, - function, - update, - create_user, - rho_update, - - user_connected, - user_disconnected, - iota_connected, - iota_disconnected, - sync_client_iota_status, - - get_user_data, - get_iota_data, - iota_user_data, - - change_user_data, - change_iota_data, - - get_register, - complete_register_user, - complete_register_iota, - delete_user, - delete_iota, - - start_register, - complete_register, -} -impl CommunicationType { - pub fn parse(p0: String) -> CommunicationType { - for datatype in CommunicationType::iter() { - if datatype.to_string().to_lowercase().replace('_', "") - == p0.to_lowercase().replace('_', "") - { - return datatype; - } - } - CommunicationType::error - } - pub fn to_string(&self) -> String { - return format!("{:?}", self); - } -} - -#[derive(Debug, Clone)] -pub struct CommunicationValue { - id: Uuid, - comm_type: CommunicationType, - sender: i64, - receiver: i64, - data: HashMap, -} - -#[allow(dead_code)] -impl CommunicationValue { - pub fn new(comm_type: CommunicationType) -> Self { - Self { - id: Uuid::new_v4(), - comm_type, - sender: 0, - receiver: 0, - data: HashMap::new(), - } - } - pub fn with_id(mut self, p0: Uuid) -> Self { - self.id = p0; - self - } - pub fn get_id(&self) -> Uuid { - self.id.clone() - } - pub fn with_sender(mut self, sender: i64) -> Self { - self.sender = sender; - self - } - pub fn get_sender(&self) -> i64 { - self.sender.clone() - } - pub fn with_receiver(mut self, receiver: i64) -> Self { - self.receiver = receiver; - self - } - pub fn get_receiver(&self) -> i64 { - 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 { - self.data.insert(key, JsonValue::String(value)); - self - } - pub fn add_data(mut self, key: DataTypes, value: JsonValue) -> Self { - self.data.insert(key, value); - self - } - pub fn add_array(mut self, key: DataTypes, value: Array) -> Self { - self.data.insert(key, JsonValue::Array(value)); - self - } - pub fn get_data(&self, key: DataTypes) -> Option<&JsonValue> { - self.data.get(&key) - } - - pub fn get_type(&self) -> CommunicationType { - self.comm_type.clone() - } - pub fn is_type(&self, p0: CommunicationType) -> bool { - self.comm_type == p0 - } - pub fn to_json(&self) -> JsonValue { - let mut jdata = object! {}; - for (k, v) in &self.data { - jdata[&format!("{:?}", k)] = JsonValue::from(v.clone()); - } - if self.sender > 0 && self.receiver > 0 { - object! { - id: self.id.to_string(), - type: format!("{:?}", self.comm_type), - sender: self.sender, - receiver: self.receiver, - data: jdata - } - } else if self.sender > 0 { - object! { - id: self.id.to_string(), - type: format!("{:?}", self.comm_type), - sender: self.sender, - data: jdata - } - } else if self.receiver > 0 { - object! { - id: self.id.to_string(), - type: format!("{:?}", self.comm_type), - receiver: self.receiver, - data: jdata - } - } else { - object! { - id: self.id.to_string(), - type: format!("{:?}", self.comm_type), - data: jdata - } - } - } - - pub fn from_json(json_str: &str) -> Self { - if let Ok(parsed) = parse(json_str) { - let comm_type = CommunicationType::parse(parsed["type"].to_string()); - let mut sender: i64 = 0; - if parsed.has_key("sender") { - sender = parsed["sender"].as_i64().unwrap_or(0); - } - let mut receiver: i64 = 0; - if parsed.has_key("receiver") { - receiver = parsed["receiver"].as_i64().unwrap_or(0); - } - - let uuid = - Uuid::parse_str(parsed["id"].as_str().unwrap_or("")).unwrap_or(Uuid::new_v4()); - let mut data = HashMap::new(); - if parsed["data"].is_object() { - for (k, v) in parsed["data"].entries() { - data.insert(DataTypes::parse(k.to_string()), v.clone()); - } - } - - Self { - id: uuid, - comm_type, - sender, - receiver, - data, - } - } else { - Self { - id: Uuid::new_v4(), - comm_type: CommunicationType::error, - sender: 0, - receiver: 0, - data: HashMap::new(), - } - } - } - pub fn forward_to_other_iota(original: &mut CommunicationValue) -> CommunicationValue { - let receiver = original - .get_data(DataTypes::receiver_id) - .unwrap_or(&JsonValue::Number(Number::from(0))) - .as_i64() - .unwrap_or(0); - - let now_ms = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as i64; - - let sender = original.get_sender(); - CommunicationValue::new(CommunicationType::message_other_iota) - .with_id(original.get_id()) - .with_receiver(receiver) - .add_data( - DataTypes::receiver_id, - JsonValue::Number(Number::from(receiver)), - ) - .with_sender(sender) - .add_data(DataTypes::send_time, JsonValue::String(now_ms.to_string())) - .add_data( - DataTypes::sender_id, - JsonValue::Number(Number::from(sender)), - ) - .add_data( - DataTypes::content, - JsonValue::String(original.get_data(DataTypes::content).unwrap().to_string()), - ) - } -} diff --git a/src/data/mod.rs b/src/data/mod.rs deleted file mode 100644 index 7575266..0000000 --- a/src/data/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod communication; \ No newline at end of file diff --git a/src/gui/app_state.rs b/src/gui/app_state.rs old mode 100644 new mode 100755 index 3cf1f06..a161226 --- a/src/gui/app_state.rs +++ b/src/gui/app_state.rs @@ -143,7 +143,7 @@ impl AppState { pub fn setup() { ACTIVE_TASKS.insert("System info loader".to_string()); tokio::spawn(async move { - let mut sys = System::new_with_specifics(RefreshKind::new()); + let mut sys = System::new_with_specifics(RefreshKind::everything()); let mut last_total_received = 0u64; let mut last_total_transmitted = 0u64; let mut counter = 0.0; diff --git a/src/gui/elements/console_card.rs b/src/gui/elements/console_card.rs index 889e4e7..1269b64 100644 --- a/src/gui/elements/console_card.rs +++ b/src/gui/elements/console_card.rs @@ -1,4 +1,5 @@ use crossterm::event::{KeyCode, KeyEvent}; +use epsilon_core::{CommunicationType, CommunicationValue}; use ratatui::{ Frame, layout::Rect, @@ -10,7 +11,6 @@ use uuid::Uuid; use crate::{ ACTIVE_TASKS, RELOAD, SHUTDOWN, - data::communication::{CommunicationType, CommunicationValue}, gui::{ elements::elements::{Element, InteractableElement, JoinableElement}, interaction_result::InteractionResult, @@ -260,15 +260,7 @@ pub async fn run_command(command: &str) { pub async fn ping(time: u64) { let time = time; - let conn = { - let guard = OMIKRON_CONNECTION.read().await; - guard.as_ref().cloned() - }; - - let conn = match conn { - Some(c) => c, - None => return, - }; + let conn = OMIKRON_CONNECTION.clone(); let response_cv = conn .await_response( diff --git a/src/main.rs b/src/main.rs index a72ce87..aa355bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,25 +8,19 @@ use tokio::sync::RwLock; use tokio::time::{Duration, sleep}; mod auth; -mod communities; -mod data; mod gui; mod langu; mod omikron; -mod server; mod terms; mod users; mod util; -use crate::communities::community_manager; -use crate::communities::interactables::registry; use crate::gui::app_state; use crate::gui::app_state::AppState; use crate::gui::screens::main_screen::MainScreen; use crate::gui::ui::start_tui; use crate::langu::language_creator; use crate::omikron::omikron_connection::{OMIKRON_CONNECTION, OmikronConnection}; -use crate::server::server::start; use crate::terms::consent_state; use crate::users::user_manager; use crate::util::config_util::CONFIG; @@ -119,7 +113,7 @@ async fn main() { log!("User IDS: {}", sb); // COMMUNITY MANAGEMENT - registry::load_interactables().await; + /* registry::load_interactables().await; community_manager::load_communities().await; community_manager::save_communities().await; let mut sb1 = "".to_string(); @@ -131,7 +125,7 @@ async fn main() { sb1.remove(0); sb1 = sb1 + ","; } - log!("Community IDS: {}", sb1); + log!("Community IDS: {}", sb1); */ let port = CONFIG.read().await.get_port(); let mut ip = "0.0.0.0".to_string(); for iface in pnet::datalink::interfaces() { @@ -144,6 +138,7 @@ async fn main() { } } } + /* if start(port).await { log_t!("community_active", ip, port.to_string()); } else { @@ -152,7 +147,7 @@ async fn main() { } else { log_t!("community_start_error", port.to_string()); } - } + } */ if !has_dir("web") { download_and_extract_zip( "https://omega.tensamin.net/api/download/iota_frontend", @@ -160,26 +155,16 @@ async fn main() { ) .await; } + let omikron: Arc = Arc::new(OmikronConnection::new()); + omikron.connect().await; + + log_t!("setup_completed"); loop { if *SHUTDOWN.read().await { break; } - let omikron: Arc = Arc::new(OmikronConnection::new()); - omikron.connect().await; - { - let mut omikron_connection = OMIKRON_CONNECTION.write().await; - *omikron_connection = Some(omikron.clone()); - } - log_t!("setup_completed"); - loop { - if *SHUTDOWN.read().await { - break; - } - if !omikron.is_connected().await { - break; - } - sleep(Duration::from_millis(100)).await; - } + + sleep(Duration::from_millis(100)).await; } if *RELOAD.read().await { loop { @@ -190,7 +175,7 @@ async fn main() { } &CONFIG.write().await.clear(); user_manager::clear(); - community_manager::clear(); + /*community_manager::clear();*/ *APP_STATE.lock().unwrap() = AppState::new(); } ui.terminal.lock().unwrap().clear(); diff --git a/src/omikron/omikron_connection.rs b/src/omikron/omikron_connection.rs old mode 100644 new mode 100755 index ae8d071..3e92317 --- a/src/omikron/omikron_connection.rs +++ b/src/omikron/omikron_connection.rs @@ -5,59 +5,275 @@ use crate::util::chats_util::{get_user, mod_user}; use crate::util::crypto_util::{DataFormat, SecurePayload}; use crate::util::file_util::{get_children, load_file, save_file}; use crate::util::{chat_files, chats_util}; -use crate::{ACTIVE_TASKS, SHUTDOWN, log, log_cv_in, log_cv_out, log_t}; -use crate::{ - data::communication::{CommunicationType, CommunicationValue, DataTypes}, - util::{config_util::CONFIG, crypto_helper}, -}; +use crate::util::{config_util::CONFIG, crypto_helper}; +use crate::{ACTIVE_TASKS, SHUTDOWN, log, log_cv_in, log_t}; use dashmap::DashMap; -use futures::Stream; -use futures_util::sink::Sink; -use futures_util::{SinkExt, StreamExt}; +use epsilon_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; +use epsilon_native::{Receiver, Sender}; use json::JsonValue; -use json::number::Number; use std::collections::HashMap; use std::sync::{Arc, LazyLock}; -use std::time::{SystemTime, UNIX_EPOCH}; -use tokio::sync::{Mutex, RwLock, mpsc}; -use tokio::time::{Duration, Instant, sleep}; -use tokio_tungstenite::{connect_async, tungstenite::protocol::Message}; -use tungstenite::Utf8Bytes; +use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; +use tokio::sync::{Mutex, RwLock, mpsc, watch}; +use tokio::task::JoinHandle; +use tokio::time::sleep; use uuid::Uuid; -use warp::filters::log::log; -pub static OMIKRON_CONNECTION: LazyLock>>>> = - LazyLock::new(|| Arc::new(RwLock::new(None))); +// ============================================================================ +// Configuration +// ============================================================================ + +const OMIKRON_HOST_DEFAULT: &str = "methanium.net"; +const OMIKRON_PORT_DEFAULT: u16 = 959; +const RECONNECT_DELAY: Duration = Duration::from_secs(5); +const MAX_RECONNECT_DELAY: Duration = Duration::from_secs(300); +const CONNECTION_TIMEOUT: Duration = Duration::from_secs(10); +const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(10); +const TASK_CLEANUP_INTERVAL: Duration = Duration::from_secs(60); +const TASK_MAX_AGE: Duration = Duration::from_secs(60); + +// ============================================================================ +// Waiting Task System +// ============================================================================ + +pub struct WaitingTask { + pub task: Box, CommunicationValue) -> bool + Send + Sync>, + pub inserted_at: Instant, +} + +pub static WAITING_TASKS: LazyLock> = LazyLock::new(|| DashMap::new()); + +pub fn start_task_cleanup_loop() { + tokio::spawn(async { + loop { + sleep(TASK_CLEANUP_INTERVAL).await; + WAITING_TASKS.retain(|_, v| v.inserted_at.elapsed() < TASK_MAX_AGE); + } + }); +} + +// ============================================================================ +// Connection State +// ============================================================================ + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum ConnectionState { + Disconnected, + Connecting, + Connected { identified: bool }, +} + +impl ConnectionState { + pub fn is_connected(&self) -> bool { + matches!(self, ConnectionState::Connected { .. }) + } + + pub fn is_identified(&self) -> bool { + matches!(self, ConnectionState::Connected { identified: true }) + } +} + +// ============================================================================ +// Omikron Connection (Client-side with auto-reconnect) +// ============================================================================ -#[derive(Clone)] pub struct OmikronConnection { - pub(crate) writer: - Arc + Send + Unpin>>>>, - waiting: Arc>>, + state: Arc>, + sender: Arc>>>, + connection_loop_handle: Arc>>>, + host: String, + port: u16, pub last_ping: Arc>, - pub message_send_times: Arc>>, - pub is_connected: Arc>, + heartbeat_handle: Arc>>>, + message_send_times: Arc>>, + pub connection_id: Uuid, + shutdown_tx: Arc>>>, + reconnect_on_close: Arc>, } impl OmikronConnection { pub fn new() -> Self { - Self { - writer: Arc::new(Mutex::new(None)), - waiting: Arc::new(DashMap::new()), + Self::with_host(OMIKRON_HOST_DEFAULT, OMIKRON_PORT_DEFAULT) + } + + pub fn with_host(host: &str, port: u16) -> Self { + let (shutdown_tx, _) = watch::channel(false); + + OmikronConnection { + state: Arc::new(RwLock::new(ConnectionState::Disconnected)), + sender: Arc::new(RwLock::new(None)), + connection_loop_handle: Arc::new(Mutex::new(None)), + host: host.to_string(), + port, last_ping: Arc::new(Mutex::new(-1)), + heartbeat_handle: Arc::new(Mutex::new(None)), message_send_times: Arc::new(Mutex::new(HashMap::new())), - is_connected: Arc::new(Mutex::new(false)), + connection_id: Uuid::new_v4(), + shutdown_tx: Arc::new(Mutex::new(Some(shutdown_tx))), + reconnect_on_close: Arc::new(RwLock::new(true)), } } - pub async fn is_connected(&self) -> bool { - *self.is_connected.lock().await - } + + // ------------------------------------------------------------------------- + // Connection Management + // ------------------------------------------------------------------------- pub async fn connect(self: &Arc) { - if self.is_connected().await { - return; + if self.connection_loop_handle.lock().await.is_none() { + self.clone().start().await; + } + } + + pub async fn start(self: Arc) { + if let Some(handle) = self.connection_loop_handle.lock().await.take() { + handle.abort(); } + *self.reconnect_on_close.write().await = true; + + let self_clone = self.clone(); + let handle = tokio::spawn(async move { + self_clone.connection_loop().await; + }); + + *self.connection_loop_handle.lock().await = Some(handle); + } + + pub async fn stop(&self) { + *self.reconnect_on_close.write().await = false; + + if let Some(tx) = self.shutdown_tx.lock().await.take() { + let _ = tx.send(true); + } + + if let Some(handle) = self.connection_loop_handle.lock().await.take() { + handle.abort(); + } + + if let Some(handle) = self.heartbeat_handle.lock().await.take() { + handle.abort(); + } + + if let Some(sender) = self.sender.read().await.as_ref() { + sender.close(); + } + + *self.state.write().await = ConnectionState::Disconnected; + *self.sender.write().await = None; + } + + async fn connection_loop(self: Arc) { + let mut reconnect_delay = RECONNECT_DELAY; + let shutdown_rx = self.shutdown_tx.lock().await.as_ref().unwrap().subscribe(); + let mut shutdown_rx = shutdown_rx; + + loop { + if *shutdown_rx.borrow() || *SHUTDOWN.read().await { + log_t!("omikron_connection_loop_shutdown"); + break; + } + + if !*self.reconnect_on_close.read().await { + break; + } + + match self.clone().connect_once().await { + Ok(()) => { + if *self.reconnect_on_close.read().await { + log!("Connection lost, reconnecting in {:?}...", reconnect_delay); + } else { + break; + } + } + Err(e) => { + log!( + "Connection failed: {}, retrying in {:?}...", + e, + reconnect_delay + ); + } + } + + tokio::select! { + _ = sleep(reconnect_delay) => {} + _ = shutdown_rx.changed() => { + if *shutdown_rx.borrow() { + break; + } + } + } + + reconnect_delay = std::cmp::min(reconnect_delay * 2, MAX_RECONNECT_DELAY); + } + } + + async fn connect_once(self: Arc) -> Result<(), String> { + *self.state.write().await = ConnectionState::Connecting; + log_t!("omikron_connecting"); + + let addr_str = format!("https://{}:{}/ws/iota/", self.host, self.port); + + let (sender, mut receiver) = epsilon_native::client::connect(&addr_str, None) + .await + .map_err(|e| format!("Connection failed: {}", e))?; + + log_t!("omikron_connection_success"); + + let sender_arc = Arc::new(sender); + *self.sender.write().await = Some(sender_arc.clone()); + *self.state.write().await = ConnectionState::Connected { identified: false }; + + // Handle registration/identification + self.handle_authentication().await; + + // Start read loop + let read_self = self.clone(); + let read_handle = tokio::spawn(async move { + read_self.read_loop(&mut receiver).await; + }); + + // Start heartbeat + let heartbeat_self = self.clone(); + let heartbeat_handle = tokio::spawn(async move { + heartbeat_self.heartbeat_loop().await; + }); + *self.heartbeat_handle.lock().await = Some(heartbeat_handle); + + { + ACTIVE_TASKS.insert("Omikron Listener".to_string()); + } + + // Wait for read loop to complete + let result = read_handle.await; + + // Cleanup + *self.sender.write().await = None; + *self.state.write().await = ConnectionState::Disconnected; + { + ACTIVE_TASKS.remove("Omikron Listener"); + } + + if let Some(handle) = self.heartbeat_handle.lock().await.take() { + handle.abort(); + } + + match result { + Ok(()) => { + if *self.reconnect_on_close.read().await { + Err("Connection closed, will reconnect".to_string()) + } else { + Ok(()) + } + } + Err(e) => Err(format!("Read loop error: {}", e)), + } + } + + // ------------------------------------------------------------------------- + // Authentication (Registration/Identification) + // ------------------------------------------------------------------------- + + async fn handle_authentication(&self) { let conf = CONFIG.read().await; let iota_id = conf.get_iota_id(); let public_key = conf.get_public_key(); @@ -71,651 +287,538 @@ impl OmikronConnection { let private_key_base64 = crypto_helper::secret_key_to_base64(&key_pair.secret); let mut conf_write = CONFIG.write().await; - conf_write.change("public_key", JsonValue::String(public_key_base64.clone())); - conf_write.change("private_key", JsonValue::String(private_key_base64)); + /*conf_write.change("public_key", DataValue::Str(public_key_base64.clone())); + conf_write.change("private_key", DataValue::Str(private_key_base64));*/ conf_write.update(); drop(conf_write); - if self.connect_internal().await { - match self - .clone() - .await_response( - &CommunicationValue::new(CommunicationType::register_iota) - .add_data(DataTypes::public_key, JsonValue::String(public_key_base64)), - Some(Duration::from_secs(20)), - ) - .await - { - Ok(response_cv) => { - let iota_json = response_cv - .get_data(DataTypes::register_id) - .unwrap_or(&JsonValue::Null); - let iota_id = iota_json.as_i64().unwrap_or(0); + let register_msg = CommunicationValue::new(CommunicationType::register_iota) + .add_data(DataTypes::public_key, DataValue::Str(public_key_base64)); - let mut conf_write = CONFIG.write().await; - conf_write.change("iota_id", iota_json.clone()); - conf_write.update(); - drop(conf_write); - log!("Registered with Iota-ID: {}", iota_id); - } - Err(timeout) => { - log!("{}", timeout); - } + let msg_id = register_msg.get_id(); + + WAITING_TASKS.insert( + msg_id, + WaitingTask { + task: Box::new(|selfc, cv| { + if !cv.is_type(CommunicationType::success) { + return false; + } + + let iota_value = cv.get_data(DataTypes::register_id); + let iota_id = iota_value.as_number().unwrap_or(0); + + if iota_id != 0 { + tokio::spawn(async move { + let mut conf_write = CONFIG.write().await; + conf_write.change("iota_id", JsonValue::from(iota_id)); + conf_write.update(); + drop(conf_write); + log!("Registered with Iota-ID: {}", iota_id); + + // Send identification after registration + let identify_msg = + CommunicationValue::new(CommunicationType::identification) + .add_data(DataTypes::iota_id, DataValue::Number(iota_id)); + selfc.send_message(&identify_msg).await; + }); + } else { + log!("Iota registration failed."); + } + true + }), + inserted_at: Instant::now(), + }, + ); + + self.send_message(®ister_msg).await; + } else { + let identify_msg = CommunicationValue::new(CommunicationType::identification) + .add_data(DataTypes::iota_id, DataValue::Number(iota_id)); + self.send_message(&identify_msg).await; + } + } + + // ------------------------------------------------------------------------- + // Read Loop & Heartbeat + // ------------------------------------------------------------------------- + + async fn read_loop(self: Arc, receiver: &mut Receiver) { + loop { + let result = receiver.receive().await; + match result { + Ok(cv) => { + self.clone().handle_message(cv).await; + } + Err(e) => { + log!("Receive error: {}", e); + break; } } - } else { - if self.connect_internal().await { + if !receiver.is_open() { + log!("Connection closed "); + break; + } + } + } + + async fn heartbeat_loop(self: Arc) { + loop { + sleep(HEARTBEAT_INTERVAL).await; + + if !self.state.read().await.is_connected() { + break; + } + + if let Some(sender) = self.sender.read().await.as_ref() { + if !sender.is_open() { + break; + } + } else { + break; + } + + self.send_ping().await; + } + } + + // ------------------------------------------------------------------------- + // Message Handling (Preserved from original) + // ------------------------------------------------------------------------- + + pub async fn handle_message(self: Arc, cv: CommunicationValue) { + log_cv_in!(&cv); + + let msg_id = cv.get_id(); + + // Only check new waiting tasks + if let Some((_, task)) = WAITING_TASKS.remove(&msg_id) { + if (task.task)(self.clone(), cv.clone()) { + return; + } + } + + // Check new waiting tasks + if let Some((_, task)) = WAITING_TASKS.remove(&msg_id) { + if (task.task)(self.clone(), cv.clone()) { + return; + } + } + + if cv.is_type(CommunicationType::pong) { + self.handle_pong(&cv).await; + return; + } + + if cv.is_type(CommunicationType::challenge) { + self.handle_challenge(&cv).await; + return; + } + + if cv.is_type(CommunicationType::success) { + let iota_id = cv.get_data(DataTypes::iota_id).as_number().unwrap_or(0); + if iota_id != 0 { + let mut conf = CONFIG.write().await; + conf.change("iota_id", JsonValue::from(iota_id as i64)); + conf.update(); + log!("Iota registered with ID: {}", iota_id); + + let login_message = CommunicationValue::new(CommunicationType::identification) + .add_data(DataTypes::iota_id, DataValue::Number(iota_id)); + + let self_clone = self.clone(); + tokio::spawn(async move { + self_clone.send_message(&login_message).await; + }); + } + return; + } + + if cv.is_type(CommunicationType::identification_response) { + if let Some(accepted) = cv.get_data(DataTypes::accepted).as_bool() { + log!("Omikron connected: {}", accepted.to_string()); + let mut state = self.state.write().await; + if let ConnectionState::Connected { identified: _ } = *state { + *state = ConnectionState::Connected { identified: true }; + } + } + return; + } + + // ************************************************ // + // Direct messages // + // ************************************************ // + if cv.is_type(CommunicationType::message_state) { + let sender_id = &cv.get_sender(); + let receiver_id = &cv.get_receiver(); + + let _ = chat_files::change_message_state( + cv.get_data(DataTypes::send_time).as_number().unwrap_or(0) as i64, + *receiver_id as i64, + *sender_id as i64, + MessageState::from_str( + cv.get_data(DataTypes::message_state).as_str().unwrap_or(""), + ), + ); + } + + if cv.is_type(CommunicationType::message_other_iota) { + let sender_id = &cv.get_sender(); + let receiver_id = &cv.get_receiver(); + let timestamp = cv.get_data(DataTypes::send_time).as_number().unwrap_or( + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as i64, + ); + + chat_files::add_message( + timestamp as u128, + false, + *receiver_id as i64, + *sender_id as i64, + cv.get_data(DataTypes::content).as_str().unwrap(), + ); + + let user_forward = CommunicationValue::new(CommunicationType::message_live) + .with_id(cv.get_id()) + .with_receiver(*receiver_id) + .add_data( + DataTypes::send_time, + cv.get_data(DataTypes::send_time).clone(), + ) + .add_data(DataTypes::message, cv.get_data(DataTypes::content).clone()) + .add_data( + DataTypes::sender_id, + DataValue::Number(cv.get_sender() as i64), + ); + + let user_resp = self + .clone() + .await_response(&user_forward, Some(Duration::from_secs(10))) + .await; + + if let Ok(user_resp) = user_resp { + let ms = MessageState::from_str( + &user_resp + .get_data(DataTypes::message_state) + .as_string() + .unwrap_or("".to_string()), + ) + .upgrade(MessageState::Received); + let _ = change_message_state( + timestamp, + *receiver_id as i64, + *sender_id as i64, + ms.clone(), + ); + self.send_message( - &CommunicationValue::new(CommunicationType::identification).add_data( - DataTypes::iota_id, - JsonValue::Number(json::number::Number::from(iota_id)), - ), + &CommunicationValue::new(CommunicationType::message_state) + .with_id(cv.get_id()) + .with_receiver(*sender_id) + .with_sender(*receiver_id) + .add_data( + DataTypes::send_time, + cv.get_data(DataTypes::send_time).clone(), + ) + .add_data( + DataTypes::message_state, + DataValue::Str(ms.as_str().to_string()), + ), + ) + .await; + } else { + self.send_message( + &CommunicationValue::new(CommunicationType::message_state) + .with_id(cv.get_id()) + .with_receiver(*sender_id) + .with_sender(*receiver_id) + .add_data( + DataTypes::send_time, + cv.get_data(DataTypes::send_time).clone(), + ) + .add_data( + DataTypes::message_state, + DataValue::Str(MessageState::Sent.as_str().to_string()), + ), ) .await; } + return; } - } - async fn connect_internal(self: &Arc) -> bool { - if self.is_connected().await { - return true; + if cv.is_type(CommunicationType::message_send) { + let my_id = cv.get_sender(); + let other_id = cv.get_data(DataTypes::receiver_id).as_number().unwrap_or(0); + let now_ms = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as u128; + + chat_files::add_message( + now_ms, + true, + my_id as i64, + other_id, + &*cv.get_data(DataTypes::content).as_str().unwrap(), + ); + + let ack = CommunicationValue::new(CommunicationType::success) + .with_id(cv.get_id()) + .with_receiver(my_id); + self.send_message(&ack).await; + + let forward = CommunicationValue::new(CommunicationType::message_other_iota) + .with_id(cv.get_id()) + .with_receiver(other_id as u64) + .add_data(DataTypes::receiver_id, DataValue::Number(other_id)) + .with_sender(my_id) + .add_data(DataTypes::send_time, DataValue::Str(now_ms.to_string())) + .add_data(DataTypes::sender_id, DataValue::Number(my_id as i64)) + .add_data( + DataTypes::content, + DataValue::Str( + cv.get_data(DataTypes::content) + .as_str() + .unwrap() + .to_string(), + ), + ); + self.send_message(&forward).await; + return; } - log_t!("omikron_connecting"); - let conf = CONFIG.read().await; - let addr = conf - .get("omikron_addr") - .as_str() - .unwrap_or("wss://app.tensamin.net/ws/iota/"); - let stream_res = connect_async(addr).await; - if let Err(e) = stream_res { - log!("con error {}", e.to_string()); - return false; + if cv.is_type(CommunicationType::messages_get) { + let my_id = cv.get_sender(); + let partner_id = cv.get_data(DataTypes::user_id).as_number().unwrap_or(0); + let offset = cv.get_data(DataTypes::offset).as_number().unwrap_or(0); + let amount = cv.get_data(DataTypes::amount).as_number().unwrap_or(0); + // let messages = chat_files::get_messages(my_id as i64, partner_id, offset, amount); + let resp = CommunicationValue::new(CommunicationType::messages_get) + .with_id(cv.get_id()) + .with_receiver(my_id) + //.add_data(DataTypes::messages, messages) + ; + + self.send_message(&resp).await; + return; } - let (stream, _) = stream_res.unwrap(); - log_t!("omikron_connection_success"); - let (write_half, read_half) = stream.split(); + if cv.is_type(CommunicationType::get_chats) { + let user_id = cv.get_sender(); + let users = chats_util::get_users(user_id as i64).as_i64().unwrap(); + let resp = CommunicationValue::new(CommunicationType::get_chats) + .with_id(cv.get_id()) + .with_receiver(user_id) + .add_data(DataTypes::user_ids, DataValue::Number(users)); + self.send_message(&resp).await; + return; + } - *self.writer.lock().await = Some(Box::new(write_half)); - let boxed_reader: Box< - dyn Stream> + Send + Unpin, - > = Box::new(read_half); - self.spawn_listener(boxed_reader).await; + if cv.is_type(CommunicationType::add_conversation) { + let user_id = cv.get_sender(); + let other_id = cv + .get_data(DataTypes::chat_partner_id) + .as_number() + .unwrap_or(0); + let mut contact = get_user(user_id as i64, other_id).unwrap_or(Contact::new(other_id)); + contact.set_last_message_at( + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_millis() as i64, + ); + mod_user(user_id as i64, &contact); + let resp = CommunicationValue::new(CommunicationType::add_conversation) + .with_id(cv.get_id()) + .with_receiver(user_id); + self.send_message(&resp).await; + return; + } - let mut is_connected = self.is_connected.lock().await; - *is_connected = true; - drop(is_connected); + if cv.is_type(CommunicationType::add_community) { + UserCommunityUtil::add_community( + cv.get_sender() as i64, + cv.get_data(DataTypes::community_address) + .as_str() + .unwrap() + .to_string(), + cv.get_data(DataTypes::community_title) + .as_str() + .unwrap() + .to_string(), + cv.get_data(DataTypes::position) + .as_str() + .unwrap() + .to_string(), + ); + let resp = CommunicationValue::new(CommunicationType::add_community) + .with_id(cv.get_id()) + .with_receiver(cv.get_sender()); + self.send_message(&resp).await; + return; + } - let sel_arc_clone = self.clone(); - tokio::spawn(async move { - loop { - if *SHUTDOWN.read().await { - break; + if cv.is_type(CommunicationType::get_communities) { + let resp = CommunicationValue::new(CommunicationType::get_communities) + .with_id(cv.get_id()) + .with_receiver(cv.get_sender()) + /*.add_data( + DataTypes::communities, + DataValue::Array(UserCommunityUtil::get_communities(cv.get_sender() as i64)), + ) */; + self.send_message(&resp).await; + return; + } + + if cv.is_type(CommunicationType::remove_community) { + UserCommunityUtil::remove_community( + cv.get_sender() as i64, + cv.get_data(DataTypes::community_address) + .as_str() + .unwrap() + .to_string(), + ); + let resp = CommunicationValue::new(CommunicationType::remove_community) + .with_id(cv.get_id()) + .with_receiver(cv.get_sender()); + self.send_message(&resp).await; + return; + } + + if cv.is_type(CommunicationType::settings_save) { + let my_id = cv.get_sender(); + let settings_name = cv.get_data(DataTypes::settings_name).as_str().unwrap(); + let settings_value = cv.get_data(DataTypes::payload).as_str().unwrap(); + + save_file( + &format!("users/{}/settings/", my_id), + &format!("{}.settings", settings_name), + &settings_value, + ); + + let response = CommunicationValue::new(CommunicationType::settings_save) + .with_receiver(my_id) + .with_id(cv.get_id()); + + self.send_message(&response).await; + return; + } + + if cv.is_type(CommunicationType::settings_load) { + let my_id = cv.get_sender(); + let settings_name = cv.get_data(DataTypes::settings_name).as_string().unwrap(); + let settings_value_str = load_file( + &format!("users/{}/settings/", my_id), + &format!("{}.settings", settings_name), + ); + let response = CommunicationValue::new(CommunicationType::settings_load) + .with_id(cv.get_id()) + .with_receiver(my_id) + .add_data(DataTypes::payload, DataValue::Str(settings_value_str)) + .add_data(DataTypes::settings_name, DataValue::Str(settings_name)); + + self.send_message(&response).await; + return; + } + + if cv.is_type(CommunicationType::settings_list) { + let my_id = cv.get_sender(); + let settings = get_children(&format!("users/{}/settings/", my_id)); + let mut settings_json = Vec::new(); + for s in settings { + let s = s.replace(".settings", ""); + if s.is_empty() { + continue; } - if !sel_arc_clone.is_connected().await { - break; - } - sel_arc_clone.send_ping().await; - sleep(Duration::from_secs(10)).await; + let _ = settings_json.push(DataValue::Str(s)); } - }); + let response = CommunicationValue::new(CommunicationType::settings_list) + .with_id(cv.get_id()) + .with_receiver(my_id) + .add_data(DataTypes::settings, DataValue::Array(settings_json)); - true + self.send_message(&response).await; + return; + } } + async fn handle_challenge(&self, cv: &CommunicationValue) { + let conf = CONFIG.read().await; + let private_key = conf.get_private_key().unwrap(); + drop(conf); + + let omikron_public_key = cv.get_data(DataTypes::public_key).as_str().unwrap(); + let encrypted_challenge = cv.get_data(DataTypes::challenge).as_str().unwrap(); + + let solved_challenge = { + if let Ok(decrypted) = SecurePayload::new( + encrypted_challenge, + DataFormat::Base64, + crypto_helper::load_secret_key(&private_key).unwrap(), + ) { + if let Ok(decrypted) = decrypted + .decrypt_x448(crypto_helper::load_public_key(omikron_public_key).unwrap()) + { + Some(decrypted) + } else { + None + } + } else { + None + } + }; + + if let Some(decrypted) = solved_challenge { + let response = CommunicationValue::new(CommunicationType::challenge_response) + .with_id(cv.get_id()) + .add_data( + DataTypes::challenge, + DataValue::Str(decrypted.export(DataFormat::Base64)), + ); + + self.send_message(&response).await; + } else { + log!("Failed to decrypt challenge"); + } + } + + // ------------------------------------------------------------------------- + // Public API + // ------------------------------------------------------------------------- + pub async fn send_message(&self, cv: &CommunicationValue) { - if !cv.is_type(CommunicationType::ping) { - log_cv_out!(cv); - } - Self::send_message_static( - &self.writer, - Arc::clone(&self.is_connected), - cv.to_json().to_string(), - ) - .await; - } - - async fn spawn_listener( - self: &Arc, - mut read_half: Box> + Send + Unpin>, - ) { - 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(); - - { - ACTIVE_TASKS.insert("Omikron Listener".to_string()); - } - tokio::spawn(async move { - while let Some(msg) = read_half.next().await { - if *SHUTDOWN.read().await { - break; + let sender_guard = self.sender.read().await; + if let Some(sender) = sender_guard.as_ref() { + if !sender.is_open() { + log_t!("send_message_failed", "connection closed".to_string()); + drop(sender_guard); + if let Some(sender) = self.sender.write().await.take() { + sender.close(); } - sel_out - .clone() - .handle_message( - msg, - waiting_out.clone(), - writer_out.clone(), - is_connected_out.clone(), - ) - .await; - } - *is_connected_out.lock().await = false; - log!("Connection closed."); - { - ACTIVE_TASKS.remove("Omikron Listener"); - } - }); - } - pub async fn handle_message( - self: Arc, - msg: Result, - waiting: Arc>>, - writer: Arc< - Mutex< - Option + Send + Unpin + 'static>>, - >, - >, - is_connected: Arc>, - ) { - match msg { - Ok(Message::Close(Some(frame))) => { - log!("[Omikron] Closed: {:?}", frame); - *is_connected.lock().await = false; return; } - Ok(Message::Text(text)) => { - let cv = CommunicationValue::from_json(&text); - if let Some((_, y)) = waiting.remove(&cv.get_id()) { - y(cv); - return; - } - if cv.is_type(CommunicationType::pong) { - self.handle_pong(&cv, true).await; - return; - } - log_cv_in!(&cv); - if cv.is_type(CommunicationType::challenge) { - let conf = CONFIG.read().await; - let private_key = conf.get_private_key().unwrap(); - drop(conf); - let omikron_public_key = cv - .get_data(DataTypes::public_key) - .unwrap() - .as_str() - .unwrap(); - let encrypted_challenge = - cv.get_data(DataTypes::challenge).unwrap().as_str().unwrap(); + let sender_clone = Arc::clone(sender); + drop(sender_guard); - let solved_challenge = { - if let Ok(decrypted) = SecurePayload::new( - encrypted_challenge, - DataFormat::Base64, - crypto_helper::load_secret_key(&private_key).unwrap(), - ) { - if let Ok(decrypted) = decrypted.decrypt_x448( - crypto_helper::load_public_key(omikron_public_key).unwrap(), - ) { - Some(decrypted) - } else { - None - } - } else { - None - } - }; - - if let Some(decrypted) = solved_challenge { - let response = - CommunicationValue::new(CommunicationType::challenge_response) - .with_id(cv.get_id()) - .add_data( - DataTypes::challenge, - JsonValue::String(decrypted.export(DataFormat::Base64)), - ); - - self.send_message(&response).await; - } else { - log!("Failed to decrypt challenge"); - } - - return; - } - if cv.is_type(CommunicationType::success) { - let iota_id = cv - .get_data(DataTypes::iota_id) - .unwrap_or(&JsonValue::Null) - .as_i64() - .unwrap_or(0); - if iota_id != 0 { - let mut conf = CONFIG.write().await; - conf.change("iota_id", JsonValue::Number(iota_id.into())); - conf.update(); - log!("Iota registered with ID: {}", iota_id); - - let login_message = - CommunicationValue::new(CommunicationType::identification).add_data( - DataTypes::iota_id, - JsonValue::Number(json::number::Number::from(iota_id)), - ); - - let self_clone = self.clone(); - tokio::spawn(async move { - self_clone.send_message(&login_message).await; - }); - } else { - log("Iota registration failed."); - } - return; - } - if cv.is_type(CommunicationType::identification_response) { - if let Some(accepted) = cv.get_data(DataTypes::accepted) { - log!("Omikron connected: {}", accepted.to_string()); - } - return; - } - - // ************************************************ // - // Direct messages // - // ************************************************ // - if cv.is_type(CommunicationType::message_state) { - let sender_id = &cv.get_sender(); - let receiver_id = &cv.get_receiver(); - - let _ = chat_files::change_message_state( - cv.get_data(DataTypes::send_time) - .unwrap_or(&JsonValue::new_object()) - .as_i64() - .unwrap_or(0) as i64, - *receiver_id, - *sender_id, - MessageState::from_str( - cv.get_data(DataTypes::message_state) - .unwrap_or(&JsonValue::Null) - .as_str() - .unwrap_or(""), - ), - ); - } - if cv.is_type(CommunicationType::message_other_iota) { - let sender_id = &cv.get_sender(); - let receiver_id = &cv.get_receiver(); - let timestamp = cv - .get_data(DataTypes::send_time) - .unwrap_or(&JsonValue::new_object()) - .as_i64() - .unwrap_or( - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as i64, - ); - chat_files::add_message( - timestamp as u128, - false, - *receiver_id, - *sender_id, - cv.get_data(DataTypes::content).unwrap().as_str().unwrap(), - ); - let user_forward = CommunicationValue::new(CommunicationType::message_live) - .with_id(cv.get_id()) - .with_receiver(*receiver_id) - .add_data( - DataTypes::send_time, - cv.get_data(DataTypes::send_time).unwrap().clone(), - ) - .add_data( - DataTypes::message, - cv.get_data(DataTypes::content).unwrap().clone(), - ) - .add_data( - DataTypes::sender_id, - JsonValue::Number(Number::from(cv.get_sender())), - ); - let user_resp = self - .clone() - .await_response(&user_forward, Some(Duration::from_secs(10))) - .await; - - if let Ok(user_resp) = user_resp { - let ms = MessageState::from_str( - user_resp - .get_data(DataTypes::message_state) - .unwrap_or(&JsonValue::Null) - .as_str() - .unwrap_or(""), - ) - .upgrade(MessageState::Received); - let _ = - change_message_state(timestamp, *receiver_id, *sender_id, ms.clone()); - self.send_message( - &CommunicationValue::new(CommunicationType::message_state) - .with_id(cv.get_id()) - .with_receiver(*sender_id) - .with_sender(*receiver_id) - .add_data( - DataTypes::send_time, - cv.get_data(DataTypes::send_time).unwrap().clone(), - ) - .add_data(DataTypes::message_state, JsonValue::from(ms.as_str())), - ) - .await; - } else { - self.send_message( - &CommunicationValue::new(CommunicationType::message_state) - .with_id(cv.get_id()) - .with_receiver(*sender_id) - .with_sender(*receiver_id) - .add_data( - DataTypes::send_time, - cv.get_data(DataTypes::send_time).unwrap().clone(), - ) - .add_data( - DataTypes::message_state, - JsonValue::from(MessageState::Sent.as_str()), - ), - ) - .await; - } - return; - } - - if cv.is_type(CommunicationType::message_send) { - let my_id = cv.get_sender(); - let other_id = cv - .get_data(DataTypes::receiver_id) - .unwrap_or(&JsonValue::Null) - .as_i64() - .unwrap_or(0); - let now_ms = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as u128; - - chat_files::add_message( - now_ms, - true, - my_id, - other_id, - &*cv.get_data(DataTypes::content).unwrap().to_string(), - ); - - let ack = CommunicationValue::new(CommunicationType::success) - .with_id(cv.get_id()) - .with_receiver(my_id); - Self::send_message_static( - &writer.clone(), - Arc::clone(&is_connected), - ack.to_json().to_string(), - ) - .await; - - let forward = CommunicationValue::new(CommunicationType::message_other_iota) - .with_id(cv.get_id()) - .with_receiver(other_id) - .add_data( - DataTypes::receiver_id, - JsonValue::Number(Number::from(other_id)), - ) - .with_sender(my_id) - .add_data(DataTypes::send_time, JsonValue::String(now_ms.to_string())) - .add_data(DataTypes::sender_id, JsonValue::Number(Number::from(my_id))) - .add_data( - DataTypes::content, - JsonValue::String(cv.get_data(DataTypes::content).unwrap().to_string()), - ); - Self::send_message_static( - &writer.clone(), - is_connected, - forward.to_json().to_string(), - ) - .await; - return; - } - - if cv.is_type(CommunicationType::messages_get) { - let my_id = cv.get_sender(); - let partner_id = cv - .get_data(DataTypes::user_id) - .unwrap_or(&JsonValue::Null) - .as_i64() - .unwrap_or(0); - let offset = cv - .get_data(DataTypes::offset) - .unwrap_or(&JsonValue::Null) - .to_string() - .parse::() - .unwrap_or(0); - let amount = cv - .get_data(DataTypes::amount) - .unwrap_or(&JsonValue::Null) - .to_string() - .parse::() - .unwrap_or(0); - let messages = chat_files::get_messages(my_id, partner_id, offset, amount); - let resp = CommunicationValue::new(CommunicationType::messages_get) - .with_id(cv.get_id()) - .with_receiver(my_id) - .add_data(DataTypes::messages, messages); - - Self::send_message_static( - &writer.clone(), - is_connected, - resp.to_json().to_string(), - ) - .await; - return; - } - - if cv.is_type(CommunicationType::get_chats) { - let user_id = cv.get_sender(); - let users = chats_util::get_users(user_id); - let resp = CommunicationValue::new(CommunicationType::get_chats) - .with_id(cv.get_id()) - .with_receiver(user_id) - .add_data(DataTypes::user_ids, users); - Self::send_message_static( - &writer.clone(), - is_connected, - resp.to_json().to_string(), - ) - .await; - return; - } - - if cv.is_type(CommunicationType::add_conversation) { - let user_id = cv.get_sender(); - let other_id = cv - .get_data(DataTypes::chat_partner_id) - .unwrap_or(&JsonValue::Null) - .as_i64() - .unwrap_or(0); - let mut contact = get_user(user_id, other_id).unwrap_or(Contact::new(other_id)); - contact.set_last_message_at( - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as i64, - ); - mod_user(user_id, &contact); - let resp = CommunicationValue::new(CommunicationType::add_conversation) - .with_id(cv.get_id()) - .with_receiver(user_id); - Self::send_message_static( - &writer.clone(), - is_connected, - resp.to_json().to_string(), - ) - .await; - return; - } - - if cv.is_type(CommunicationType::add_community) { - UserCommunityUtil::add_community( - cv.get_sender(), - cv.get_data(DataTypes::community_address) - .unwrap() - .to_string(), - cv.get_data(DataTypes::community_title).unwrap().to_string(), - cv.get_data(DataTypes::position).unwrap().to_string(), - ); - let resp = CommunicationValue::new(CommunicationType::add_community) - .with_id(cv.get_id()) - .with_receiver(cv.get_sender()); - Self::send_message_static( - &writer.clone(), - is_connected, - resp.to_json().to_string(), - ) - .await; - return; - } - - if cv.is_type(CommunicationType::get_communities) { - let resp = CommunicationValue::new(CommunicationType::get_communities) - .with_id(cv.get_id()) - .with_receiver(cv.get_sender()) - .add_array( - DataTypes::communities, - UserCommunityUtil::get_communities(cv.get_sender()), - ); - Self::send_message_static( - &writer.clone(), - is_connected, - resp.to_json().to_string(), - ) - .await; - return; - } - - if cv.is_type(CommunicationType::remove_community) { - UserCommunityUtil::remove_community( - cv.get_sender(), - cv.get_data(DataTypes::community_address) - .unwrap() - .to_string(), - ); // needs UserCommunityUtil - let resp = CommunicationValue::new(CommunicationType::remove_community) - .with_id(cv.get_id()) - .with_receiver(cv.get_sender()); - Self::send_message_static( - &writer.clone(), - is_connected, - resp.to_json().to_string(), - ) - .await; - return; - } - - if cv.is_type(CommunicationType::settings_save) { - let my_id = cv.get_sender(); - let settings_name = cv.get_data(DataTypes::settings_name).unwrap().to_string(); - let settings_value = cv.get_data(DataTypes::payload).unwrap().to_string(); - - save_file( - &format!("users/{}/settings/", my_id), - &format!("{}.settings", settings_name), - &settings_value, - ); - - let response = CommunicationValue::new(CommunicationType::settings_save) - .with_receiver(my_id) - .with_id(cv.get_id()); - - Self::send_message_static( - &writer.clone(), - is_connected, - response.to_json().to_string(), - ) - .await; - return; - } - if cv.is_type(CommunicationType::settings_load) { - let my_id = cv.get_sender(); - let settings_name = cv.get_data(DataTypes::settings_name).unwrap().to_string(); - let settings_value_str = load_file( - &format!("users/{}/settings/", my_id), - &format!("{}.settings", settings_name), - ); - let settings_value_json = JsonValue::from(settings_value_str); - let response = CommunicationValue::new(CommunicationType::settings_load) - .with_id(cv.get_id()) - .with_receiver(my_id) - .add_data(DataTypes::payload, settings_value_json) - .add_data_str(DataTypes::settings_name, settings_name); - - Self::send_message_static( - &writer.clone(), - is_connected, - response.to_json().to_string(), - ) - .await; - return; - } - if cv.is_type(CommunicationType::settings_list) { - let my_id = cv.get_sender(); - let settings = get_children(&format!("users/{}/settings/", my_id)); - let mut settings_json = JsonValue::new_array(); - for s in settings { - let s = s.replace(".settings", ""); - if s.is_empty() { - continue; - } - let _ = settings_json.push(JsonValue::String(s)); - } - let response = CommunicationValue::new(CommunicationType::settings_list) - .with_id(cv.get_id()) - .with_receiver(my_id) - .add_data(DataTypes::settings, settings_json); - - Self::send_message_static( - &writer.clone(), - is_connected, - response.to_json().to_string(), - ) - .await; - return; - } - } - Err(e) => { - log!("Omikron] Error: {}", e); - *is_connected.lock().await = false; - return; - } - _ => {} - } - } - - pub async fn send_message_static( - writer: &Arc< - Mutex + Send + Unpin>>>, - >, - connected: Arc>, - msg: String, - ) { - let mut guard = writer.lock().await; - - if let Some(writer) = guard.as_mut() { - if let Err(e) = writer.send(Message::Text(Utf8Bytes::from(msg))).await { + if let Err(e) = sender_clone.send(cv).await { log_t!("send_message_failed", e.to_string()); - *connected.lock().await = false; - return; - } - - if let Err(e) = writer.flush().await { - log_t!("send_message_failed", e.to_string()); - *connected.lock().await = false; } } else { - log_t!("send_message_failed", "Writer not initialized".to_string()); - *connected.lock().await = false; + log_t!("send_message_failed", "not connected".to_string()); } } + pub async fn is_connected(&self) -> bool { + self.state.read().await.is_connected() + } + + pub async fn is_identified(&self) -> bool { + self.state.read().await.is_identified() + } + pub async fn await_response( &self, cv: &CommunicationValue, @@ -724,17 +827,18 @@ impl OmikronConnection { let (tx, mut rx) = mpsc::channel(1); let msg_id = cv.get_id(); - let task_tx = tx.clone(); - self.waiting.insert( + WAITING_TASKS.insert( msg_id, - Box::new(move |response_cv| { - let inner_tx = task_tx.clone(); - tokio::spawn(async move { - if let Err(e) = inner_tx.send(response_cv).await { - log_t!("Failed to send response back to awaiter: {}", e.to_string()); - } - }); - }), + WaitingTask { + task: Box::new(move |_, response_cv| { + let inner_tx = tx.clone(); + tokio::spawn(async move { + let _ = inner_tx.send(response_cv).await; + }); + true + }), + inserted_at: Instant::now(), + }, ); self.send_message(&cv).await; @@ -743,14 +847,53 @@ impl OmikronConnection { match tokio::time::timeout(timeout, rx.recv()).await { Ok(Some(response_cv)) => Ok(response_cv), - Ok(_) => Err("Failed to receive response, channel was closed.".to_string()), + Ok(_) => Err("Channel closed".to_string()), Err(_) => { - self.waiting.remove(&msg_id); - Err(format!( - "Request timed out after {} seconds.", - timeout.as_secs() - )) + WAITING_TASKS.remove(&msg_id); + Err("Request timed out".to_string()) } } } + + pub async fn await_connection(&self, timeout_duration: Option) -> Result<(), String> { + if self.state.read().await.is_connected() { + return Ok(()); + } + + let timeout = timeout_duration.unwrap_or(CONNECTION_TIMEOUT); + let start = Instant::now(); + + loop { + if self.state.read().await.is_connected() { + return Ok(()); + } + + if start.elapsed() >= timeout { + return Err(format!( + "Connection not established within {} seconds", + timeout.as_secs() + )); + } + + sleep(Duration::from_millis(100)).await; + } + } +} + +// ============================================================================ +// Global Instance +// ============================================================================ + +pub static OMIKRON_CONNECTION: LazyLock> = LazyLock::new(|| { + let conn = Arc::new(OmikronConnection::new()); + + start_task_cleanup_loop(); + + conn +}); + +pub async fn get_omikron_connection() -> Arc { + let conn = OMIKRON_CONNECTION.clone(); + conn.connect().await; + conn } diff --git a/src/omikron/ping_pong_task.rs b/src/omikron/ping_pong_task.rs index c851c44..fde0623 100644 --- a/src/omikron/ping_pong_task.rs +++ b/src/omikron/ping_pong_task.rs @@ -1,47 +1,40 @@ use crate::APP_STATE; -use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::omikron::omikron_connection::OmikronConnection; -use json::number::Number; -use tokio::time::Instant; -use uuid::Uuid; +use dashmap::DashMap; +use epsilon_core::{CommunicationType, CommunicationValue, DataTypes, DataValue, rand_u32}; +use std::sync::LazyLock; +use std::time::Instant; +use tokio::time::Duration; + +// Dedicated lightweight ping tracking +static PING_TIMES: LazyLock> = LazyLock::new(|| DashMap::new()); impl OmikronConnection { pub async fn send_ping(&self) { - let uuid = Uuid::new_v4(); - let send_time = Instant::now(); + let id = rand_u32(); - self.message_send_times.lock().await.insert(uuid, send_time); - self.send_ping_message(uuid).await; - } + PING_TIMES.insert(id, Instant::now()); + + // Auto-cleanup old pings (optional) + PING_TIMES.retain(|_, v| v.elapsed() < Duration::from_secs(30)); - pub async fn send_ping_message(&self, uuid: Uuid) { let ping_message = CommunicationValue::new(CommunicationType::ping) - .with_id(uuid) - .add_data_num( + .with_id(id) + .add_data( DataTypes::last_ping, - Number::from(*self.last_ping.lock().await), + DataValue::Number(*self.last_ping.lock().await), ); self.send_message(&ping_message).await; } - /// Handles incoming pong and calculates latency - pub async fn handle_pong(&self, cv: &CommunicationValue, log: bool) { + pub async fn handle_pong(&self, cv: &CommunicationValue) { let id = cv.get_id(); - let send_time_opt = { - let queue = self.message_send_times.lock().await; - queue.get(&id).cloned() - }; - if let Some(send_time) = send_time_opt { - let ping = Instant::now().duration_since(send_time).as_millis() as i64; - self.message_send_times.lock().await.remove(&id); - - *self.last_ping.lock().await = ping as i64; - - if log { - APP_STATE.lock().unwrap().push_ping_val(ping as f64); - } + if let Some((_, send_time)) = PING_TIMES.remove(&id) { + let ping_ms = Instant::now().duration_since(send_time).as_millis() as i64; + *self.last_ping.lock().await = ping_ms; + APP_STATE.lock().unwrap().push_ping_val(ping_ms as f64); } } } diff --git a/src/server/mod.rs b/src/server/mod.rs index 003deea..de2a79a 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,4 +1,3 @@ pub mod api; pub mod server; -pub mod socket; pub mod web_path_parser; diff --git a/src/server/server.rs b/src/server/server.rs index b74facf..b55a50f 100644 --- a/src/server/server.rs +++ b/src/server/server.rs @@ -1,6 +1,5 @@ use crate::log; use crate::server::api::api_config; -use crate::server::socket::WsSession; use crate::server::web_path_parser; use crate::util::file_util::load_file_buf; use crate::{ACTIVE_TASKS, SHUTDOWN}; diff --git a/src/server/socket.rs b/src/server/socket.rs deleted file mode 100644 index 79a4e4d..0000000 --- a/src/server/socket.rs +++ /dev/null @@ -1,97 +0,0 @@ -use crate::{ - data::communication::{CommunicationType, CommunicationValue}, - log, -}; -use actix::{Actor, ActorContext, AsyncContext, StreamHandler}; -use actix_web_actors::ws; -use std::time::{Duration, Instant}; - -const IDLE_TIMEOUT: Duration = Duration::from_secs(30); - -use actix::Message; - -#[derive(Message)] -#[rtype(result = "()")] -pub struct WsSendMessage(pub String); - -impl actix::Handler for WsSession { - type Result = (); - - fn handle(&mut self, msg: WsSendMessage, ctx: &mut Self::Context) { - ctx.text(msg.0); - } -} - -pub struct WsSession { - path: String, - last_heartbeat: Instant, -} - -impl WsSession { - pub fn new(path: String) -> Self { - Self { - path, - last_heartbeat: Instant::now(), - } - } - fn start_heartbeat(&self, ctx: &mut ws::WebsocketContext) { - ctx.run_interval(Duration::from_secs(5), |act, ctx| { - if Instant::now().duration_since(act.last_heartbeat) > IDLE_TIMEOUT { - ctx.close(None); - ctx.stop(); - return; - } - - let ping = CommunicationValue::new(CommunicationType::ping) - .to_json() - .to_string(); - - ctx.text(ping); - }); - } -} - -impl Actor for WsSession { - type Context = ws::WebsocketContext; - - fn started(&mut self, ctx: &mut Self::Context) { - self.start_heartbeat(ctx); - - log!("WebSocket session started for path: {}", self.path); - - if self.path.starts_with("/ws/users/") { - log!("UserConnection handling is not yet implemented."); - } else if self.path.starts_with("/ws/community/") { - let community_id = self.path.split('/').nth(3).unwrap_or_default(); - log!( - "CommunityConnection handling for {} is not yet implemented.", - community_id - ); - } - } - - fn stopped(&mut self, _ctx: &mut Self::Context) { - log!("WebSocket session stopped for path: {}", self.path); - } -} - -impl StreamHandler> for WsSession { - fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { - match msg { - Ok(ws::Message::Ping(msg)) => { - self.last_heartbeat = Instant::now(); - ctx.pong(&msg); - } - Ok(ws::Message::Pong(_)) => self.last_heartbeat = Instant::now(), - Ok(ws::Message::Text(_)) => self.last_heartbeat = Instant::now(), - Ok(ws::Message::Close(reason)) => { - ctx.close(reason); - ctx.stop(); - } - Err(_) => { - ctx.stop(); - } - _ => ctx.stop(), - } - } -} diff --git a/src/users/user_manager.rs b/src/users/user_manager.rs index 95da132..58e78b1 100644 --- a/src/users/user_manager.rs +++ b/src/users/user_manager.rs @@ -1,5 +1,4 @@ -use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; -use crate::omikron::omikron_connection::{OMIKRON_CONNECTION, OmikronConnection}; +use crate::omikron::omikron_connection::OMIKRON_CONNECTION; use crate::users::user_profile::UserProfile; use crate::util::crypto_helper::{self, public_key_to_base64}; use crate::util::file_util::{load_file, save_file}; @@ -7,16 +6,16 @@ use crate::util::logger::PrintType; use crate::{RELOAD, SHUTDOWN}; use crate::{log, log_cv}; use base64::{Engine as _, engine::general_purpose::STANDARD}; +use epsilon_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; use hex::{self}; use json::JsonValue; -use json::number::Number; use once_cell::sync::Lazy; use rand::Rng; use rand_core::OsRng; use rand_core::RngCore; use sha2::{Digest, Sha256}; use std::io::{self}; -use std::sync::{Arc, Mutex}; +use std::sync::Mutex; use std::time::Duration; use x448::{PublicKey, Secret}; @@ -52,15 +51,7 @@ pub async fn load_from_tu(username: &str) -> Result<(), ()> { pub async fn create_user(username: &str) -> (Option, Option) { let register_cv = CommunicationValue::new(CommunicationType::get_register); - let conn = { - let guard = OMIKRON_CONNECTION.read().await; - guard.as_ref().cloned() - }; - - let conn = match conn { - Some(c) => c, - None => return (None, None), - }; + let conn = OMIKRON_CONNECTION.clone(); let response_cv = match conn .await_response(®ister_cv, Some(Duration::from_secs(20))) @@ -71,11 +62,7 @@ pub async fn create_user(username: &str) -> (Option, Option }; log_cv!(PrintType::Omega, response_cv); - let user_id = match response_cv - .get_data(DataTypes::user_id) - .unwrap_or(&JsonValue::Null) - .as_i64() - { + let user_id = match response_cv.get_data(DataTypes::user_id).as_number() { Some(id) => id, None => return (None, None), }; @@ -104,24 +91,14 @@ pub async fn create_user(username: &str) -> (Option, Option ); let cv = CommunicationValue::new(CommunicationType::complete_register_user) - .add_data(DataTypes::user_id, JsonValue::Number(Number::from(user_id))) - .add_data(DataTypes::username, JsonValue::String(username.to_string())) + .add_data(DataTypes::user_id, DataValue::Number(user_id)) + .add_data(DataTypes::username, DataValue::Str(username.to_string())) .add_data( DataTypes::public_key, - JsonValue::String(public_key_to_base64(&public_key)), + DataValue::Str(public_key_to_base64(&public_key)), ) - .add_data(DataTypes::iota_id, JsonValue::Number(Number::from(user_id))) - .add_data(DataTypes::reset_token, JsonValue::String(reset_token)); - - let conn = { - let guard = OMIKRON_CONNECTION.read().await; - guard.as_ref().cloned() - }; - - let conn = match conn { - Some(c) => c, - None => return (None, None), - }; + .add_data(DataTypes::iota_id, DataValue::Number(user_id)) + .add_data(DataTypes::reset_token, DataValue::Str(reset_token)); let response_cv = conn .await_response(&cv, Some(Duration::from_secs(20))) diff --git a/src/util/logger.rs b/src/util/logger.rs old mode 100644 new mode 100755 index c6a57c2..5e228a4 --- a/src/util/logger.rs +++ b/src/util/logger.rs @@ -1,4 +1,5 @@ use std::{ + collections::BTreeMap, fs::{self, OpenOptions}, io::Write, path::Path, @@ -7,6 +8,7 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; +use epsilon_core::{CommunicationValue, DataTypes, DataValue}; use ratatui::style::Color; use crate::{ @@ -156,82 +158,6 @@ pub fn log_internal(kind: PrintType, prefix: String, is_error: bool, message: St } } -use crate::data::communication::CommunicationValue; -use json::JsonValue; -pub fn log_cv_internal(prefix: String, cv: &CommunicationValue, print_type: Option) { - let formatted = format_cv(cv); - - log_internal( - print_type.unwrap_or(PrintType::General), - prefix, - false, - formatted, - ); -} - -pub fn format_cv(cv: &CommunicationValue) -> String { - let mut parts = Vec::new(); - - let sender = cv.get_sender(); - let receiver = cv.get_receiver(); - - if sender > 0 && receiver > 0 { - parts.push(format!("{} > {}", sender, receiver)); - } else if sender > 0 { - parts.push(format!("{}", sender)); - } else if receiver > 0 { - parts.push(format!("> {}", receiver)); - } - - let comm_type = cv.get_type().to_string(); - parts.push(format!("{}", comm_type)); - - let mut data_parts = Vec::new(); - if let JsonValue::Object(data) = &cv.clone().to_json()["data"] { - for (key, value) in data.iter() { - let val_string = match value { - JsonValue::String(s) => s.clone(), - _ => value.dump(), - }; - - data_parts.push(format!("{} {}", key, val_string)); - } - } - - if !data_parts.is_empty() { - parts.push(format!("{}", data_parts.join(", "))); - } - - parts.join(": ") -} -#[macro_export] -macro_rules! log_cv { - ($kind:expr, $cv:expr) => { - $crate::util::logger::log_cv_internal("".to_string(), &$cv, Some($kind)) - }; - ($cv:expr) => { - $crate::util::logger::log_cv_internal("".to_string(), &$cv, None) - }; -} -#[macro_export] -macro_rules! log_cv_in { - ($kind:expr, $cv:expr) => { - $crate::util::logger::log_cv_internal("> ".to_string(), &$cv, Some($kind)) - }; - ($cv:expr) => { - $crate::util::logger::log_cv_internal("> ".to_string(), &$cv, None) - }; -} -#[macro_export] -macro_rules! log_cv_out { - ($kind:expr, $cv:expr) => { - $crate::util::logger::log_cv_internal("< ".to_string(), &$cv, Some($kind)) - }; - ($cv:expr) => { - $crate::util::logger::log_cv_internal("< ".to_string(), &$cv, None) - }; -} - #[macro_export] macro_rules! log_t { ($key:expr) => { @@ -320,3 +246,139 @@ macro_rules! log_err { ) }; } + +// ******** COMMUNICATION VALUES ******** +pub fn log_cv_internal( + prefix: &'static str, + cv: &CommunicationValue, + print_type: Option, +) { + let formatted = format_cv(cv); + + log_internal( + print_type.unwrap_or(PrintType::General), + prefix.to_string(), + false, + formatted, + ); +} + +pub fn format_cv(cv: &CommunicationValue) -> String { + let mut parts = Vec::new(); + + let sender = cv.get_sender(); + let receiver = cv.get_receiver(); + + if sender > 0 && receiver > 0 { + parts.push(format!("{} > {}", sender, receiver)); + } else if sender > 0 { + parts.push(format!("{}", sender)); + } else if receiver > 0 { + parts.push(format!("> {}", receiver)); + } + + let comm_type = cv.get_type().to_string(); + parts.push(format!("{}", comm_type)); + + let data: &BTreeMap = cv.get_data_container(); + + let formated_data = + format_data_container(data.iter().map(|(k, v)| (k.clone(), v.clone())).collect()); + + parts.push(format!("{}", formated_data)); + + parts.join(": ") +} + +fn format_data_container(data: Vec<(DataTypes, DataValue)>) -> String { + let parts: Vec = data + .into_iter() + .map(|(key, value)| { + let key_str = key.to_string(); + + match value { + DataValue::Str(s) => format!("{}=\"{}\"", key_str, s), + + DataValue::Container(inner) => { + let inner_formatted = format_data_container(inner); + format!("{}={{ {} }}", key_str, inner_formatted) + } + + DataValue::Array(arr) => { + let arr_formatted = format_array(arr); + format!("{}=[{}]", key_str, arr_formatted) + } + + DataValue::Bool(b) => format!("{}={}", key_str, b), + + DataValue::BoolTrue => format!("{}=true", key_str), + DataValue::BoolFalse => format!("{}=false", key_str), + + DataValue::Number(num) => format!("{}={}", key_str, num), + + _ => "".to_string(), + } + }) + .collect(); + + parts.join(", ") +} + +fn format_array(arr: Vec) -> String { + let parts: Vec = arr + .into_iter() + .map(|value| match value { + DataValue::Str(s) => format!("\"{}\"", s), + + DataValue::Container(inner) => { + let inner_formatted = format_data_container(inner); + format!("{{ {} }}", inner_formatted) + } + + DataValue::Array(inner_arr) => { + let formatted = format_array(inner_arr); + format!("[{}]", formatted) + } + + DataValue::Bool(b) => b.to_string(), + + DataValue::BoolTrue => "true".to_string(), + DataValue::BoolFalse => "false".to_string(), + + DataValue::Number(num) => num.to_string(), + + _ => String::new(), + }) + .collect(); + + parts.join(", ") +} + +#[macro_export] +macro_rules! log_cv { + ($kind:expr, $cv:expr) => { + $crate::util::logger::log_cv_internal("", &$cv, Some($kind)) + }; + ($cv:expr) => { + $crate::util::logger::log_cv_internal("", &$cv, None) + }; +} + +#[macro_export] +macro_rules! log_cv_in { + ($kind:expr, $cv:expr) => { + $crate::util::logger::log_cv_internal("> ", &$cv, Some($kind)) + }; + ($cv:expr) => { + $crate::util::logger::log_cv_internal("> ", &$cv, None) + }; +} +#[macro_export] +macro_rules! log_cv_out { + ($kind:expr, $cv:expr) => { + $crate::util::logger::log_cv_internal("< ", &$cv, Some($kind)) + }; + ($cv:expr) => { + $crate::util::logger::log_cv_internal("< ", &$cv, None) + }; +}