From 86cb583cf21a834bb99613df72e3eb7e3e22c24a Mon Sep 17 00:00:00 2001 From: Alois Date: Thu, 2 Apr 2026 22:28:07 +0200 Subject: [PATCH] Nuke repo --- .gitignore | 19 - Cargo.lock | 3910 ----------------- Cargo.toml | 37 - LICENSE | 16 - README.md | 1 - .../anonymous_client_connection.rs | 519 --- src/anonymous_clients/anonymous_manager.rs | 53 - src/anonymous_clients/mod.rs | 2 - src/calls/call_group.rs | 106 - src/calls/call_manager.rs | 97 - src/calls/call_util.rs | 151 - src/calls/caller.rs | 49 - src/calls/mod.rs | 4 - src/data/mod.rs | 1 - src/data/user.rs | 30 - src/main.rs | 51 - src/omega/mod.rs | 1 - src/omega/omega_connection.rs | 741 ---- src/omega/ping_pong_task.rs | 41 - src/rho/client_connection.rs | 583 --- src/rho/connection.rs | 358 -- src/rho/iota_connection.rs | 461 -- src/rho/mod.rs | 6 - src/rho/rho_connection.rs | 199 - src/rho/rho_manager.rs | 83 - src/rho/server.rs | 25 - src/util/crypto_helper.rs | 149 - src/util/crypto_util.rs | 178 - src/util/file_util.rs | 185 - src/util/logger.rs | 280 -- src/util/mod.rs | 4 - 31 files changed, 8340 deletions(-) delete mode 100644 .gitignore delete mode 100644 Cargo.lock delete mode 100644 Cargo.toml delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 src/anonymous_clients/anonymous_client_connection.rs delete mode 100644 src/anonymous_clients/anonymous_manager.rs delete mode 100644 src/anonymous_clients/mod.rs delete mode 100644 src/calls/call_group.rs delete mode 100644 src/calls/call_manager.rs delete mode 100644 src/calls/call_util.rs delete mode 100644 src/calls/caller.rs delete mode 100644 src/calls/mod.rs delete mode 100644 src/data/mod.rs delete mode 100644 src/data/user.rs delete mode 100644 src/main.rs delete mode 100644 src/omega/mod.rs delete mode 100644 src/omega/omega_connection.rs delete mode 100644 src/omega/ping_pong_task.rs delete mode 100644 src/rho/client_connection.rs delete mode 100755 src/rho/connection.rs delete mode 100755 src/rho/iota_connection.rs delete mode 100644 src/rho/mod.rs delete mode 100644 src/rho/rho_connection.rs delete mode 100644 src/rho/rho_manager.rs delete mode 100644 src/rho/server.rs delete mode 100755 src/util/crypto_helper.rs delete mode 100644 src/util/crypto_util.rs delete mode 100644 src/util/file_util.rs delete mode 100644 src/util/logger.rs delete mode 100644 src/util/mod.rs diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 1baef92..0000000 --- a/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -debug -target - -# These are backup files generated by rustfmt -**/*.rs.bk - -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb -*.env -# Generated by cargo mutants -# Contains mutation testing data -**/mutants.out*/W - - -# Added by cargo -/target -/logs diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 41cef35..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,3910 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "Omikron" -version = "0.1.0" -dependencies = [ - "aes-gcm", - "ansi_term", - "base64 0.22.1", - "dashmap", - "dotenv", - "futures", - "hex", - "hkdf", - "livekit-api", - "livekit-protocol", - "log", - "once_cell", - "rand 0.8.5", - "rand_core 0.6.4", - "rustls", - "sha2", - "strum", - "strum_macros", - "thiserror 2.0.18", - "tokio", - "ttp-core", - "ttp-native", - "uuid", - "x448", -] - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common", - "generic-array", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[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", - "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", -] - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.5.0", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" -dependencies = [ - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "windows-sys 0.61.2", -] - -[[package]] -name = "async-lock" -version = "3.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" -dependencies = [ - "event-listener 5.4.1", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-native-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9343dc5acf07e79ff82d0c37899f079db3534d99f189a1837c8e549c99405bec" -dependencies = [ - "futures-util", - "native-tls", - "thiserror 1.0.69", - "url", -] - -[[package]] -name = "async-std" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-tungstenite" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cca750b12e02c389c1694d35c16539f88b8bbaa5945934fdc1b41a776688589" -dependencies = [ - "async-native-tls", - "async-std", - "futures-io", - "futures-util", - "log", - "pin-project-lite", - "tungstenite 0.21.0", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "aws-lc-rs" -version = "1.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a054912289d18629dc78375ba2c3726a3afe3ff71b4edba9dedfca0e3446d1fc" -dependencies = [ - "aws-lc-sys", - "untrusted 0.7.1", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.39.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[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 = "bitflags" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" -dependencies = [ - "objc2", -] - -[[package]] -name = "blocking" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" -dependencies = [ - "async-channel 2.5.0", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "bumpalo" -version = "3.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - -[[package]] -name = "cc" -version = "1.2.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chrono" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" -dependencies = [ - "num-traits", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest", - "fiat-crypto 0.2.9", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dashmap" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "data-encoding" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "der-parser" -version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" -dependencies = [ - "asn1-rs", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - -[[package]] -name = "deranged" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dispatch2" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" -dependencies = [ - "bitflags", - "objc2", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" -dependencies = [ - "curve25519-dalek", - "ed25519", - "serde", - "sha2", - "subtle", - "zeroize", -] - -[[package]] -name = "ed448-goldilocks" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87b5fa9e9e3dd5fe1369f380acd3dcdfa766dbd0a1cd5b048fb40e38a6a78e79" -dependencies = [ - "fiat-crypto 0.1.20", - "hex", - "subtle", -] - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest", - "ff", - "generic-array", - "group", - "hkdf", - "pem-rfc7468", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener 5.4.1", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "ff" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "futures" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - -[[package]] -name = "futures-executor" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" - -[[package]] -name = "futures-lite" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" - -[[package]] -name = "futures-task" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - -[[package]] -name = "futures-util" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi 5.3.0", - "wasip2", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", - "wasip2", - "wasip3", -] - -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.4.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http 1.4.0", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "hyper" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http 1.4.0", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-util", - "http 1.4.0", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2 0.6.3", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" -dependencies = [ - "equivalent", - "hashbrown 0.16.1", - "serde", - "serde_core", -] - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array", -] - -[[package]] -name = "ipnet" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" - -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" -dependencies = [ - "cfg-if", - "futures-util", - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "jsonwebtoken" -version = "10.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" -dependencies = [ - "base64 0.22.1", - "ed25519-dalek", - "getrandom 0.2.17", - "hmac", - "js-sys", - "p256", - "p384", - "rand 0.8.5", - "rsa", - "serde", - "serde_json", - "sha2", - "signature", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - -[[package]] -name = "libc" -version = "0.2.184" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" - -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - -[[package]] -name = "linux-raw-sys" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" - -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - -[[package]] -name = "livekit-api" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020c7eaab7cec16b69a058659f9acff32067e0e2d4f81e80639f3ffa29464b09" -dependencies = [ - "async-tungstenite", - "base64 0.21.7", - "http 1.4.0", - "jsonwebtoken", - "livekit-protocol", - "log", - "os_info", - "parking_lot", - "pbjson-types", - "prost", - "rand 0.9.2", - "reqwest", - "scopeguard", - "serde", - "serde_json", - "sha2", - "thiserror 1.0.69", - "tokio-tungstenite", - "url", -] - -[[package]] -name = "livekit-protocol" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c21d56b4dc2598b1296ca891abb225bf1c05ea007d6f43bc4fd48c31be64bf59" -dependencies = [ - "futures-util", - "livekit-runtime", - "parking_lot", - "pbjson", - "pbjson-types", - "prost", - "serde", - "thiserror 1.0.69", - "tokio", -] - -[[package]] -name = "livekit-runtime" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532e84c6cdc5fe774f2b5d9912597b5f3bea561927a48296d03e24549d21c3f6" -dependencies = [ - "tokio", - "tokio-stream", -] - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" -dependencies = [ - "value-bag", -] - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "mio" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "multimap" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" - -[[package]] -name = "native-tls" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags", - "cfg-if", - "cfg_aliases", - "libc", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[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-bigint-dig" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" -dependencies = [ - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - -[[package]] -name = "num-conv" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", - "libm", -] - -[[package]] -name = "objc2" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" -dependencies = [ - "objc2-encode", -] - -[[package]] -name = "objc2-cloud-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" -dependencies = [ - "bitflags", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-data" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" -dependencies = [ - "bitflags", - "dispatch2", - "objc2", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" -dependencies = [ - "bitflags", - "dispatch2", - "objc2", - "objc2-core-foundation", - "objc2-io-surface", -] - -[[package]] -name = "objc2-core-image" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-location" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-text" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" -dependencies = [ - "bitflags", - "objc2", - "objc2-core-foundation", - "objc2-core-graphics", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" -dependencies = [ - "bitflags", - "block2", - "libc", - "objc2", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" -dependencies = [ - "bitflags", - "objc2", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" -dependencies = [ - "bitflags", - "objc2", - "objc2-core-foundation", - "objc2-foundation", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" -dependencies = [ - "bitflags", - "block2", - "objc2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-core-image", - "objc2-core-location", - "objc2-core-text", - "objc2-foundation", - "objc2-quartz-core", - "objc2-user-notifications", -] - -[[package]] -name = "objc2-user-notifications" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" -dependencies = [ - "objc2", - "objc2-foundation", -] - -[[package]] -name = "octets" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8311fa8ab7a57759b4ff1f851a3048d9ef0effaa0130726426b742d26d8a88e7" - -[[package]] -name = "oid-registry" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" -dependencies = [ - "asn1-rs", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "openssl" -version = "0.10.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "openssl-sys" -version = "0.9.112" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d55af3b3e226502be1526dfdba67ab0e9c96fc293004e79576b2b9edb0dbdb" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "os_info" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224" -dependencies = [ - "android_system_properties", - "log", - "nix", - "objc2", - "objc2-foundation", - "objc2-ui-kit", - "serde", - "windows-sys 0.61.2", -] - -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - -[[package]] -name = "p384" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pbjson" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1030c719b0ec2a2d25a5df729d6cff1acf3cc230bf766f4f97833591f7577b90" -dependencies = [ - "base64 0.21.7", - "serde", -] - -[[package]] -name = "pbjson-build" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" -dependencies = [ - "heck 0.4.1", - "itertools 0.11.0", - "prost", - "prost-types", -] - -[[package]] -name = "pbjson-types" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18f596653ba4ac51bdecbb4ef6773bc7f56042dc13927910de1684ad3d32aa12" -dependencies = [ - "bytes", - "chrono", - "pbjson", - "pbjson-build", - "prost", - "prost-build", - "serde", -] - -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64 0.22.1", - "serde_core", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "petgraph" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "polling" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" -dependencies = [ - "bytes", - "heck 0.5.0", - "itertools 0.12.1", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn", - "tempfile", -] - -[[package]] -name = "prost-derive" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" -dependencies = [ - "anyhow", - "itertools 0.12.1", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "prost-types" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" -dependencies = [ - "prost", -] - -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -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.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" -dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "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", -] - -[[package]] -name = "r-efi" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rcgen" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e" -dependencies = [ - "aws-lc-rs", - "rustls-pki-types", - "time", - "x509-parser 0.18.1", - "yasna", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" - -[[package]] -name = "reqwest" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "http 1.4.0", - "http-body", - "http-body-util", - "hyper", - "hyper-tls", - "hyper-util", - "js-sys", - "log", - "native-tls", - "percent-encoding", - "pin-project-lite", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "rsa" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustc-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rusticata-macros" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" -dependencies = [ - "nom", -] - -[[package]] -name = "rustix" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -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-pki-types" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted 0.9.0", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - -[[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" -dependencies = [ - "errno", - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest", - "rand_core 0.6.4", -] - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "socket2" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "strum" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" - -[[package]] -name = "strum_macros" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tempfile" -version = "3.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" -dependencies = [ - "fastrand", - "getrandom 0.4.2", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" -dependencies = [ - "thiserror-impl 2.0.18", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" - -[[package]] -name = "time-macros" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -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", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.6.3", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" -dependencies = [ - "futures-util", - "log", - "native-tls", - "tokio", - "tokio-native-tls", - "tungstenite 0.20.1", -] - -[[package]] -name = "tower" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "bitflags", - "bytes", - "futures-util", - "http 1.4.0", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "ttp-core" -version = "0.1.0" -source = "git+https://github.com/Tensamin/TTP.git#e246d1af6a42c71514d0ccc06fef94d71e4ad167" -dependencies = [ - "base64 0.22.1", - "byteorder", - "rand 0.8.5", - "strum", - "strum_macros", -] - -[[package]] -name = "ttp-native" -version = "0.1.0" -source = "git+https://github.com/Tensamin/TTP.git#e246d1af6a42c71514d0ccc06fef94d71e4ad167" -dependencies = [ - "quinn", - "rustls", - "rustls-native-certs", - "thiserror 2.0.18", - "tokio", - "ttp-core", - "wtransport", -] - -[[package]] -name = "tungstenite" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 0.2.12", - "httparse", - "log", - "native-tls", - "rand 0.8.5", - "sha1", - "thiserror 1.0.69", - "url", - "utf-8", -] - -[[package]] -name = "tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 1.4.0", - "httparse", - "log", - "native-tls", - "rand 0.8.5", - "sha1", - "thiserror 1.0.69", - "url", - "utf-8", -] - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" -dependencies = [ - "getrandom 0.4.2", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "value-bag" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - -[[package]] -name = "web-sys" -version = "0.3.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" -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 = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck 0.5.0", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck 0.5.0", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "wtransport" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56b611f195638f3790e4e5a41e9d777643a6c324ae4ffd1f0f53f2738e7678c" -dependencies = [ - "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]] -name = "x448" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd07d4fae29e07089dbcacf7077cd52dce7760125ca9a4dd5a35ca603ffebb" -dependencies = [ - "ed448-goldilocks", - "hex", - "rand_core 0.5.1", -] - -[[package]] -name = "x509-parser" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569f339c0c402346d4a75a9e39cf8dad310e287eef1ff56d4c68e5067f53460" -dependencies = [ - "asn1-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "rusticata-macros", - "thiserror 2.0.18", - "time", -] - -[[package]] -name = "x509-parser" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" -dependencies = [ - "asn1-rs", - "aws-lc-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "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]] -name = "yoke" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 3127b12..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "Omikron" -version = "0.1.0" -edition = "2024" - -[dependencies] -ttp-core = { git = "https://github.com/Tensamin/TTP.git", package = "ttp-core" } -ttp-native = { git = "https://github.com/Tensamin/TTP.git", package = "ttp-native" } - -ansi_term = "*" -uuid = { version = "*", features = ["v4"] } - -base64 = "0.22.1" -dashmap = "*" -futures = "*" -hex = "*" -once_cell = "1.21.3" -rand = "0.8" -rand_core = { version = "0.6", features = ["getrandom", "std"] } -rustls = { version = "0.23.37", default-features = false, features = [ - "std", - "tls12", - "aws-lc-rs", - "prefer-post-quantum", -] } -aes-gcm = "0.10.3" -sha2 = "0.10.9" -tokio = { version = "*", features = ["full"] } -x448 = { version = "*" } -log = "0.4" -dotenv = "0.15.0" -hkdf = "0.12.4" -strum = "0.28.0" -strum_macros = "0.28.0" -livekit-api = { version = "0.4.14", features = ["native-tls"] } -livekit-protocol = "0.7.1" -thiserror = "2.0.18" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d218eff..0000000 --- a/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -Copyright (c) [2025] [Methanium] -All rights reserved. - -This software is protected by copyright. Copying, editing, -distributing, publicly performing, or any other use of this software -or its components, in source or binary form, is strictly prohibited without the express -written permission of the copyright holder. - -FUTURE LICENSE ACCEPTANCE: -It is the copyright holder's intention to release this software in the future -under a license yet to be defined, which will, among other things, -allow private, non-commercial use. This statement does not constitute -a current license grant and does not alter the above -prohibition on use, copying, or modification. Until the formal -publication of such a future license, all rights remain -reserved. diff --git a/README.md b/README.md deleted file mode 100644 index 06c1cdb..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# ⚠️ Moved to [git.methanium.net](https://git.methanium.net/tensamin/omikron) ⚠️ diff --git a/src/anonymous_clients/anonymous_client_connection.rs b/src/anonymous_clients/anonymous_client_connection.rs deleted file mode 100644 index 8c57490..0000000 --- a/src/anonymous_clients/anonymous_client_connection.rs +++ /dev/null @@ -1,519 +0,0 @@ -use std::str::FromStr; -use std::sync::Arc; -use std::time::Duration; -use tokio::sync::RwLock; -use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; -use ttp_native::{Receiver, Sender}; -use uuid::Uuid; - -use crate::anonymous_clients::anonymous_manager::{self, generate_username}; -use crate::calls::call_manager; -use crate::omega::omega_connection::get_omega_connection; -use crate::rho::connection::GeneralConnection; -use crate::rho::rho_manager; -use crate::util::logger::PrintType; -use crate::{log_cv_in, log_cv_out, log_out}; - -pub struct AnonymousClientConnection { - user_id: u64, - - pub sender: Arc, - pub receiver: Arc, - pub ping: Arc>, - pub interested_users: Arc>>, - is_open: Arc>, - pub user_name: Arc>, - pub display_name: Arc>, - pub avatar: Arc>, -} - -impl AnonymousClientConnection { - pub async fn from_general(general: Arc, user_id: u64) -> Arc { - let username: String = generate_username(); - Arc::new(Self { - user_id: user_id, - - ping: Arc::new(RwLock::new(0)), - interested_users: Arc::new(RwLock::new(Vec::new())), - is_open: Arc::new(RwLock::new(true)), - sender: general.sender.clone(), - receiver: general.receiver.clone(), - user_name: Arc::new(RwLock::new(username.to_lowercase())), - display_name: Arc::new(RwLock::new(username)), - avatar: Arc::new(RwLock::new(String::new())), - }) - } - pub fn start(self: Arc) { - let self_clone = self.clone(); - tokio::spawn(async move { - while let Ok(cv) = self_clone.receiver.receive().await { - self_clone.clone().handle_message(cv).await; - } - self_clone.handle_close().await; - }); - } - - /// Get the user ID - pub fn get_user_id(&self) -> u64 { - self.user_id - } - - /// Get the user name - pub async fn get_user_name(&self) -> String { - self.user_name.read().await.clone() - } - - /// Get the display name - pub async fn get_display_name(&self) -> String { - self.display_name.read().await.clone() - } - - pub async fn set_display_name(&self, display: String) { - *self.display_name.write().await = display; - } - - /// Get the avatar - pub async fn get_avatar(&self) -> String { - self.avatar.read().await.clone() - } - - /// Send a CommunicationValue to the client - pub async fn send_message(self: Arc, cv: &CommunicationValue) { - if !*self.is_open.read().await { - log_out!( - self.user_id as i64, - PrintType::Client, - "Attempted to send message to a closed connection." - ); - return; - } - if !cv.is_type(CommunicationType::pong) { - log_cv_out!(PrintType::Client, &cv); - } - if let Err(e) = self.sender.send(&cv).await { - log_out!( - self.user_id as i64, - PrintType::Client, - "Send failed: {:?}", - e - ); - } - } - - /// Handle incoming message from client - pub async fn handle_message(self: Arc, cv: CommunicationValue) { - tokio::spawn(async move { - if cv.is_type(CommunicationType::ping) { - self.handle_ping(cv).await; - return; - } - log_cv_in!(PrintType::Client, &cv); - - if cv.is_type(CommunicationType::identification) { - let call_id = - Uuid::parse_str(cv.get_data(DataTypes::call_id).as_str().unwrap_or("")) - .unwrap_or(Uuid::new_v4()); - - let call = if let Some(call) = call_manager::get_call(call_id).await { - if call.is_anonymous().await { - call - } else { - self.send_error_response( - &cv.get_id(), - CommunicationType::error_not_authenticated, - ) - .await; - return; - } - } else { - self.send_error_response( - &cv.get_id(), - CommunicationType::error_not_authenticated, - ) - .await; - return; - }; - - let mut invited = Vec::new(); - for call_invitee in call.members.read().await.clone() { - let call_invitee_cv = get_omega_connection() - .await_response( - &CommunicationValue::new(CommunicationType::get_user_data).add_data( - DataTypes::user_id, - DataValue::Number(call_invitee.user_id as i64), - ), - Some(Duration::from_secs(2)), - ) - .await - .unwrap(); - let mut json_invitee = Vec::new(); - let _ = json_invitee.push(( - DataTypes::user_id, - call_invitee_cv.get_data(DataTypes::user_id).clone(), - )); - let _ = json_invitee.push(( - DataTypes::username, - call_invitee_cv.get_data(DataTypes::username).clone(), - )); - let _ = json_invitee.push(( - DataTypes::display, - call_invitee_cv.get_data(DataTypes::display).clone(), - )); - let _ = json_invitee.push(( - DataTypes::avatar, - call_invitee_cv.get_data(DataTypes::avatar).clone(), - )); - - let _ = invited.push(DataValue::Container(json_invitee)); - } - - let token = call.create_anonymous_token(self.get_user_id()).await; - - let mut serialized = Vec::new(); - let _ = serialized.push((DataTypes::call_id, DataValue::Str(call_id.to_string()))); - let _ = - serialized.push((DataTypes::call_invited, DataValue::Array(invited.clone()))); - let _ = serialized.push((DataTypes::call_members, DataValue::Array(invited))); - let _ = serialized.push((DataTypes::call_token, DataValue::Str(token.unwrap()))); - self.clone() - .send_message( - &&CommunicationValue::new(CommunicationType::identification_response) - .with_id(cv.get_id()) - .add_data(DataTypes::user_id, DataValue::Number(self.user_id as i64)) - .add_data( - DataTypes::username, - DataValue::Str(self.clone().get_user_name().await), - ) - .add_data( - DataTypes::display, - DataValue::Str(self.get_display_name().await), - ) - .add_data(DataTypes::avatar, DataValue::Str(self.get_avatar().await)) - .add_data(DataTypes::call_state, DataValue::Container(serialized)), - ) - .await; - } - - // Handle ping - if cv.is_type(CommunicationType::ping) { - self.handle_ping(cv).await; - return; - } - // Handle client status changes - if cv.is_type(CommunicationType::client_changed) { - self.handle_client_changed(cv).await; - return; - } - - // Handle call invites - if cv.is_type(CommunicationType::call_invite) { - self.handle_call_invite(cv).await; - return; - } - - // Handle get call requests - if cv.is_type(CommunicationType::call_token) { - self.handle_get_call(cv).await; - return; - } - - if cv.is_type(CommunicationType::call_disconnect_user) { - self.handle_call_disconnect_user(cv).await; - return; - } - - if cv.is_type(CommunicationType::call_timeout_user) { - self.handle_call_timeout_user(cv).await; - return; - } - - if cv.is_type(CommunicationType::change_user_data) { - if let Some(display_name) = cv.get_data(DataTypes::display).as_str() { - let _ = self.set_display_name(display_name.to_string()).await; - } - - return; - } - - if cv.is_type(CommunicationType::get_user_data) { - if let Some(anonymous) = { - if let Some(user_id) = cv.get_data(DataTypes::user_id).as_number() { - anonymous_manager::get_anonymous_user(user_id as u64).await - } else if let Some(username) = cv.get_data(DataTypes::username).as_str() { - anonymous_manager::get_anonymous_user_by_name(username.to_string()).await - } else { - None - } - } { - let response = CommunicationValue::new(CommunicationType::get_user_data) - .with_id(cv.get_id()) - .add_data( - DataTypes::username, - DataValue::Str(anonymous.get_user_name().await), - ) - .add_data( - DataTypes::user_id, - DataValue::Number(anonymous.user_id as i64), - ) - .add_data( - DataTypes::display, - DataValue::Str(anonymous.get_display_name().await), - ) - .add_data(DataTypes::user_state, DataValue::Str("online".to_string())) - .add_data( - DataTypes::avatar, - DataValue::Str(anonymous.get_avatar().await), - ); - - self.send_message(&response).await; - - return; - } - } - - if cv.is_type(CommunicationType::get_user_data) - || cv.is_type(CommunicationType::get_iota_data) - || cv.is_type(CommunicationType::delete_user) - { - self.handle_omega_forward(cv).await; - return; - } - }); - } - async fn handle_omega_forward(self: Arc, cv: CommunicationValue) { - let client_for_closure = self.clone(); - tokio::spawn(async move { - let response_cv = get_omega_connection() - .await_response(&cv.with_sender(self.user_id), Some(Duration::from_secs(20))) - .await; - if let Ok(response_cv) = response_cv { - client_for_closure.send_message(&response_cv).await; - } - }); - } - - /// Handle ping message - async fn handle_ping(self: Arc, cv: CommunicationValue) { - // Update our ping if provided - if let DataValue::Number(last_ping) = cv.get_data(DataTypes::last_ping) { - if let Ok(ping_val) = last_ping.to_string().parse::() { - let mut ping_guard = self.ping.write().await; - *ping_guard = ping_val; - } - } - - // Send pong response - let response = CommunicationValue::new(CommunicationType::pong).with_id(cv.get_id()); - - self.send_message(&response).await; - } - - /// Handle client status change - async fn handle_client_changed(self: Arc, _cv: CommunicationValue) { - /*let user_id = self.get_user_id().await; - if let Some(_status_str) = cv.get_data(DataTypes::user_state) { - let user_status = UserStatus::online; - }*/ - } - - /// Handle call invite - async fn handle_call_invite(self: Arc, cv: CommunicationValue) { - let receiver_id: i64 = cv.get_data(DataTypes::receiver_id).as_number().unwrap_or(0); - if receiver_id == 0 { - self.send_error_response(&cv.get_id(), CommunicationType::error_no_user_id) - .await; - return; - } - - let call_id = match cv.get_data(DataTypes::call_id) { - DataValue::Str(id_str) => match Uuid::parse_str(&id_str.to_string()) { - Ok(id) => id, - Err(_) => { - self.send_error_response( - &cv.get_id(), - CommunicationType::error_invalid_call_id, - ) - .await; - return; - } - }, - _ => { - self.send_error_response(&cv.get_id(), CommunicationType::error_no_call_id) - .await; - return; - } - }; - - let invited = call_manager::add_invite(call_id, self.user_id, receiver_id as u64).await; - if !invited { - self.send_error_response(&cv.get_id(), CommunicationType::error_invalid_call_id) - .await; - return; - } - - // Find target RhoConnection - let target_rho = match rho_manager::get_rho_con_for_user(receiver_id).await { - Some(rho) => rho, - _ => { - self.send_error_response(&cv.get_id(), CommunicationType::error) - .await; - return; - } - }; - - // Get sender user ID - let sender_id = self.get_user_id(); - - // Create and send call distribution message - let forward = CommunicationValue::new(CommunicationType::call_invite) - .with_receiver(receiver_id as u64) - .with_sender(sender_id) - .add_data(DataTypes::call_id, DataValue::Str(call_id.to_string())) - .add_data( - DataTypes::receiver_id, - DataValue::Str(receiver_id.to_string()), - ) - .add_data(DataTypes::sender_id, DataValue::Str(sender_id.to_string())); - - target_rho.message_to_client(forward).await; - - let response = CommunicationValue::new(CommunicationType::success).with_id(cv.get_id()); - self.send_message(&response).await; - } - - /// Handle get call request - async fn handle_get_call(self: Arc, cv: CommunicationValue) { - let user_id = self.get_user_id(); - - let call_id = match cv.get_data(DataTypes::call_id) { - DataValue::Str(id_str) => match Uuid::parse_str(&id_str.to_string()) { - Ok(id) => id, - Err(_) => { - self.send_error_response(&cv.get_id(), CommunicationType::error) - .await; - return; - } - }, - _ => { - self.send_error_response(&cv.get_id(), CommunicationType::error) - .await; - return; - } - }; - - if let Some(token) = call_manager::get_call_token(user_id, call_id).await { - let response = CommunicationValue::new(CommunicationType::call_token) - .with_id(cv.get_id()) - .with_receiver(user_id) - .add_data(DataTypes::call_token, DataValue::Str(token.to_string())); - self.send_message(&response).await; - } else { - self.send_error_response(&cv.get_id(), CommunicationType::error) - .await; - return; - } - } - async fn handle_call_timeout_user(self: Arc, cv: CommunicationValue) { - let call_id = - Uuid::from_str(cv.get_data(DataTypes::call_id).as_str().unwrap_or("")).unwrap(); - let user_id = cv.get_data(DataTypes::user_id).as_number().unwrap_or(0); - let untill = cv.get_data(DataTypes::untill).as_number().unwrap_or(0); - - let call = call_manager::get_call(call_id).await; - if let Some(call) = call { - if call - .get_caller(self.get_user_id()) - .await - .unwrap() - .has_admin() - { - call.get_caller(user_id as u64) - .await - .unwrap() - .set_timeout(untill) - .await; - } - } - } - async fn handle_call_disconnect_user(self: Arc, cv: CommunicationValue) { - let call_id = - Uuid::from_str(cv.get_data(DataTypes::call_id).as_str().unwrap_or("")).unwrap(); - let user_id = cv.get_data(DataTypes::user_id).as_number().unwrap_or(0); - - let call = call_manager::get_call(call_id).await; - if let Some(call) = call { - if call - .get_caller(self.get_user_id()) - .await - .unwrap() - .has_admin() - { - call.remove_caller(user_id as u64).await; - } - } - } - - /// Send error response - async fn send_error_response(self: Arc, message_id: &u32, error_type: CommunicationType) { - let error = CommunicationValue::new(error_type).with_id(*message_id); - self.send_message(&error).await; - } - /// Close the connection - pub async fn close(&self) { - let mut is_open_guard = self.is_open.write().await; - if !*is_open_guard { - return; - } - *is_open_guard = false; - - let _ = self.sender.close(); - } - - #[allow(dead_code)] - /// Set interested users list - pub async fn set_interested_users(self: Arc, interested_ids: Vec) { - let mut interested_guard = self.interested_users.write().await; - *interested_guard = interested_ids; - } - #[allow(dead_code)] - pub async fn get_interested_users(self: Arc) -> Vec { - let interested_guard = self.interested_users.read().await; - interested_guard.clone() - } - - #[allow(dead_code)] - /// Check if interested in a user and send notification - pub async fn are_you_interested(self: Arc, user_id: i64) { - let interested_guard = self.clone().get_interested_users().await; - if interested_guard.contains(&user_id) { - let notification = CommunicationValue::new(CommunicationType::client_changed) - .add_data(DataTypes::user_id, DataValue::Str(user_id.to_string())) - .add_data(DataTypes::user_state, DataValue::Str("online".to_string())); - - self.send_message(¬ification).await; - } - } - - /// Handle connection close - pub async fn handle_close(&self) { - - // TODO delete temp user - } -} - -// Implement Clone to make it easier to work with Arc -impl Clone for AnonymousClientConnection { - fn clone(&self) -> Self { - Self { - sender: Arc::clone(&self.sender), - receiver: Arc::clone(&self.receiver), - user_id: self.user_id, - ping: Arc::clone(&self.ping), - interested_users: Arc::clone(&self.interested_users), - is_open: Arc::clone(&self.is_open), - user_name: Arc::clone(&self.user_name), - display_name: Arc::clone(&self.display_name), - avatar: Arc::clone(&self.avatar), - } - } -} diff --git a/src/anonymous_clients/anonymous_manager.rs b/src/anonymous_clients/anonymous_manager.rs deleted file mode 100644 index edfefde..0000000 --- a/src/anonymous_clients/anonymous_manager.rs +++ /dev/null @@ -1,53 +0,0 @@ -use dashmap::DashMap; -use once_cell::sync::Lazy; -use rand::Rng; -use rand::seq::SliceRandom; -use std::sync::Arc; - -use crate::anonymous_clients::anonymous_client_connection::AnonymousClientConnection; - -static ANONYMOUS_USERS: Lazy>> = - Lazy::new(|| DashMap::new()); - -#[allow(dead_code)] -pub async fn add_anonymous_user(connection: Arc) { - ANONYMOUS_USERS.insert(connection.get_user_id(), connection); -} - -#[allow(dead_code)] -pub async fn remove_anonymous_user(user_id: u64) { - ANONYMOUS_USERS.remove(&user_id); -} - -pub async fn get_anonymous_user(user_id: u64) -> Option> { - ANONYMOUS_USERS.get(&user_id).map(|c| c.clone()) -} - -pub async fn get_anonymous_user_by_name( - username: String, -) -> Option> { - for user_conn in ANONYMOUS_USERS - .iter() - .map(|ref_multi| ref_multi.value().clone()) - { - if user_conn.get_user_name().await == username { - return Some(user_conn); - } - } - - return None; -} - -// TODO: implement check if taken -pub fn generate_username() -> String { - let adjectives = ["Swift", "Clever", "Brave", "Sneaky", "Fierce"]; - let nouns = ["Tiger", "Eagle", "Shark", "Wolf", "Dragon"]; - - let mut rng = rand::thread_rng(); - let adj = adjectives.choose(&mut rng).unwrap(); - let noun = nouns.choose(&mut rng).unwrap(); - - let number: u16 = rng.gen_range(0..10000); - - format!("{}{}{}", adj, noun, number) -} diff --git a/src/anonymous_clients/mod.rs b/src/anonymous_clients/mod.rs deleted file mode 100644 index 3edd0b4..0000000 --- a/src/anonymous_clients/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod anonymous_client_connection; -pub mod anonymous_manager; diff --git a/src/calls/call_group.rs b/src/calls/call_group.rs deleted file mode 100644 index 91e85cf..0000000 --- a/src/calls/call_group.rs +++ /dev/null @@ -1,106 +0,0 @@ -use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; - -use std::{env, sync::Arc, time::Duration}; -use tokio::sync::RwLock; -use uuid::Uuid; - -use crate::{ - calls::{call_util, caller::Caller}, - omega::omega_connection::get_omega_connection, -}; - -pub struct CallGroup { - pub call_id: Uuid, - pub members: RwLock>>, - pub show: RwLock, - pub anonymous_joining: RwLock, - pub short_link: RwLock>, -} - -impl CallGroup { - pub fn new(call_id: Uuid, user: Arc) -> Self { - CallGroup { - call_id, - members: RwLock::new(vec![user]), - show: RwLock::new(true), - anonymous_joining: RwLock::new(false), - short_link: RwLock::new(None), - } - } - - pub async fn get_caller(&self, user_id: u64) -> Option> { - self.members - .read() - .await - .iter() - .find(|caller| caller.user_id == user_id) - .cloned() - } - - pub async fn is_anonymous(&self) -> bool { - *self.anonymous_joining.read().await - } - - pub async fn set_anonymous_joining(&self, enable: bool) { - *self.anonymous_joining.write().await = enable; - - let _ = call_util::set_room_metadata( - self.call_id, - format!("{{\"anonymous_joining\": \"{}\"}}", enable), - ) - .await; - - if self.short_link.read().await.is_none() { - let long_link = format!( - "https://app.tensamin.net/call/anonymous?call_id={}&omikron_id={}", - self.call_id, - env::var("ID") - .unwrap_or("0".to_string()) - .parse::() - .unwrap_or(0), - ); - let response_cv = get_omega_connection() - .await_response( - &CommunicationValue::new(CommunicationType::shorten_link) - .add_data(DataTypes::link, DataValue::Str(long_link)), - Some(Duration::from_secs(20)), - ) - .await; - if let Ok(response) = response_cv { - *self.short_link.write().await = Some( - response - .get_data(DataTypes::link) - .as_str() - .unwrap() - .to_string(), - ); - log::info!( - "Shortened link for call {} is {}", - self.call_id, - self.short_link.read().await.as_ref().unwrap() - ); - } - } - } - - pub async fn create_anonymous_token(&self, user_id: u64) -> Option { - if self.is_anonymous().await { - if let Ok(token) = call_util::create_token(user_id, self.call_id, false) { - return Some(token); - } - } - None - } - - pub async fn remove_caller(&self, user_id: u64) { - let _ = call_util::remove_participant(self.call_id, user_id).await; - self.members - .write() - .await - .retain(|caller| caller.user_id != user_id); - } - - pub async fn get_short_link(self: Arc) -> Option { - self.short_link.read().await.clone() - } -} diff --git a/src/calls/call_manager.rs b/src/calls/call_manager.rs deleted file mode 100644 index a17f347..0000000 --- a/src/calls/call_manager.rs +++ /dev/null @@ -1,97 +0,0 @@ -use dashmap::DashMap; -use once_cell::sync::Lazy; -use std::sync::Arc; -use uuid::Uuid; - -use crate::calls::{call_group::CallGroup, caller::Caller}; - -pub static CALL_GROUPS: Lazy>> = Lazy::new(|| DashMap::new()); -#[allow(dead_code)] -pub async fn get_call_invites(user_id: u64) -> Vec> { - let mut callers = Vec::new(); - for (_, cg) in CALL_GROUPS.clone().into_iter() { - let members = cg.members.read().await; - for member in members.iter() { - if member.user_id == user_id { - callers.push(member.clone()); - } - } - } - callers -} - -pub async fn get_call(call_id: Uuid) -> Option> { - if let Some(b) = CALL_GROUPS.get(&call_id) { - Some(b.clone()) - } else { - None - } -} - -pub async fn get_call_groups(user_id: u64) -> Vec> { - let mut call_groups = Vec::new(); - for (_, cg) in CALL_GROUPS.clone().into_iter() { - let is_member = { - let members = cg.members.read().await; - members.iter().any(|m| m.user_id == user_id) - }; - - if is_member { - call_groups.push(cg.clone()); - } - } - call_groups -} - -pub async fn get_call_token(user_id: u64, call_id: Uuid) -> Option { - if let Some(cg) = CALL_GROUPS.get(&call_id) { - let mut members = cg.members.write().await; - - if let Some(member) = members.iter().find(|m| m.user_id == user_id) { - return Some(member.create_token()); - } - - let new_caller = Arc::new(Caller::new(user_id, call_id, false)); - let token = new_caller.create_token(); - - members.push(new_caller); - - return Some(token); - } - - if let Some(cg) = CALL_GROUPS.get(&call_id) { - let cg_clone = cg.clone(); - - let mut members = cg_clone.members.write().await; - if let Some(member) = members.iter().find(|m| m.user_id == user_id) { - return Some(member.create_token()); - } - let new_caller = Arc::new(Caller::new(user_id, call_id, false)); - let token = new_caller.create_token(); - members.push(new_caller); - return Some(token); - } - - let caller = Arc::new(Caller::new(user_id, call_id, true)); - let call_group = CallGroup::new(call_id, caller.clone()); - - CALL_GROUPS.insert(call_id, Arc::new(call_group)); - - Some(caller.create_token()) -} - -pub async fn add_invite(call_id: Uuid, inviter_id: u64, invitee_id: u64) -> bool { - if let Some(cg) = CALL_GROUPS.get(&call_id) { - let mut members = cg.members.write().await; - - let is_inviter_member = members.iter().any(|m| m.user_id == inviter_id); - - if is_inviter_member { - if !members.iter().any(|m| m.user_id == invitee_id) { - members.push(Arc::new(Caller::new(invitee_id, call_id, false))); - } - return true; - } - } - false -} diff --git a/src/calls/call_util.rs b/src/calls/call_util.rs deleted file mode 100644 index 57df005..0000000 --- a/src/calls/call_util.rs +++ /dev/null @@ -1,151 +0,0 @@ -use livekit_api::{ - access_token::{self}, - services::room::RoomClient, -}; -use livekit_protocol::Room; -use std::env; -use std::str::FromStr; -use std::time::Duration; -use uuid::Uuid; - -use crate::{calls::call_manager::CALL_GROUPS, log, log_err, util::logger::PrintType}; - -pub fn get_livekit() -> Result<(String, String, String), ()> { - let hostname = match env::var("LIVEKI_HOSTNAME") { - Ok(secret) => secret, - Err(_) => { - log_err!(0, PrintType::General, "LIVEKI_HOSTNAME not set!"); - return Err(()); - } - }; - let api_key = match env::var("LIVEKIT_API_KEY") { - Ok(key) => key, - Err(_) => { - log_err!(0, PrintType::General, "LIVEKIT_API_KEY not set!"); - return Err(()); - } - }; - let api_secret = match env::var("LIVEKIT_API_SECRET") { - Ok(secret) => secret, - Err(_) => { - log_err!(0, PrintType::General, "LIVEKIT_API_SECRET not set!"); - return Err(()); - } - }; - Ok((hostname, api_key, api_secret)) -} - -pub fn create_token(user_id: u64, call_id: Uuid, has_admin: bool) -> Result { - let (_, api_key, api_secret) = get_livekit()?; - - let token = access_token::AccessToken::with_api_key(&api_key, &api_secret) - .with_identity(&user_id.to_string()) - .with_grants(access_token::VideoGrants { - room_join: true, - room_admin: has_admin, - room: call_id.to_string(), - ..Default::default() - }) - .with_metadata(&format!("{{\"isAdmin\":{}}}", has_admin)) - .to_jwt(); - if let Ok(token) = token { - Ok(token) - } else { - Err(()) - } -} -#[allow(dead_code)] -pub async fn get_room(call_id: Uuid) -> Result<(RoomClient, Room), ()> { - if let Ok((hostname, api_key, api_secret)) = get_livekit() { - let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); - let rooms = room_service.list_rooms(Vec::new()).await; - if let Ok(rooms) = rooms { - for room in rooms { - if room.name == call_id.to_string() { - return Ok((room_service, room)); - } - } - } - } - return Err(()); -} - -pub async fn remove_participant(call_id: Uuid, user_id: u64) -> Result<(), ()> { - if let Ok((hostname, api_key, api_secret)) = get_livekit() { - let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); - if let Ok(_) = room_service - .remove_participant(&call_id.to_string(), &user_id.to_string()) - .await - { - return Ok(()); - } - } - return Err(()); -} - -#[allow(dead_code)] -pub async fn get_room_metadata(call_id: Uuid) -> Result { - if let Ok((_, room)) = get_room(call_id).await { - Ok(room.metadata) - } else { - Err(()) - } -} - -pub async fn set_room_metadata(call_id: Uuid, metadata: String) -> Result<(), ()> { - if let Ok((hostname, api_key, api_secret)) = get_livekit() { - let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); - if let Ok(_) = room_service - .update_room_metadata(&call_id.to_string(), &metadata) - .await - { - return Ok(()); - } - } - return Err(()); -} - -pub fn garbage_collect_calls() { - tokio::spawn(async move { - loop { - if let Ok((hostname, api_key, api_secret)) = get_livekit() { - let room_service = RoomClient::with_api_key(&hostname, &api_key, &api_secret); - clean_calls(room_service).await; - } - tokio::time::sleep(Duration::from_secs(2)).await; - } - }); -} -pub async fn clean_calls(room_service: RoomClient) { - let rooms = room_service.list_rooms(Vec::new()).await.unwrap(); - let mut call_ids: Vec = Vec::new(); - let mut no_users: Vec = Vec::new(); - for room in rooms { - if let Ok(id) = Uuid::from_str(&room.name) { - if room.num_participants == 0 { - no_users.push(id); - } - call_ids.push(id); - } - } - let size_pre = CALL_GROUPS.len(); - for (id, _) in CALL_GROUPS.clone().into_iter() { - if !call_ids.contains(&id) { - CALL_GROUPS.remove(&id); - } - } - for (_, cg) in CALL_GROUPS.clone().into_iter() { - *cg.show.write().await = !no_users.contains(&cg.call_id); - } - - let size_post = CALL_GROUPS.len(); - if size_pre - size_post != 0 { - log!( - 0, - PrintType::Call, - "Cleaned {} calls, {} remaining", - size_pre - size_post, - size_post - ); - } -} diff --git a/src/calls/caller.rs b/src/calls/caller.rs deleted file mode 100644 index 74e0c3b..0000000 --- a/src/calls/caller.rs +++ /dev/null @@ -1,49 +0,0 @@ -use std::time::{SystemTime, UNIX_EPOCH}; - -use tokio::sync::RwLock; -use uuid::Uuid; - -use crate::calls::call_util; - -pub struct Caller { - pub user_id: u64, - pub call_id: Uuid, - pub has_admin: bool, - pub timeout: RwLock, -} - -impl Caller { - pub fn new(user_id: u64, call_id: Uuid, has_admin: bool) -> Self { - Caller { - user_id, - call_id, - has_admin, - timeout: RwLock::new(0), - } - } - #[allow(dead_code)] - pub fn set_admin(&mut self, has_admin: bool) { - self.has_admin = has_admin; - } - pub fn has_admin(&self) -> bool { - self.has_admin - } - #[allow(dead_code)] - pub async fn is_timeouted(&self) -> bool { - *self.timeout.read().await - > SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as i64 - } - pub async fn set_timeout(&self, timeout: i64) { - *self.timeout.write().await = timeout; - } - pub fn create_token(&self) -> String { - if let Ok(token) = call_util::create_token(self.user_id, self.call_id, self.has_admin()) { - token - } else { - String::new() - } - } -} diff --git a/src/calls/mod.rs b/src/calls/mod.rs deleted file mode 100644 index 8413354..0000000 --- a/src/calls/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod call_group; -pub mod call_manager; -pub mod call_util; -pub mod caller; diff --git a/src/data/mod.rs b/src/data/mod.rs deleted file mode 100644 index 22d12a3..0000000 --- a/src/data/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod user; diff --git a/src/data/user.rs b/src/data/user.rs deleted file mode 100644 index a175e6d..0000000 --- a/src/data/user.rs +++ /dev/null @@ -1,30 +0,0 @@ -use strum::IntoEnumIterator; -use strum_macros::EnumIter; - -#[derive(Debug, Clone, PartialEq, EnumIter, Eq)] -#[allow(unused, non_camel_case_types)] -pub enum UserStatus { - user_offline, - user_online, - user_dnd, - user_idle, - user_wc, - user_borked, - iota_offline, - iota_online, - iota_borked, -} -#[allow(unused)] -impl UserStatus { - pub fn to_string(&self) -> String { - format!("{:?}", self) - } - pub fn from_str(s: &str) -> Option { - for sel in UserStatus::iter() { - if &sel.to_string() == s { - return Some(sel); - } - } - None - } -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index fa511ea..0000000 --- a/src/main.rs +++ /dev/null @@ -1,51 +0,0 @@ -mod anonymous_clients; -mod calls; -mod data; -mod omega; -mod rho; -mod util; - -use std::env; - -use dotenv::dotenv; -use once_cell::sync::Lazy; -use rustls::crypto::aws_lc_rs::default_provider; - -use crate::{ - calls::call_util::garbage_collect_calls, - omega::omega_connection::get_omega_connection, - rho::server::start, - util::{ - crypto_helper::{load_public_key, load_secret_key}, - logger::startup, - }, -}; - -static PRIVATE_KEY: Lazy = Lazy::new(|| env::var("PRIVATE_KEY").unwrap()); -pub fn get_private_key() -> x448::Secret { - load_secret_key(&*PRIVATE_KEY).unwrap() -} -static PUBLIC_KEY: Lazy = Lazy::new(|| env::var("PUBLIC_KEY").unwrap()); -pub fn get_public_key() -> x448::PublicKey { - load_public_key(&*PUBLIC_KEY).unwrap() -} - -#[tokio::main] -async fn main() { - if let Err(_) = default_provider().install_default() { - println!("Error loading Provider"); - return; - } - dotenv().ok(); - startup(); - - get_omega_connection(); - tokio::spawn(async move { - if let Err(e) = start(959).await { - log_err!(0, util::logger::PrintType::General, "{}", e); - } - }); - garbage_collect_calls(); - - tokio::signal::ctrl_c().await.unwrap(); -} diff --git a/src/omega/mod.rs b/src/omega/mod.rs deleted file mode 100644 index cbe77d9..0000000 --- a/src/omega/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod omega_connection; diff --git a/src/omega/omega_connection.rs b/src/omega/omega_connection.rs deleted file mode 100644 index ab84eb2..0000000 --- a/src/omega/omega_connection.rs +++ /dev/null @@ -1,741 +0,0 @@ -use crate::{ - data::user::UserStatus, - get_private_key, log, log_cv_in, log_cv_out, log_err, log_in, - rho::rho_manager::{self, RHO_CONNECTIONS, connection_count}, - util::{ - crypto_helper::{decrypt_b64, secret_key_to_base64}, - file_util::load_file_vec, - logger::PrintType, - }, -}; -use dashmap::DashMap; -use once_cell::sync::Lazy; -use std::{collections::HashMap, env, sync::Arc, time::Duration}; -use tokio::{ - sync::{Mutex, RwLock, mpsc, watch}, - task::JoinHandle, - time::{Instant, sleep}, -}; -use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue, rand_u32}; -use ttp_native::{Receiver, Sender}; -use uuid::Uuid; - -// ============================================================================ -// Configuration -// ============================================================================ - -const OMEGA_HOST_DEFAULT: &str = "methanium.net"; -const OMEGA_PORT_DEFAULT: u16 = 9187; -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(5); -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: Lazy> = Lazy::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 }, -} - -#[allow(unused_variables)] -impl ConnectionState { - pub fn is_connected(&self) -> bool { - match self { - ConnectionState::Connected { identified } => true, - _ => false, - } - } - - #[allow(dead_code)] - pub fn is_identified(&self) -> bool { - match self { - ConnectionState::Connected { identified: true } => true, - _ => false, - } - } -} - -// ============================================================================ -// Omega Connection (Client-side with auto-reconnect) -// ============================================================================ -#[allow(dead_code)] -pub struct OmegaConnection { - state: Arc>, - sender: Arc>>>, - connection_loop_handle: Arc>>>, - host: String, - port: u16, - server_cert: Vec, - last_ping: Arc>, - heartbeat_handle: Arc>>>, - message_send_times: Arc>>, - pub connection_id: Uuid, - shutdown_tx: Arc>>>, - // Track if we should reconnect on close - reconnect_on_close: Arc>, -} - -impl OmegaConnection { - pub fn new() -> Self { - Self::with_host(OMEGA_HOST_DEFAULT, OMEGA_PORT_DEFAULT) - } - - pub fn with_host(host: &str, port: u16) -> Self { - // Load server certificate from default location - let server_cert = - load_file_vec("certs", "cert.pem").expect("Failed to load server certificate"); - - Self::with_host_and_cert(host, port, server_cert) - } - - // New constructor that accepts certificate directly - pub fn with_host_and_cert(host: &str, port: u16, server_cert: Vec) -> Self { - let (shutdown_tx, _) = watch::channel(false); - - OmegaConnection { - 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, - server_cert, - last_ping: Arc::new(Mutex::new(-1)), - heartbeat_handle: Arc::new(Mutex::new(None)), - message_send_times: Arc::new(Mutex::new(HashMap::new())), - connection_id: Uuid::new_v4(), - shutdown_tx: Arc::new(Mutex::new(Some(shutdown_tx))), - reconnect_on_close: Arc::new(RwLock::new(true)), - } - } - - // ------------------------------------------------------------------------- - // Connection Management - // ------------------------------------------------------------------------- - - pub async fn start(self: Arc) { - // Cancel any existing connection loop - if let Some(handle) = self.connection_loop_handle.lock().await.take() { - handle.abort(); - } - - // Set reconnect flag - *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); - } - - #[allow(dead_code)] - pub async fn stop(&self) { - // Disable reconnection - *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(); - } - - // Close sender if connected - 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() { - log_in!(0, PrintType::Omega, "Connection loop shutting down"); - break; - } - - // Check if reconnection is enabled - if !*self.reconnect_on_close.read().await { - log_in!(0, PrintType::Omega, "Reconnection disabled, exiting loop"); - break; - } - - match self.clone().connect_once().await { - Ok(()) => { - // Connection closed gracefully, check if we should reconnect - if *self.reconnect_on_close.read().await { - log_err!( - 0, - PrintType::Omega, - "Connection lost, reconnecting in {:?}...", - reconnect_delay - ); - } else { - log_in!(0, PrintType::Omega, "Connection closed, not reconnecting"); - break; - } - } - Err(e) => { - log_err!( - 0, - PrintType::Omega, - "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; - - let addr_str = format!("https://{}:{}", self.host, self.port); - - let (sender, mut receiver) = ttp_native::client::connect(&addr_str, None) - .await - .map_err(|e| format!("Connection failed: {}", e))?; - - log_in!( - 0, - PrintType::Omega, - "QUIC connection established to {}", - addr_str - ); - - // Store sender - let sender_arc = Arc::new(sender); - *self.sender.write().await = Some(sender_arc.clone()); - *self.state.write().await = ConnectionState::Connected { identified: false }; - - // Get handle for close monitoring - let sender_handle = sender_arc.handle().clone(); - - // Start read loop - let read_self = self.clone(); - let read_handle = tokio::spawn(async move { - read_self.read_loop(&mut receiver, sender_handle).await; - }); - - // Send identification - self.send_identification().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); - - // Wait for read loop to complete (connection closed) - let result = read_handle.await; - - // Cleanup - *self.sender.write().await = None; - *self.state.write().await = ConnectionState::Disconnected; - - if let Some(handle) = self.heartbeat_handle.lock().await.take() { - handle.abort(); - } - - match result { - Ok(()) => { - // Check if we should reconnect - if *self.reconnect_on_close.read().await { - Err("Connection closed, will reconnect".to_string()) - } else { - Ok(()) - } - } - Err(e) => Err(format!("Read loop error: {}", e)), - } - } - - // ------------------------------------------------------------------------- - // Identification Handshake - // ------------------------------------------------------------------------- - - async fn send_identification(&self) { - let id = rand_u32(); - - let omikron_id = env::var("ID") - .unwrap_or("0".to_string()) - .parse::() - .unwrap_or(0); - - let identify_msg = CommunicationValue::new(CommunicationType::identification) - .with_id(id) - .add_data(DataTypes::omikron_id, DataValue::Number(omikron_id)); - - WAITING_TASKS.insert( - id, - WaitingTask { - task: Box::new(|selfc, cv| { - if cv.is_type(CommunicationType::error_not_found) { - log_err!( - 0, - PrintType::Omega, - "Identification failed: Omikron ID not found" - ); - return false; - } - if !cv.is_type(CommunicationType::challenge) { - return false; - } - - tokio::spawn(async move { - if let Err(e) = selfc.handle_challenge(cv).await { - log_err!(0, PrintType::Omega, "Challenge handling failed: {}", e); - } - }); - true - }), - inserted_at: Instant::now(), - }, - ); - - self.send_message(&identify_msg).await; - } - - async fn handle_challenge(&self, cv: CommunicationValue) -> Result<(), String> { - let challenge = cv - .get_data(DataTypes::challenge) - .as_str() - .ok_or("Challenge not found")?; - - let server_pub_key = cv - .get_data(DataTypes::public_key) - .as_str() - .ok_or("Public key not found")?; - - let decrypted_challenge = decrypt_b64( - &secret_key_to_base64(&get_private_key()), - server_pub_key, - challenge, - ) - .map_err(|e| format!("Decryption failed: {:?}", e))?; - - let response_msg = CommunicationValue::new(CommunicationType::challenge_response) - .with_id(cv.get_id()) - .add_data(DataTypes::challenge, DataValue::Str(decrypted_challenge)); - - let response_id = response_msg.get_id(); - - WAITING_TASKS.insert( - response_id, - WaitingTask { - task: Box::new(|selfc, final_cv| { - if !final_cv.is_type(CommunicationType::identification_response) { - log_err!(0, PrintType::Omega, "Expected identification_response"); - return false; - } - - let accepted = final_cv - .get_data(DataTypes::accepted) - .as_bool() - .unwrap_or(false); - - if !accepted { - log_err!(0, PrintType::Omega, "Omega did not accept identification"); - return false; - } - - tokio::spawn(async move { - let mut state = selfc.state.write().await; - if let ConnectionState::Connected { identified: _ } = *state { - *state = ConnectionState::Connected { identified: true }; - } - drop(state); - - selfc.sync_client_iota_status().await; - }); - - log!(0, PrintType::Omega, "Successfully identified with Omega"); - true - }), - inserted_at: Instant::now(), - }, - ); - - self.send_message(&response_msg).await; - Ok(()) - } - - async fn sync_client_iota_status(self: Arc) { - let mut connected_iota_ids: Vec = Vec::new(); - let mut connected_user_ids: Vec = Vec::new(); - - let rho_connections_reader = RHO_CONNECTIONS.read().await; - - for iota_id in rho_connections_reader.keys() { - connected_iota_ids.push(DataValue::Number(*iota_id)); - } - - for rho in rho_connections_reader.values() { - for client_conn in rho.get_client_connections().await { - connected_user_ids.push(DataValue::Number(client_conn.get_user_id().await as i64)); - } - } - - drop(rho_connections_reader); - - let sync_msg = CommunicationValue::new(CommunicationType::sync_client_iota_status) - .add_data(DataTypes::iota_ids, DataValue::Array(connected_iota_ids)) - .add_data(DataTypes::user_ids, DataValue::Array(connected_user_ids)) - .add_data( - DataTypes::rho_connections, - DataValue::Number(connection_count().await as i64), - ); - - self.send_message(&sync_msg).await; - } - - // ------------------------------------------------------------------------- - // Read Loop & Heartbeat - // ------------------------------------------------------------------------- - - async fn read_loop( - self: Arc, - receiver: &mut Receiver, - sender_handle: Arc, - ) { - // Monitor both receiver and sender handle for close - let mut close_rx = sender_handle.subscribe_close(); - - loop { - tokio::select! { - result = receiver.receive() => { - match result { - Ok(cv) => { - if !cv.is_type(CommunicationType::pong) && !cv.is_type(CommunicationType::ping) { - log_cv_in!(PrintType::Omega, &cv); - } - - if cv.is_type(CommunicationType::pong) || cv.is_type(CommunicationType::ping) { - self.handle_pong(&cv).await; - continue; - } - - let msg_id = cv.get_id(); - if let Some((_, task)) = WAITING_TASKS.remove(&msg_id) { - if (task.task)(self.clone(), cv.clone()) { - continue; - } - } - - if cv.is_type(CommunicationType::iota_user_data) { - if let DataValue::Array(users) = cv.get_data(DataTypes::user_ids) { - let mut user_ids: Vec = Vec::new(); - for value in users { - if let DataValue::Number(user_id) = value { - user_ids.push(*user_id as u64); - } - } - let connections = crate::rho::rho_manager::RHO_CONNECTIONS.read().await; - if let Some(iota_id) = cv.get_data(DataTypes::iota_id).as_number() { - if let Some(rho) = connections.get(&iota_id) { - rho.get_iota_connection().set_user_ids(user_ids).await; - } - } else { - for rho in connections.values() { - rho.get_iota_connection().set_user_ids(user_ids.clone()).await; - } - } - } - } - } - Err(e) => { - log_err!(0, PrintType::Omega, "Receive error: {}", e); - break; - } - } - } - _ = close_rx.changed() => { - // Connection was closed by either side - if let Some(reason) = close_rx.borrow().clone() { - log_err!(0, PrintType::Omega, "Connection closed: {:?}", reason); - } else { - log_in!(0, PrintType::Omega, "Connection closed cleanly"); - } - break; - } - } - } - } - - async fn heartbeat_loop(self: Arc) { - loop { - sleep(HEARTBEAT_INTERVAL).await; - - // Check if still connected - if !self.state.read().await.is_connected() { - break; - } - - // Check if sender is closed - if let Some(sender) = self.sender.read().await.as_ref() { - if sender.is_closed() { - log_err!(0, PrintType::Omega, "Sender closed, stopping heartbeat"); - break; - } - } else { - break; - } - - self.send_ping().await; - } - } - - async fn send_ping(&self) { - let ping = CommunicationValue::new(CommunicationType::ping).add_data( - DataTypes::send_time, - DataValue::Number( - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap_or_default() - .as_secs() as i64, - ), - ); - self.send_message(&ping).await; - } - - async fn handle_pong(&self, cv: &CommunicationValue) { - let timestamp = cv - .get_data(DataTypes::send_time) - .as_number() - .unwrap_or_else(|| { - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap_or_default() - .as_secs() as i64 - }); - - *self.last_ping.lock().await = timestamp; - } - - // ------------------------------------------------------------------------- - // Public API - // ------------------------------------------------------------------------- - - pub async fn send_message(&self, cv: &CommunicationValue) { - if !cv.is_type(CommunicationType::pong) && !cv.is_type(CommunicationType::ping) { - log_cv_out!(PrintType::Omega, &cv); - } - - let sender_guard = self.sender.read().await; - if let Some(sender) = sender_guard.as_ref() { - // Check if closed before sending - if sender.is_closed() { - log_err!(0, PrintType::Omega, "Cannot send: connection closed"); - drop(sender_guard); - // Trigger reconnection by closing the connection state - if let Some(sender) = self.sender.write().await.take() { - sender.close(); - } - return; - } - - let sender_clone = Arc::clone(sender); - drop(sender_guard); - - if let Err(e) = sender_clone.send(cv).await { - log_err!(0, PrintType::Omega, "Send failed: {}", e); - } - } else { - log_err!(0, PrintType::Omega, "Cannot send: not connected"); - } - } - - 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; - } - } - - pub async fn await_response( - &self, - cv: &CommunicationValue, - timeout_duration: Option, - ) -> Result { - self.await_connection(timeout_duration).await?; - - let (tx, mut rx) = mpsc::channel(1); - let msg_id = cv.get_id(); - - WAITING_TASKS.insert( - msg_id, - 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; - - let timeout = timeout_duration.unwrap_or(Duration::from_secs(10)); - - match tokio::time::timeout(timeout, rx.recv()).await { - Ok(Some(response_cv)) => Ok(response_cv), - Ok(_) => Err("Channel closed".to_string()), - Err(_) => { - WAITING_TASKS.remove(&msg_id); - Err("Request timed out".to_string()) - } - } - } - - #[allow(dead_code)] - pub async fn is_connected(&self) -> bool { - self.state.read().await.is_connected() - } - #[allow(dead_code)] - pub async fn is_identified(&self) -> bool { - self.state.read().await.is_identified() - } - - #[allow(dead_code)] - pub async fn close_iota(iota_id: i64) { - let cv = CommunicationValue::new(CommunicationType::iota_disconnected) - .add_data(DataTypes::iota_id, DataValue::Number(iota_id)); - OMEGA_CONNECTION.send_message(&cv).await; - } - - pub async fn client_changed(_iota_id: i64, user_id: i64, state: UserStatus) { - let msg_type = match state { - UserStatus::iota_offline => CommunicationType::user_disconnected, - UserStatus::user_offline => CommunicationType::user_disconnected, - _ => CommunicationType::user_connected, - }; - - let cv = CommunicationValue::new(msg_type) - .add_data(DataTypes::user_id, DataValue::Number(user_id)); - OMEGA_CONNECTION.send_message(&cv).await; - } - - pub async fn user_states(user_id: i64, user_ids: Vec) { - let user_ids = user_ids.iter().map(|v| DataValue::Number(*v)).collect(); - - let cv = CommunicationValue::new(CommunicationType::get_states) - .add_data(DataTypes::user_ids, DataValue::Array(user_ids)); - let msg_id = cv.get_id(); - - WAITING_TASKS.insert( - msg_id, - WaitingTask { - task: Box::new( - move |_: Arc, response: CommunicationValue| { - tokio::spawn(async move { - let rho = rho_manager::get_rho_con_for_user(user_id).await; - if let Some(rho) = rho { - for client in rho.get_client_connections_for_user(user_id).await { - client.send_message(&response).await; - } - } - }); - true - }, - ), - inserted_at: Instant::now(), - }, - ); - - OMEGA_CONNECTION.send_message(&cv).await; - } -} - -// ============================================================================ -// Global Instance -// ============================================================================ - -static OMEGA_CONNECTION: Lazy> = Lazy::new(|| { - let conn = Arc::new(OmegaConnection::new()); - - // Start the connection manager immediately - let conn_clone = conn.clone(); - tokio::spawn(async move { - conn_clone.start().await; - }); - - start_task_cleanup_loop(); - - conn -}); - -pub fn get_omega_connection() -> Arc { - OMEGA_CONNECTION.clone() -} diff --git a/src/omega/ping_pong_task.rs b/src/omega/ping_pong_task.rs deleted file mode 100644 index c7fc0b9..0000000 --- a/src/omega/ping_pong_task.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::time::Duration; -use tokio::time::Instant; -use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue, rand_u32}; - -use crate::omega::omega_connection::OmegaConnection; - -const PING_TIMEOUT: Duration = Duration::from_secs(30); - -impl OmegaConnection { - pub async fn send_ping(&self) { - let id = rand_u32(); - let send_time = Instant::now(); - - let mut message_send_times = self.message_send_times.lock().await; - message_send_times.retain(|_uuid, time| time.elapsed() < PING_TIMEOUT); - message_send_times.insert(id as i64, send_time); - - self.send_ping_message(id).await; - } - - pub async fn send_ping_message(&self, id: u32) { - let ping_message = CommunicationValue::new(CommunicationType::ping) - .with_id(id) - .add_data( - DataTypes::last_ping, - DataValue::Number(self.last_ping.lock().await.unwrap()), - ); - - self.send_message(&ping_message).await; - } - - /// Handles incoming pong and calculates latency - pub async fn handle_pong(&self, cv: &CommunicationValue, _log: bool) { - let id = cv.get_id(); - let mut message_send_times = self.message_send_times.lock().await; - if let Some(send_time) = message_send_times.remove(&(id as i64)) { - let ping = Instant::now().duration_since(send_time).as_millis() as i64; - *self.last_ping.lock().await = ping; - } - } -} diff --git a/src/rho/client_connection.rs b/src/rho/client_connection.rs deleted file mode 100644 index ebaabf2..0000000 --- a/src/rho/client_connection.rs +++ /dev/null @@ -1,583 +0,0 @@ -use crate::anonymous_clients::anonymous_manager; -use crate::calls::{call_manager, call_util}; -use crate::omega::omega_connection::get_omega_connection; -use crate::rho::connection::GeneralConnection; -use crate::rho::{rho_connection::RhoConnection, rho_manager}; -use crate::util::logger::PrintType; -use crate::{data::user::UserStatus, omega::omega_connection::OmegaConnection}; -use crate::{log_cv_in, log_cv_out, log_err, log_in, log_out}; -use std::str::FromStr; -use std::sync::Arc; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use tokio::sync::RwLock; -use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; -use ttp_native::{Receiver, Sender}; -use uuid::Uuid; - -pub struct ClientConnection { - pub user_id: u64, - - pub sender: Arc, - pub receiver: Arc, - pub ping: Arc>, - pub_key: Arc>>>, - pub rho_connection: Arc>>>, - pub interested_users: Arc>>, - is_open: Arc>, -} - -impl ClientConnection { - pub async fn from_general(general: Arc, user_id: u64) -> Arc { - Arc::new(Self { - ping: Arc::new(RwLock::new(0)), - pub_key: Arc::new(RwLock::new(None)), - rho_connection: general.rho_connection.clone(), - interested_users: Arc::new(RwLock::new(Vec::new())), - is_open: Arc::new(RwLock::new(true)), - sender: general.sender.clone(), - receiver: general.receiver.clone(), - user_id: user_id, - }) - } - pub fn start(self: Arc) { - let self_clone = self.clone(); - tokio::spawn(async move { - while let Ok(cv) = self_clone.receiver.receive().await { - self_clone.clone().handle_message(cv).await; - } - self_clone.handle_close().await; - }); - - let self_clone2 = self.clone(); - tokio::spawn(async move { - tokio::time::sleep(Duration::from_millis(50)).await; - if self_clone2.get_rho_connection().await.is_none() { - self_clone2 - .send_error_response(0, CommunicationType::error) - .await; - } - }); - } - - /// Get the user ID - pub async fn get_user_id(&self) -> u64 { - self.user_id - } - - /// Get current ping - pub async fn get_ping(&self) -> i64 { - *self.ping.read().await - } - - /// Get RhoConnection if available - pub async fn get_rho_connection(&self) -> Option> { - self.rho_connection.read().await.clone() - } - - /// Send a CommunicationValue to the client - pub async fn send_message(self: Arc, cv: &CommunicationValue) { - if !*self.is_open.read().await { - log_out!( - self.user_id as i64, - PrintType::Client, - "Attempted to send message to a closed connection." - ); - return; - } - if !cv.is_type(CommunicationType::pong) && !cv.is_type(CommunicationType::ping) { - log_cv_out!(PrintType::Client, &cv); - } - let _ = self.sender.send(&cv).await; - } - - /// Handle incoming message from client - pub async fn handle_message(self: Arc, cv: CommunicationValue) { - tokio::spawn(async move { - if cv.is_type(CommunicationType::ping) { - self.handle_ping(cv).await; - return; - } - log_cv_in!(PrintType::Client, cv); - - // Handle client status changes - if cv.is_type(CommunicationType::client_changed) { - self.handle_client_changed(cv).await; - return; - } - - // Handle call invites - if cv.is_type(CommunicationType::call_invite) { - self.handle_call_invite(cv).await; - return; - } - - // Handle get call requests - if cv.is_type(CommunicationType::call_token) { - self.handle_get_call(cv).await; - return; - } - - if cv.is_type(CommunicationType::call_disconnect_user) { - self.handle_call_disconnect_user(cv).await; - return; - } - - if cv.is_type(CommunicationType::call_timeout_user) { - self.handle_call_timeout_user(cv).await; - return; - } - - if cv.is_type(CommunicationType::call_set_anonymous_joining) { - self.handle_call_set_anonymous_joining(cv).await; - return; - } - if cv.is_type(CommunicationType::get_user_data) { - if let Some(anonymous) = { - if let Some(user_id) = cv.get_data(DataTypes::user_id).as_number() { - anonymous_manager::get_anonymous_user(user_id as u64).await - } else if let Some(username) = cv.get_data(DataTypes::username).as_str() { - anonymous_manager::get_anonymous_user_by_name(username.to_string()).await - } else { - None - } - } { - let response = CommunicationValue::new(CommunicationType::get_user_data) - .with_id(cv.get_id()) - .add_data( - DataTypes::username, - DataValue::Str(anonymous.get_user_name().await), - ) - .add_data( - DataTypes::user_id, - DataValue::Number(anonymous.get_user_id() as i64), - ) - .add_data( - DataTypes::display, - DataValue::Str(anonymous.get_display_name().await), - ) - .add_data( - DataTypes::avatar, - DataValue::Str(anonymous.get_avatar().await), - ) - .add_data(DataTypes::user_state, DataValue::Str("online".to_string())); - - self.send_message(&response).await; - - return; - } - } - - if cv.is_type(CommunicationType::change_user_data) - || cv.is_type(CommunicationType::read_notification) - || cv.is_type(CommunicationType::get_notifications) - || cv.is_type(CommunicationType::get_user_data) - || cv.is_type(CommunicationType::get_iota_data) - || cv.is_type(CommunicationType::delete_user) - { - let sender = self.get_user_id().await; - self.handle_omega_forward(cv.with_sender(sender as u64)) - .await; - return; - } - // Forward other messages to Iota - self.forward_to_iota(cv).await; - }); - } - async fn handle_omega_forward(self: Arc, cv: CommunicationValue) { - let client_for_closure = self.clone(); - tokio::spawn(async move { - let response_cv = get_omega_connection() - .await_response(&cv.with_sender(self.user_id), Some(Duration::from_secs(20))) - .await; - if let Ok(response_cv) = response_cv { - client_for_closure.send_message(&response_cv).await; - } - }); - } - - /// Handle ping message - async fn handle_ping(self: Arc, cv: CommunicationValue) { - // Update our ping if provided - if let DataValue::Number(last_ping) = cv.get_data(DataTypes::last_ping) { - let current = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis(); - let mut ping_guard = self.ping.write().await; - *ping_guard = current as i64 - last_ping; - } - - // Get Iota ping from RhoConnection - let iota_ping = if let Some(rho_conn) = self.get_rho_connection().await { - rho_conn.get_iota_connection().get_ping().await - } else { - -1 - }; - - // Send pong response - let response = CommunicationValue::new(CommunicationType::pong) - .with_id(cv.get_id()) - .add_data(DataTypes::ping_iota, DataValue::Number(iota_ping)); - - self.send_message(&response).await; - } - - /// Handle client status change - async fn handle_client_changed(self: Arc, cv: CommunicationValue) { - let user_id = self.get_user_id().await; - if let DataValue::Str(_status_str) = cv.get_data(DataTypes::user_state) { - let user_status = UserStatus::user_online; - if let Some(rho_conn) = self.get_rho_connection().await { - OmegaConnection::client_changed( - rho_conn.get_iota_id().await as i64, - user_id as i64, - user_status, - ) - .await; - } - } - } - - /// Handle call invite - async fn handle_call_invite(self: Arc, cv: CommunicationValue) { - let receiver_id: i64 = cv.get_data(DataTypes::receiver_id).as_number().unwrap_or(0); - if receiver_id == 0 { - self.send_error_response(cv.get_id(), CommunicationType::error_no_user_id) - .await; - return; - } - - let call_id = match cv.get_data(DataTypes::call_id) { - DataValue::Str(id_str) => match Uuid::parse_str(id_str.as_str()) { - Ok(id) => id, - Err(_) => { - self.send_error_response(cv.get_id(), CommunicationType::error_invalid_call_id) - .await; - return; - } - }, - _ => { - self.send_error_response(cv.get_id(), CommunicationType::error_no_call_id) - .await; - return; - } - }; - - let invited = call_manager::add_invite(call_id, self.user_id, receiver_id as u64).await; - if !invited { - self.send_error_response(cv.get_id(), CommunicationType::error_invalid_call_id) - .await; - return; - } - - // Find target RhoConnection - let target_rho = match rho_manager::get_rho_con_for_user(receiver_id).await { - Some(rho) => rho, - _ => { - self.send_error_response(cv.get_id(), CommunicationType::error) - .await; - return; - } - }; - - // Get sender user ID - let sender_id = self.get_user_id().await; - - // Create and send call distribution message - let forward = CommunicationValue::new(CommunicationType::call_invite) - .with_receiver(receiver_id as u64) - .with_sender(sender_id as u64) - .add_data(DataTypes::call_id, DataValue::Str(call_id.to_string())) - .add_data( - DataTypes::receiver_id, - DataValue::Str(receiver_id.to_string()), - ) - .add_data(DataTypes::sender_id, DataValue::Str(sender_id.to_string())); - - target_rho.message_to_client(forward).await; - - let response = CommunicationValue::new(CommunicationType::success).with_id(cv.get_id()); - self.send_message(&response).await; - } - - /// Handle get call request - async fn handle_get_call(self: Arc, cv: CommunicationValue) { - let user_id = self.get_user_id().await; - - let call_id = match cv.get_data(DataTypes::call_id) { - DataValue::Str(id_str) => match Uuid::parse_str(id_str.as_str()) { - Ok(id) => id, - Err(_) => { - self.send_error_response(cv.get_id(), CommunicationType::error) - .await; - return; - } - }, - _ => { - self.send_error_response(cv.get_id(), CommunicationType::error) - .await; - return; - } - }; - - if let Some(token) = call_manager::get_call_token(user_id, call_id).await { - let response = CommunicationValue::new(CommunicationType::call_token) - .with_id(cv.get_id()) - .with_receiver(user_id as u64) - .add_data(DataTypes::call_token, DataValue::Str(token)); - self.send_message(&response).await; - } else { - self.send_error_response(cv.get_id(), CommunicationType::error) - .await; - return; - } - } - async fn handle_call_timeout_user(self: Arc, cv: CommunicationValue) { - let call_id = - Uuid::from_str(cv.get_data(DataTypes::call_id).as_str().unwrap_or("")).unwrap(); - let user_id = cv.get_data(DataTypes::user_id).as_number().unwrap_or(0); - let untill = cv.get_data(DataTypes::untill).as_number().unwrap_or(0); - - let call = call_manager::get_call(call_id).await; - if let Some(call) = call { - if call - .get_caller(self.get_user_id().await) - .await - .unwrap() - .has_admin() - { - let _ = call_util::remove_participant(call_id, user_id as u64).await; - call.get_caller(user_id as u64) - .await - .unwrap() - .set_timeout(untill) - .await; - } - } - } - async fn handle_call_disconnect_user(self: Arc, cv: CommunicationValue) { - let call_id = - Uuid::from_str(cv.get_data(DataTypes::call_id).as_str().unwrap_or("")).unwrap(); - let user_id = cv.get_data(DataTypes::user_id).as_number().unwrap_or(0); - - let call = call_manager::get_call(call_id).await; - if let Some(call) = call { - if call - .get_caller(self.get_user_id().await) - .await - .unwrap() - .has_admin() - { - call.remove_caller(user_id as u64).await; - } - } - } - async fn handle_call_set_anonymous_joining(self: Arc, cv: CommunicationValue) { - let call_id = - Uuid::from_str(cv.get_data(DataTypes::call_id).as_str().unwrap_or("")).unwrap(); - let enable = cv.get_data(DataTypes::enabled).as_bool().unwrap_or(true); - - let call = call_manager::get_call(call_id).await; - - let mut short_link = None; - if let Some(call) = call { - if call - .get_caller(self.get_user_id().await) - .await - .unwrap() - .has_admin() - { - call.set_anonymous_joining(enable).await; - } - short_link = call.get_short_link().await; - } - let mut response_cv = - CommunicationValue::new(CommunicationType::call_set_anonymous_joining) - .with_id(cv.get_id()) - .add_data(DataTypes::call_id, DataValue::Str(call_id.to_string())) - .add_data(DataTypes::enabled, DataValue::Bool(enable)); - if let Some(short_link) = short_link { - response_cv = response_cv.add_data(DataTypes::link, DataValue::Str(short_link)); - } - self.send_message(&response_cv).await; - } - - /// Forward message to Iota - async fn forward_to_iota(self: Arc, cv: CommunicationValue) { - let sender_user_id = self.get_user_id().await; - let msg_id = cv.get_id(); - let msg_type = cv.get_type(); - - log_in!( - sender_user_id as i64, - PrintType::Client, - "Forwarding client->iota: sender={} type={:?} id={} receiver={}", - sender_user_id, - msg_type, - msg_id, - cv.get_receiver() - ); - - if cv.is_type(CommunicationType::add_conversation) - && cv - .get_data(DataTypes::chat_partner_id) - .as_number() - .is_none() - { - let chat_partner_name = cv - .get_data(DataTypes::chat_partner_name) - .as_str() - .unwrap_or("") - .to_string(); - - if anonymous_manager::get_anonymous_user_by_name(chat_partner_name.to_string()) - .await - .is_some() - { - self.send_error_response(cv.get_id(), CommunicationType::error_anonymous) - .await; - return; - } - - let load_uuid_response = get_omega_connection() - .await_response( - &CommunicationValue::new(CommunicationType::get_user_data) - .with_id(cv.clone().get_id()) - .add_data( - DataTypes::username, - DataValue::Str(chat_partner_name.clone()), - ), - Some(Duration::from_secs(20)), - ) - .await; - let chat_partner_id = { - if let Ok(load_uuid_response) = load_uuid_response { - load_uuid_response.get_data(DataTypes::user_id).clone() - } else { - DataValue::Null - } - }; - - if let Some(rho_conn) = self.get_rho_connection().await { - let iota_id = rho_conn.get_iota_id().await; - log_in!( - sender_user_id as i64, - PrintType::Client, - "Resolved rho for add_conversation: sender={} -> iota_id={} id={}", - sender_user_id, - iota_id, - msg_id - ); - - let updated_cv = cv - .with_sender(sender_user_id as u64) - .add_data(DataTypes::chat_partner_id, chat_partner_id); - rho_conn.message_to_iota(updated_cv).await; - } else { - log_err!( - sender_user_id as i64, - PrintType::Client, - "No rho/iota mapping found for add_conversation sender={} type={:?} id={}", - sender_user_id, - msg_type, - msg_id - ); - } - return; - } - - if let Some(rho_conn) = self.get_rho_connection().await { - let iota_id = rho_conn.get_iota_id().await; - log_in!( - sender_user_id as i64, - PrintType::Client, - "Resolved rho for forward: sender={} -> iota_id={} type={:?} id={}", - sender_user_id, - iota_id, - msg_type, - msg_id - ); - - let updated_cv = cv.with_sender(sender_user_id as u64); - rho_conn.message_to_iota(updated_cv).await; - } else { - log_err!( - sender_user_id as i64, - PrintType::Client, - "No rho/iota mapping found for sender={} type={:?} id={}", - sender_user_id, - msg_type, - msg_id - ); - self.send_error_response(msg_id, CommunicationType::error) - .await; - } - } - - /// Send error response - async fn send_error_response(self: Arc, message_id: u32, error_type: CommunicationType) { - let error = CommunicationValue::new(error_type).with_id(message_id); - self.send_message(&error).await; - } - - /// Close the connection - pub async fn close(&self) { - let mut is_open_guard = self.is_open.write().await; - if !*is_open_guard { - return; - } - *is_open_guard = false; - - let _ = self.sender.close(); - } - - /// Set interested users list - pub async fn set_interested_users(self: Arc, interested_ids: Vec) { - let mut interested_guard = self.interested_users.write().await; - *interested_guard = interested_ids; - } - #[allow(dead_code)] - pub async fn get_interested_users(self: Arc) -> Vec { - let interested_guard = self.interested_users.read().await; - interested_guard.clone() - } - - /// Check if interested in a user and send notification - #[allow(dead_code)] - pub async fn are_you_interested(self: Arc, user_id: i64) { - let interested_guard = self.clone().get_interested_users().await; - if interested_guard.contains(&user_id) { - let notification = CommunicationValue::new(CommunicationType::client_changed) - .add_data(DataTypes::user_id, DataValue::Str(user_id.to_string())) - .add_data(DataTypes::user_state, DataValue::Str("online".to_string())); - - self.send_message(¬ification).await; - } - } - - /// Handle connection close - pub async fn handle_close(&self) { - let user_id = self.get_user_id().await; - if let Some(rho_conn) = rho_manager::get_rho_con_for_user(user_id as i64).await { - rho_conn - .close_client_connection(Arc::new(self.clone())) - .await; - } - } -} - -// Implement Clone to make it easier to work with Arc -impl Clone for ClientConnection { - fn clone(&self) -> Self { - Self { - sender: Arc::clone(&self.sender), - receiver: Arc::clone(&self.receiver), - user_id: self.user_id, - ping: Arc::clone(&self.ping), - pub_key: Arc::clone(&self.pub_key), - rho_connection: Arc::clone(&self.rho_connection), - interested_users: Arc::clone(&self.interested_users), - is_open: Arc::clone(&self.is_open), - } - } -} diff --git a/src/rho/connection.rs b/src/rho/connection.rs deleted file mode 100755 index ca746f0..0000000 --- a/src/rho/connection.rs +++ /dev/null @@ -1,358 +0,0 @@ -use rand::{Rng, distributions::Alphanumeric}; -use std::{sync::Arc, time::Duration}; -use tokio::sync::RwLock; -use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; -use ttp_native::{Receiver, Sender}; - -use crate::{ - anonymous_clients::anonymous_client_connection::AnonymousClientConnection, - get_private_key, get_public_key, log_cv_in, log_cv_out, log_err, log_in, log_out, - omega::omega_connection::get_omega_connection, - rho::{ - client_connection::ClientConnection, iota_connection::IotaConnection, - rho_connection::RhoConnection, rho_manager, - }, - util::{ - crypto_helper::{load_public_key, public_key_to_base64}, - crypto_util::{DataFormat, SecurePayload}, - logger::PrintType, - }, -}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[allow(dead_code)] -pub enum ConnectionKind { - Client, - Iota, - AnonymousClient, - Phi, -} - -pub struct GeneralConnection { - pub sender: Arc, - pub receiver: Arc, - - identified: Arc>, - challenged: Arc>, - challenge: Arc>, - - connection_kind: Arc>>, - pub rho_connection: Arc>>>, - id: Arc>, - - pub_key: Arc>>>, -} -impl GeneralConnection { - pub fn new(sender: Sender, receiver: Receiver) -> Arc { - Arc::new(Self { - sender: Arc::new(sender), - receiver: Arc::new(receiver), - identified: Arc::new(RwLock::new(false)), - challenged: Arc::new(RwLock::new(false)), - challenge: Arc::new(RwLock::new(String::new())), - connection_kind: Arc::new(RwLock::new(None)), - rho_connection: Arc::new(RwLock::new(None)), - id: Arc::new(RwLock::new(0)), - pub_key: Arc::new(RwLock::new(None)), - }) - } -} -impl GeneralConnection { - pub async fn handle(self: Arc) { - log_in!(0, PrintType::General, "General connection handler started"); - - loop { - let cv = match self.receiver.receive().await { - Ok(v) => v, - Err(_) => { - break; - } - }; - - log_cv_in!(cv); - - if !*self.identified.read().await { - self.handle_identification(cv).await; - continue; - } - - if !*self.challenged.read().await { - self.handle_challenge_response(cv).await; - } - - if *self.challenged.read().await { - let self_clone = self.clone(); - tokio::spawn(async move { - self_clone.migrate().await; - }); - break; - } - } - - log_out!(0, PrintType::General, "General connection handler stopped"); - } - async fn handle_identification(self: &Arc, cv: CommunicationValue) { - if !cv.is_type(CommunicationType::identification) { - return; - } - - if let DataValue::Number(iota_id) = cv.get_data(DataTypes::iota_id) { - *self.id.write().await = *iota_id as u64; - *self.connection_kind.write().await = Some(ConnectionKind::Iota); - - let get_pub_key_msg = CommunicationValue::new(CommunicationType::get_iota_data) - .add_data(DataTypes::iota_id, DataValue::Number(*iota_id)); - - let response_cv = get_omega_connection() - .await_response(&get_pub_key_msg, Some(Duration::from_secs(20))) - .await; - - let response_cv = match response_cv { - Ok(r) => r, - Err(_) => { - return; - } - }; - - let base64_pub = response_cv - .get_data(DataTypes::public_key) - .as_str() - .unwrap_or(""); - - let pub_key = match load_public_key(base64_pub) { - Some(pk) => pk, - None => { - return; - } - }; - - *self.pub_key.write().await = Some(pub_key.as_bytes().to_vec()); - - let challenge: String = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(32) - .map(char::from) - .collect(); - - *self.challenge.write().await = challenge.clone(); - *self.identified.write().await = true; - - let encrypted_challenge = - SecurePayload::new(challenge.as_bytes(), DataFormat::Raw, get_private_key()) - .unwrap() - .encrypt_x448(pub_key) - .unwrap() - .export(DataFormat::Base64); - - let response = CommunicationValue::new(CommunicationType::challenge) - .with_id(cv.get_id()) - .add_data( - DataTypes::public_key, - DataValue::Str(public_key_to_base64(&get_public_key())), - ) - .add_data(DataTypes::challenge, DataValue::Str(encrypted_challenge)); - - log_cv_out!(response); - let _ = self.sender.send(&response).await; - } else if let DataValue::Number(user_id) = cv.get_data(DataTypes::user_id) { - *self.id.write().await = *user_id as u64; - *self.connection_kind.write().await = Some(ConnectionKind::Client); - - let get_pub_key_msg = CommunicationValue::new(CommunicationType::get_user_data) - .add_data(DataTypes::user_id, DataValue::Number(*user_id)); - - let response_cv = get_omega_connection() - .await_response(&get_pub_key_msg, Some(Duration::from_secs(20))) - .await; - - let response_cv = match response_cv { - Ok(r) => r, - Err(_) => { - return; - } - }; - - let base64_pub = response_cv - .get_data(DataTypes::public_key) - .as_str() - .unwrap_or(""); - - let pub_key = match load_public_key(base64_pub) { - Some(pk) => pk, - None => { - return; - } - }; - - *self.pub_key.write().await = Some(pub_key.as_bytes().to_vec()); - - let challenge: String = rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(32) - .map(char::from) - .collect(); - - *self.challenge.write().await = challenge.clone(); - *self.identified.write().await = true; - - let encrypted_challenge = - SecurePayload::new(challenge.as_bytes(), DataFormat::Raw, get_private_key()) - .unwrap() - .encrypt_x448(pub_key) - .unwrap() - .export(DataFormat::Base64); - - let response = CommunicationValue::new(CommunicationType::challenge) - .with_id(cv.get_id()) - .add_data( - DataTypes::public_key, - DataValue::Str(public_key_to_base64(&get_public_key())), - ) - .add_data(DataTypes::challenge, DataValue::Str(encrypted_challenge)); - - log_cv_out!(response); - let _ = self.sender.send(&response).await; - } - } - async fn handle_challenge_response(self: &Arc, cv: CommunicationValue) { - let id = *self.id.read().await as i64; - - if !cv.is_type(CommunicationType::challenge_response) { - return; - } - - if let DataValue::Str(response) = cv.get_data(DataTypes::challenge) { - let expected = self.challenge.read().await.clone(); - - if *response == expected { - *self.challenged.write().await = true; - - let response = CommunicationValue::new(CommunicationType::identification_response) - .with_id(cv.get_id()) - .add_data(DataTypes::accepted, DataValue::Bool(true)); - - log_cv_out!(response); - if let Err(_) = self.sender.send(&response).await { - return; - } - } else { - log_err!( - id, - PrintType::Iota, - "Challenge response mismatch expected={} actual={}", - expected, - response - ); - } - } else { - log_err!( - id, - PrintType::Iota, - "Challenge response missing challenge payload" - ); - } - } - - async fn migrate(self: &Arc) -> bool { - let kind = match *self.connection_kind.read().await { - Some(kind) => kind, - None => { - return false; - } - }; - let id = *self.id.read().await; - - match kind { - ConnectionKind::Client => { - let notify = CommunicationValue::new(CommunicationType::user_connected) - .add_data(DataTypes::user_id, DataValue::Number(id as i64)); - get_omega_connection().send_message(¬ify).await; - - let user_id = id as i64; - - let client = ClientConnection::from_general(self.clone(), id).await; - - let mut rho = rho_manager::get_rho_con_for_user(user_id).await; - - if rho.is_none() { - let get_user_msg = CommunicationValue::new(CommunicationType::get_user_data) - .add_data(DataTypes::user_id, DataValue::Number(user_id)); - - if let Ok(user_data_cv) = get_omega_connection() - .await_response(&get_user_msg, Some(Duration::from_secs(20))) - .await - { - if let DataValue::Number(iota_id) = - user_data_cv.get_data(DataTypes::iota_id) - { - if let Some(bound_rho) = - rho_manager::bind_user_to_iota(user_id, *iota_id).await - { - bound_rho.bind_user_id(user_id).await; - rho = Some(bound_rho); - } - } - } - } - - *self.rho_connection.write().await = rho.clone(); - - if let Some(rho_conn) = rho { - rho_conn.bind_user_id(user_id).await; - rho_conn.add_client_connection(client.clone()).await; - } else { - log_err!( - user_id, - PrintType::Client, - "No RhoConnection found for user {}, client not attached to iota", - id - ); - } - - client.start(); - } - ConnectionKind::Iota => { - let notify = CommunicationValue::new(CommunicationType::iota_connected) - .add_data(DataTypes::iota_id, DataValue::Number(id as i64)); - get_omega_connection().send_message(¬ify).await; - - let iota = IotaConnection::from_general(self.clone(), id).await; - - let rho = Arc::new(RhoConnection::new(iota.clone(), Vec::new()).await); - - iota.set_rho_connection(rho.clone()).await; - - rho_manager::add_rho(rho).await; - - let get_iota_msg = CommunicationValue::new(CommunicationType::get_iota_data) - .add_data(DataTypes::iota_id, DataValue::Number(id as i64)); - - if let Ok(iota_data_cv) = get_omega_connection() - .await_response(&get_iota_msg, Some(Duration::from_secs(20))) - .await - { - if let DataValue::Array(users) = iota_data_cv.get_data(DataTypes::user_ids) { - let mut user_ids: Vec = Vec::new(); - for value in users { - if let DataValue::Number(user_id) = value { - user_ids.push(*user_id as u64); - } - } - iota.set_user_ids(user_ids).await; - } - } - - iota.clone().start(); - } - ConnectionKind::AnonymousClient => { - let client = AnonymousClientConnection::from_general(self.clone(), id).await; - client.start(); - } - ConnectionKind::Phi => { - let phi = ClientConnection::from_general(self.clone(), id).await; - phi.start(); - } - } - true - } -} diff --git a/src/rho/iota_connection.rs b/src/rho/iota_connection.rs deleted file mode 100755 index 41336ea..0000000 --- a/src/rho/iota_connection.rs +++ /dev/null @@ -1,461 +0,0 @@ -use crate::calls::call_group::CallGroup; -use crate::calls::call_manager; -use crate::log_cv_in; -use crate::log_cv_out; -use crate::log_err; -use crate::log_in; -use crate::omega::omega_connection::get_omega_connection; -use crate::rho::connection::GeneralConnection; -use crate::util::logger::PrintType; -use dashmap::DashMap; -use std::collections::BTreeMap; -use std::{collections::HashMap, sync::Arc, time::Duration}; -use tokio::sync::RwLock; -use tokio::sync::mpsc; -use ttp_core::CommunicationType; -use ttp_core::CommunicationValue; -use ttp_core::DataTypes; -use ttp_core::DataValue; -use ttp_native::Receiver; -use ttp_native::Sender; -use x448::PublicKey; - -use super::{rho_connection::RhoConnection, rho_manager}; -use crate::omega::omega_connection::OmegaConnection; - -#[allow(dead_code)] -pub struct IotaConnection { - pub iota_id: u64, - pub sender: Arc, - pub receiver: Arc, - pub user_ids: Arc>>, - pub ping: Arc>, - pub_key: Arc>>>, - pub waiting_tasks: - DashMap, CommunicationValue) -> bool + Send + Sync>>, - pub rho_connection: Arc>>>, -} - -impl IotaConnection { - pub async fn from_general(general: Arc, iota_id: u64) -> Arc { - Arc::new(Self { - ping: Arc::new(RwLock::new(0)), - pub_key: Arc::new(RwLock::new(None)), - rho_connection: general.rho_connection.clone(), - user_ids: Arc::new(RwLock::new(Vec::new())), - sender: general.sender.clone(), - receiver: general.receiver.clone(), - iota_id: iota_id, - waiting_tasks: DashMap::new(), - }) - } - pub fn start(self: Arc) { - let self_clone = self.clone(); - tokio::spawn(async move { - loop { - match self_clone.receiver.receive().await { - Ok(cv) => { - self_clone.clone().handle_message(cv).await; - } - Err(_) => { - break; - } - } - } - self_clone.handle_close().await; - }); - } - - /// Get the Iota ID - pub async fn get_iota_id(&self) -> u64 { - self.iota_id - } - - #[allow(dead_code)] - pub async fn get_public_key(&self) -> Option { - if let Some(public_key) = self.pub_key.read().await.clone() { - PublicKey::from_bytes(&public_key) - } else { - None - } - } - - /// Get the user IDs - pub async fn get_user_ids(&self) -> Vec { - self.user_ids.read().await.clone() - } - - /// Replace all users linked to this iota and synchronize the attached rho mapping. - pub async fn set_user_ids(&self, user_ids: Vec) { - { - let mut guard = self.user_ids.write().await; - *guard = user_ids.clone(); - } - - if let Some(rho_conn) = self.get_rho_connection().await { - let user_ids_i64: Vec = user_ids.into_iter().map(|u| u as i64).collect(); - rho_conn.set_user_ids(user_ids_i64).await; - } - } - - pub async fn add_user_id(&self, user_id: u64) { - let mut should_sync = false; - { - let mut guard = self.user_ids.write().await; - if !guard.contains(&user_id) { - guard.push(user_id); - should_sync = true; - } - } - - if should_sync { - if let Some(rho_conn) = self.get_rho_connection().await { - rho_conn.add_user_id(user_id as i64).await; - } - } - } - - /// Get current ping - pub async fn get_ping(&self) -> i64 { - *self.ping.read().await - } - - /// Set the RhoConnection reference - pub async fn set_rho_connection(&self, rho_connection: Arc) { - let mut rho_ref = self.rho_connection.write().await; - *rho_ref = Some(rho_connection); - } - - /// Get RhoConnection if available - pub async fn get_rho_connection(&self) -> Option> { - let rho_ref = self.rho_connection.read().await; - if let Some(weak_ref) = rho_ref.as_ref() { - Some(weak_ref.clone()) - } else { - None - } - } - - /// Send a CommunicationValue to the Iota - pub async fn send_message(&self, cv: &CommunicationValue) { - if !cv.is_type(CommunicationType::pong) { - log_cv_out!(PrintType::Iota, cv); - } - if let Err(e) = self.sender.send(&cv).await { - log_err!( - self.iota_id as i64, - PrintType::Iota, - "Failed to send message: {:?}", - e - ); - } - } - - /// Handle incoming message from Iota - pub async fn handle_message(self: Arc, cv: CommunicationValue) { - let msg_id = cv.get_id(); - if let Some((_, task)) = self.waiting_tasks.remove(&msg_id) { - if (task)(self.clone(), cv.clone()) { - return; - } - } - - // Handle ping - if cv.is_type(CommunicationType::ping) || cv.is_type(CommunicationType::pong) { - self.handle_ping(cv).await; - return; - } - - log_cv_in!(PrintType::Iota, cv); - - // Handle GET_CHATS - if cv.is_type(CommunicationType::get_chats) { - self.handle_get_chats(cv).await; - return; - } - - // Handle forwarding to other Iotas or clients - let receiver_id = cv.get_receiver(); - if (receiver_id != 0 && !self.get_user_ids().await.contains(&(receiver_id as u64))) - || cv.is_type(CommunicationType::message_other_iota) - || cv.is_type(CommunicationType::send_chat) - { - self.handle_forward_message(cv).await; - return; - } - - if cv.is_type(CommunicationType::change_iota_data) - || cv.is_type(CommunicationType::push_notification) - || cv.is_type(CommunicationType::get_user_data) - || cv.is_type(CommunicationType::get_iota_data) - || cv.is_type(CommunicationType::get_register) - || cv.is_type(CommunicationType::complete_register_user) - || cv.is_type(CommunicationType::delete_iota) - { - let sender = self.get_iota_id().await; - self.handle_omega_forward(cv.with_sender(sender as u64)) - .await; - return; - } - self.forward_to_client(cv).await; - } - - #[allow(dead_code)] - async fn send_error_response(&self, message_id: u32, error_type: CommunicationType) { - let error = CommunicationValue::new(error_type).with_id(message_id); - self.send_message(&error).await; - } - - #[allow(dead_code)] - async fn close(&self) { - let _ = self.sender.close(); - } - - async fn handle_omega_forward(self: Arc, cv: CommunicationValue) { - let iota_for_closure = self.clone(); - tokio::spawn(async move { - let response_cv = get_omega_connection() - .await_response(&cv.with_sender(self.iota_id), Some(Duration::from_secs(20))) - .await; - if let Ok(response_cv) = response_cv { - iota_for_closure.send_message(&response_cv).await; - } - }); - } - /// Handle ping message - async fn handle_ping(&self, cv: CommunicationValue) { - if let DataValue::Number(last_ping) = cv.get_data(DataTypes::last_ping) { - if let Ok(ping_val) = last_ping.to_string().parse::() { - let mut ping_guard = self.ping.write().await; - *ping_guard = ping_val; - } - } - - let client_pings = if let Some(rho_conn) = self.get_rho_connection().await { - rho_conn.get_client_pings().await - } else { - HashMap::new() - }; - - let pings: Vec<(DataTypes, DataValue)> = client_pings - .into_iter() - .map(|(k, v)| (DataTypes::parse(k), DataValue::Number(v))) - .collect(); - let response = CommunicationValue::new(CommunicationType::pong) - .with_id(cv.get_id()) - .add_data(DataTypes::ping_clients, DataValue::Container(pings)); - - self.send_message(&response).await; - } - - /// Handle message forwarding to other Iotas - async fn handle_forward_message(&self, cv: CommunicationValue) { - let receiver_id = cv.get_receiver(); - let sender_id = cv.get_sender(); - let my_user_ids = self.get_user_ids().await; - - log_in!( - self.iota_id as i64, - PrintType::Iota, - "Authority check: sender_id={} receiver_id={} iota_user_ids={:?} msg_type={:?} msg_id={}", - sender_id, - receiver_id, - my_user_ids, - cv.get_type(), - cv.get_id() - ); - - if my_user_ids.contains(&(sender_id as u64)) { - if let Some(target_rho) = rho_manager::get_rho_con_for_user(receiver_id as i64).await { - target_rho.message_to_iota(cv).await; - } else { - let error = CommunicationValue::new(CommunicationType::error_no_iota) - .with_id(cv.get_id()) - .with_sender(cv.get_sender()); - self.send_message(&error).await; - } - } else { - log_err!( - self.iota_id as i64, - PrintType::Iota, - "Rejected client->iota forward: sender_id={} is not authorized for this iota. Known users={:?}", - sender_id, - my_user_ids - ); - - self.send_message( - &CommunicationValue::new(CommunicationType::error_invalid_user_id).add_data( - DataTypes::error_type, - DataValue::Str( - "You are sending to another User without authority.".to_string(), - ), - ), - ) - .await; - } - } - - /// Handle GET_CHATS message - async fn handle_get_chats(&self, cv: CommunicationValue) { - let receiver_id = cv.get_receiver(); - let mut interested_ids: Vec = Vec::new(); - - // ============================ - // Load Calls - // ============================ - let calls: Vec> = call_manager::get_call_groups(receiver_id).await; - - let mut invites: HashMap> = HashMap::new(); - let empty = calls.is_empty(); - - for call in calls { - for inviter in call.members.read().await.iter() { - let call_self = call.get_caller(receiver_id).await.unwrap(); - - let inviter_id = inviter.user_id; - let timeout = *call_self.timeout.read().await; - let admin = call_self.has_admin(); - - // Build call container - let mut call_map: BTreeMap = BTreeMap::new(); - - call_map.insert(DataTypes::call_id, DataValue::Str(call.call_id.to_string())); - - if timeout > 0 { - call_map.insert(DataTypes::timeout, DataValue::Number(timeout as i64)); - } - - if admin { - call_map.insert(DataTypes::has_admin, DataValue::Bool(true)); - } - - let call_container = DataValue::container_from_map(&call_map); - - invites - .entry(inviter_id as i64) - .or_insert_with(Vec::new) - .push(call_container); - } - } - - // ============================ - // Enrich Contacts - // ============================ - let enriched_contacts = if empty { - match cv.get_data(DataTypes::user_ids) { - DataValue::Array(arr) => DataValue::Array(arr.clone()), - _ => DataValue::Array(vec![]), - } - } else { - let mut enriched: Vec = Vec::new(); - - if let DataValue::Array(users) = cv.get_data(DataTypes::user_ids) { - for user_val in users { - if let DataValue::Container(entries) = user_val { - let mut user_map: BTreeMap = - entries.iter().cloned().collect(); - - // extract user_id - if let Some(DataValue::Number(user_id)) = user_map.get(&DataTypes::user_id) - { - interested_ids.push(*user_id); - - // attach calls if exists - if let Some(call_list) = invites.get(user_id) { - user_map - .insert(DataTypes::calls, DataValue::Array(call_list.clone())); - } - } - - enriched.push(DataValue::container_from_map(&user_map)); - } - } - } - - DataValue::Array(enriched) - }; - - // ============================ - // Notify Omega - // ============================ - OmegaConnection::user_states(receiver_id as i64, interested_ids.clone()).await; - - // ============================ - // Notify Rho - // ============================ - if let Some(rho_conn) = self.get_rho_connection().await { - rho_conn - .set_interested(receiver_id as i64, interested_ids) - .await; - } - - // ============================ - // Forward to client - // ============================ - self.forward_to_client(cv.add_data(DataTypes::user_ids, enriched_contacts)) - .await; - } - - /// Forward message to client - async fn forward_to_client(&self, cv: CommunicationValue) { - if let Some(rho_conn) = self.get_rho_connection().await { - let updated_cv = cv.with_sender(self.get_iota_id().await); - rho_conn.message_to_client(updated_cv).await; - } else { - } - } - - pub async fn handle_close(&self) { - if let Some(rho_conn) = self.get_rho_connection().await { - rho_conn.close_iota_connection().await; - } - } - - #[allow(dead_code)] - pub async fn await_response( - self: Arc, - cv: &CommunicationValue, - timeout_duration: Option, - ) -> Result { - let (tx, mut rx) = mpsc::channel(1); - let msg_id = cv.get_id(); - - let task_tx = tx.clone(); - self.waiting_tasks.insert( - msg_id, - Box::new(move |_, response_cv| { - let inner_tx = task_tx.clone(); - tokio::spawn(async move { - let _ = inner_tx.send(response_cv).await; - }); - true - }), - ); - - self.send_message(cv).await; - - let timeout = timeout_duration.unwrap_or(Duration::from_secs(10)); - - 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()), - Err(_) => { - self.waiting_tasks.remove(&msg_id); - Err(format!( - "Request timed out after {} seconds.", - timeout.as_secs() - )) - } - } - } -} - -impl std::fmt::Debug for IotaConnection { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("IotaConnection") - .field("iota_id", &"[async]") - .field("identified", &"[async]") - .field("ping", &"[async]") - .finish() - } -} diff --git a/src/rho/mod.rs b/src/rho/mod.rs deleted file mode 100644 index ac498f3..0000000 --- a/src/rho/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod client_connection; -pub mod connection; -pub mod iota_connection; -pub mod rho_connection; -pub mod rho_manager; -pub mod server; diff --git a/src/rho/rho_connection.rs b/src/rho/rho_connection.rs deleted file mode 100644 index 6a740ff..0000000 --- a/src/rho/rho_connection.rs +++ /dev/null @@ -1,199 +0,0 @@ -use super::{client_connection::ClientConnection, iota_connection::IotaConnection, rho_manager}; - -use crate::data::user::UserStatus; -use crate::omega::omega_connection::OmegaConnection; -use std::collections::HashMap; -use std::sync::Arc; -use tokio::sync::RwLock; -use ttp_core::{CommunicationType, CommunicationValue, DataTypes, DataValue}; - -pub struct RhoConnection { - iota_connection: Arc, - user_ids: Arc>>, - client_connections: Arc>>>, -} - -impl RhoConnection { - /// Create a new RhoConnection - pub async fn new(iota_connection: Arc, user_ids: Vec) -> Self { - let rho_connection = Self { - iota_connection, - user_ids: Arc::new(RwLock::new(user_ids.clone())), - client_connections: Arc::new(RwLock::new(Vec::new())), - }; - - rho_connection - } - - pub async fn get_iota_id(&self) -> u64 { - self.iota_connection.iota_id - } - - pub async fn get_user_ids(&self) -> Vec { - self.user_ids.read().await.clone() - } - - pub async fn set_user_ids(&self, user_ids: Vec) { - let mut guard = self.user_ids.write().await; - *guard = user_ids; - } - - pub async fn add_user_id(&self, user_id: i64) { - let mut guard = self.user_ids.write().await; - if !guard.contains(&user_id) { - guard.push(user_id); - } - } - - pub async fn bind_user_id(&self, user_id: i64) { - self.add_user_id(user_id).await; - self.iota_connection.add_user_id(user_id as u64).await; - } - - pub fn get_iota_connection(&self) -> &Arc { - &self.iota_connection - } - - pub async fn get_client_connections(&self) -> Vec> { - let connections = self.client_connections.read().await; - connections.clone() - } - - /// Get client connections for a specific user - pub async fn get_client_connections_for_user( - &self, - user_id: i64, - ) -> Vec> { - let connections = self.client_connections.read().await; - let mut collections = Vec::new(); - for con in connections.iter() { - if con.get_user_id().await == user_id as u64 { - collections.push(con.clone()); - } - } - collections - } - - /// Add a client connection - #[allow(dead_code)] - pub async fn add_client_connection(&self, connection: Arc) { - let notification = CommunicationValue::new(CommunicationType::client_connected).add_data( - DataTypes::user_id, - DataValue::Number(connection.get_user_id().await as i64), - ); - - self.iota_connection.send_message(¬ification).await; - - { - let mut connections = self.client_connections.write().await; - connections.push(Arc::clone(&connection)); - } - - OmegaConnection::client_changed( - self.get_iota_id().await as i64, - connection.get_user_id().await as i64, - UserStatus::user_online, - ) - .await; - } - - /// Remove a client connection - pub async fn close_client_connection(&self, connection: Arc) { - let target_user_id = connection.get_user_id().await; - { - let mut connections = self.client_connections.write().await; - connections.retain(|con| { - futures::executor::block_on(async { con.get_user_id().await != target_user_id }) - }); - } - - // Notify OmegaConnection - OmegaConnection::client_changed( - self.get_iota_id().await as i64, - connection.get_user_id().await as i64, - UserStatus::user_offline, - ) - .await; - } - - /// Close the Iota connection and all associated client connections - pub async fn close_iota_connection(&self) { - // Close all client connections - let connections = self.get_client_connections().await; - for connection in connections { - connection.close().await; - } - - // Remove from manager - rho_manager::remove_rho(self.get_iota_id().await as i64).await; - - // Notify OmegaConnection - OmegaConnection::close_iota(self.get_iota_id().await as i64).await; - } - - /// Send message from Iota to specific client - pub async fn message_to_client(&self, cv: CommunicationValue) { - let connections = self.client_connections.read().await; - let receiver_id = cv.get_receiver(); - for connection in connections.iter() { - if connection.get_user_id().await == receiver_id { - connection.clone().send_message(&cv).await; - } - } - } - - /// Send message to Iota - pub async fn message_to_iota(&self, cv: CommunicationValue) { - self.iota_connection.send_message(&cv).await; - } - - /// Set interested users for a specific client - pub async fn set_interested(&self, user_id: i64, interested_ids: Vec) { - let connections = self.client_connections.read().await; - for connection in connections.iter() { - let conn_user_id = connection.get_user_id().await; - if conn_user_id == user_id as u64 { - connection - .clone() - .set_interested_users(interested_ids.clone()) - .await; - break; - } - } - } - - /// Check if clients are interested in a user - #[allow(dead_code)] - pub async fn are_they_interested(&self, user_id: i64) { - let connections = self.client_connections.read().await; - for connection in connections.iter() { - connection.clone().are_you_interested(user_id).await; - } - } - - /// Get ping information for all clients - pub async fn get_client_pings(&self) -> HashMap { - let connections = self.client_connections.read().await; - let mut pings = HashMap::new(); - - for connection in connections.iter() { - let user_id = connection.get_user_id().await; - pings.insert(user_id.to_string(), connection.get_ping().await); - } - - pings - } - - /// Check if this RhoConnection contains a specific user ID - #[allow(dead_code)] - pub async fn contains_user(&self, user_id: &i64) -> bool { - self.user_ids.read().await.contains(user_id) - } - - /// Get count of active client connections - #[allow(dead_code)] - pub async fn client_count(&self) -> usize { - let connections = self.client_connections.read().await; - connections.len() - } -} diff --git a/src/rho/rho_manager.rs b/src/rho/rho_manager.rs deleted file mode 100644 index e823a04..0000000 --- a/src/rho/rho_manager.rs +++ /dev/null @@ -1,83 +0,0 @@ -use super::rho_connection::RhoConnection; -use crate::log_in; -use crate::util::logger::PrintType; -use std::{ - collections::HashMap, - sync::{Arc, LazyLock}, -}; -use tokio::sync::RwLock; - -pub static RHO_CONNECTIONS: LazyLock>>>> = - LazyLock::new(|| Arc::new(RwLock::new(HashMap::new()))); - -pub async fn get_rho_con_for_user(user_id: i64) -> Option> { - let connections = RHO_CONNECTIONS.read().await; - for rho_connection in connections.values() { - let rho_user_ids = rho_connection.get_user_ids().await; - log_in!( - user_id, - PrintType::Client, - "Comparing user IDs: {:?}", - rho_user_ids - ); - if rho_user_ids.contains(&user_id) { - return Some(Arc::clone(rho_connection)); - } - } - None -} - -#[allow(dead_code)] -pub async fn contains_iota(iota_id: i64) -> bool { - let connections = RHO_CONNECTIONS.read().await; - connections.contains_key(&iota_id) -} - -/// Bind a user ID to an already tracked iota/rho connection. -pub async fn bind_user_to_iota(user_id: i64, iota_id: i64) -> Option> { - let connections = RHO_CONNECTIONS.read().await; - if let Some(rho_connection) = connections.get(&iota_id) { - let rho = Arc::clone(rho_connection); - drop(connections); - - rho.add_user_id(user_id).await; - - log_in!( - user_id, - PrintType::Client, - "Bound user {} to iota {}", - user_id, - iota_id - ); - - Some(rho) - } else { - None - } -} - -/// Remove a RhoConnection by Iota ID -pub async fn remove_rho(iota_id: i64) -> Option> { - let mut connections = RHO_CONNECTIONS.write().await; - connections.remove(&iota_id) -} - -/// Add a RhoConnection to the manager -pub async fn add_rho(rho_connection: Arc) { - let mut connections = RHO_CONNECTIONS.write().await; - let iota_id = rho_connection.get_iota_id().await; - connections.insert(iota_id as i64, rho_connection); -} - -/// Get a RhoConnection by Iota ID directly -#[allow(dead_code)] -pub async fn get_rho_by_iota(iota_id: i64) -> Option> { - let connections = RHO_CONNECTIONS.read().await; - connections.get(&iota_id).map(Arc::clone) -} - -/// Get the count of active connections -pub async fn connection_count() -> usize { - let connections = RHO_CONNECTIONS.read().await; - connections.len() -} diff --git a/src/rho/server.rs b/src/rho/server.rs deleted file mode 100644 index 9e3946d..0000000 --- a/src/rho/server.rs +++ /dev/null @@ -1,25 +0,0 @@ -use crate::{ - log, - rho::connection::GeneralConnection, - util::{file_util::load_file_vec, logger::PrintType}, -}; -use ttp_native::Host; - -pub async fn start(port: u16) -> Result<(), Box> { - let cert_pem = load_file_vec("certs", "cert.pem").expect("Error loading Pemfile"); - - let key_pem = load_file_vec("certs", "key.pem").expect("Error loading Keyfile"); - - let mut host: Host = ttp_native::host(port, cert_pem, key_pem).await?; - log!(0, PrintType::General, "Server listening on port {}", port); - - while let Some((sender, receiver)) = host.next().await { - tokio::spawn(async move { - let conn = GeneralConnection::new(sender, receiver); - conn.handle().await; - }); - } - log!(0, PrintType::General, "Server stopped"); - - Ok(()) -} diff --git a/src/util/crypto_helper.rs b/src/util/crypto_helper.rs deleted file mode 100755 index cb3ae6a..0000000 --- a/src/util/crypto_helper.rs +++ /dev/null @@ -1,149 +0,0 @@ -use aes_gcm::{ - Aes256Gcm, Nonce, - aead::{Aead, KeyInit, OsRng}, -}; -use base64::{Engine as _, engine::general_purpose::STANDARD}; -use rand_core::RngCore; -use sha2::{Digest, Sha256}; -use x448::{PublicKey, Secret, SharedSecret}; - -/// Errors for crypto operations -#[allow(dead_code)] -#[derive(Debug)] -pub enum CryptoError { - Base64Decode(base64::DecodeError), - InvalidKey, - AgreementError, - EncryptionError(aes_gcm::Error), - DecryptionError(aes_gcm::Error), -} - -impl From for CryptoError { - fn from(err: base64::DecodeError) -> Self { - CryptoError::Base64Decode(err) - } -} - -#[allow(dead_code)] -pub struct KeyPair { - pub secret: Secret, - pub public: PublicKey, -} - -#[allow(dead_code)] -pub fn generate_keypair() -> KeyPair { - let mut buf = [0u8; 56]; - let mut rng = OsRng; - rng.fill_bytes(&mut buf); - let secret = Secret::from_bytes(&buf).unwrap(); - let public = PublicKey::from(&secret); - KeyPair { secret, public } -} - -pub fn public_key_to_base64(pubkey: &PublicKey) -> String { - STANDARD.encode(pubkey.as_bytes().as_ref()) -} - -pub fn secret_key_to_base64(secret: &Secret) -> String { - STANDARD.encode(secret.as_bytes().as_ref()) -} - -pub fn load_public_key(base64_pub: &str) -> Option { - let bytes = STANDARD.decode(base64_pub).unwrap(); - PublicKey::from_bytes(&bytes) -} - -pub fn load_secret_key(base64_secret: &str) -> Option { - let bytes = STANDARD.decode(base64_secret).unwrap(); - Secret::from_bytes(&bytes) -} - -fn derive_aes_key(shared: &SharedSecret) -> [u8; 32] { - let mut hasher = Sha256::new(); - hasher.update(shared.as_bytes()); - let result = hasher.finalize(); - let mut key = [0u8; 32]; - key.copy_from_slice(&result[..32]); - key -} - -#[allow(dead_code)] -pub fn encrypt_b64( - base64_secret: &str, - base64_peer_pub: &str, - plaintext: &str, -) -> Result { - let secret = load_secret_key(base64_secret).unwrap(); - let peer_pub = load_public_key(base64_peer_pub).unwrap(); - encrypt(secret, peer_pub, plaintext) -} -pub fn encrypt( - secret: Secret, - peer_pub: PublicKey, - plaintext: &str, -) -> Result { - let shared = secret - .to_diffie_hellman(&peer_pub) - .ok_or(CryptoError::AgreementError)?; - let key_bytes = derive_aes_key(&shared); - let cipher = Aes256Gcm::new_from_slice(&key_bytes).expect("Key length should be correct"); - let mut nonce_bytes = [0u8; 12]; - OsRng.fill_bytes(&mut nonce_bytes); - let nonce = Nonce::from_slice(&nonce_bytes); - let ciphertext = cipher - .encrypt(nonce, plaintext.as_bytes()) - .map_err(CryptoError::EncryptionError)?; - // prefix nonce to ciphertext - let mut out = Vec::with_capacity(nonce_bytes.len() + ciphertext.len()); - out.extend_from_slice(&nonce_bytes); - out.extend_from_slice(&ciphertext); - Ok(STANDARD.encode(&out)) -} - -pub fn decrypt_b64( - base64_secret: &str, - base64_peer_pub: &str, - encrypted_base64: &str, -) -> Result { - let secret = load_secret_key(base64_secret).unwrap(); - let peer_pub = load_public_key(base64_peer_pub).unwrap(); - decrypt(secret, peer_pub, encrypted_base64) -} -pub fn decrypt( - secret: Secret, - peer_pub: PublicKey, - encrypted_base64: &str, -) -> Result { - let shared = secret - .to_diffie_hellman(&peer_pub) - .ok_or(CryptoError::AgreementError)?; - let key_bytes = derive_aes_key(&shared); - let cipher = Aes256Gcm::new_from_slice(&key_bytes).expect("Key length should be correct"); - - let encrypted = STANDARD.decode(encrypted_base64)?; - if encrypted.len() < 12 { - return Err(CryptoError::DecryptionError(aes_gcm::Error)); - } - let nonce_bytes = &encrypted[..12]; - let ciphertext = &encrypted[12..]; - let nonce = Nonce::from_slice(nonce_bytes); - let plaintext_bytes = cipher - .decrypt(nonce, ciphertext) - .map_err(CryptoError::DecryptionError)?; - let plaintext = String::from_utf8(plaintext_bytes) - .map_err(|_| CryptoError::DecryptionError(aes_gcm::Error))?; - Ok(plaintext) -} - -#[allow(dead_code)] -pub fn hash_it(input: &str) -> Vec { - let mut hasher = Sha256::new(); - hasher.update(input.as_bytes()); - hasher.finalize().to_vec() -} - -#[allow(dead_code)] -pub fn hex_hash(input: &str) -> String { - let digest = hash_it(input); - digest.iter().map(|b| format!("{:02x}", b)).collect() -} diff --git a/src/util/crypto_util.rs b/src/util/crypto_util.rs deleted file mode 100644 index bb784e8..0000000 --- a/src/util/crypto_util.rs +++ /dev/null @@ -1,178 +0,0 @@ -use aes_gcm::{ - Aes256Gcm, Nonce, - aead::{Aead, KeyInit, Payload}, -}; -use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64_STD}; -use hkdf::Hkdf; -type HkdfSha256 = sha2::Sha256; -use sha2::{Digest, Sha256 as HashSha256}; -use x448::{PublicKey, Secret}; - -#[derive(Debug)] -#[allow(dead_code)] -pub enum SecurePayloadError { - InvalidBase64, - InvalidHex, - EncryptionError, - DecryptionError, - InvalidKeyLength, -} - -#[derive(Clone, Copy, Debug)] -#[allow(dead_code)] -pub enum DataFormat { - Raw, - Base64, - Hex, -} - -pub struct SecurePayload { - inner_data: Vec, - private_key: Secret, -} - -impl Clone for SecurePayload { - fn clone(&self) -> Self { - Self { - inner_data: self.inner_data.clone(), - private_key: Secret::from_bytes(self.private_key.as_bytes()).unwrap(), - } - } -} - -#[allow(dead_code)] -impl SecurePayload { - pub fn new>( - data: T, - format: DataFormat, - private_key: S, - ) -> Result - where - S: Into, - { - let raw_data = match format { - DataFormat::Raw => data.as_ref().to_vec(), - DataFormat::Base64 => BASE64_STD - .decode(data.as_ref()) - .map_err(|_| SecurePayloadError::InvalidBase64)?, - DataFormat::Hex => { - hex::decode(data.as_ref()).map_err(|_| SecurePayloadError::InvalidHex)? - } - }; - - Ok(Self { - inner_data: raw_data, - private_key: private_key.into(), - }) - } - - pub fn get_public_key(&self) -> [u8; 56] { - *PublicKey::from(&self.private_key).as_bytes() - } - - pub fn export(&self, format: DataFormat) -> String { - match format.into() { - DataFormat::Raw => String::from_utf8_lossy(&self.inner_data).to_string(), - DataFormat::Base64 => BASE64_STD.encode(&self.inner_data), - DataFormat::Hex => hex::encode(&self.inner_data), - } - } - - pub fn get_bytes(&self) -> &[u8] { - &self.inner_data - } - - pub fn get_hash(&self, format: DataFormat) -> String { - let mut hasher = HashSha256::new(); - hasher.update(&self.inner_data); - let result = hasher.finalize(); - - match format { - DataFormat::Raw => String::from_utf8_lossy(&result).to_string(), - DataFormat::Base64 => BASE64_STD.encode(result), - DataFormat::Hex => hex::encode(result), - } - } - - pub fn encrypt_x448(&self, public_key: S) -> Result - where - S: Into, - { - let peer_pub = public_key.into(); - let shared_secret = self.private_key.as_diffie_hellman(&peer_pub).unwrap(); - - let hkdf = Hkdf::::new(None, shared_secret.as_bytes()); - let mut okm = [0u8; 44]; - - hkdf.expand(b"x448-aes-gcm-no-overhead", &mut okm) - .map_err(|_| SecurePayloadError::EncryptionError)?; - - let key = &okm[..32]; - let nonce_bytes = &okm[32..]; - - let cipher = Aes256Gcm::new(key.into()); - let nonce = Nonce::from_slice(nonce_bytes); - - let ciphertext = cipher - .encrypt( - nonce, - Payload { - msg: &self.inner_data, - aad: &[], - }, - ) - .map_err(|_| SecurePayloadError::EncryptionError)?; - - Ok(SecurePayload { - inner_data: ciphertext, - private_key: Secret::from_bytes(self.private_key.as_bytes()).unwrap(), - }) - } - - pub fn decrypt_to_format( - &self, - peer_public_key_bytes: &[u8; 56], - output_format: DataFormat, - ) -> Result { - let decrypted_instance = - self.decrypt_x448(PublicKey::from_bytes(peer_public_key_bytes).unwrap())?; - Ok(decrypted_instance.export(output_format)) - } - - pub fn decrypt_x448( - &self, - peer_public_key_bytes: S, - ) -> Result - where - S: Into, - { - let peer_pub = peer_public_key_bytes.into(); - let shared_secret = self.private_key.as_diffie_hellman(&peer_pub).unwrap(); - - let hkdf = Hkdf::::new(None, shared_secret.as_bytes()); - let mut okm = [0u8; 44]; - hkdf.expand(b"x448-aes-gcm-no-overhead", &mut okm) - .map_err(|_| SecurePayloadError::DecryptionError)?; - - let key = &okm[..32]; - let nonce_bytes = &okm[32..]; - - let cipher = Aes256Gcm::new(key.into()); - let nonce = Nonce::from_slice(nonce_bytes); - - let plaintext = cipher - .decrypt( - nonce, - Payload { - msg: &self.inner_data, - aad: &[], - }, - ) - .map_err(|_| SecurePayloadError::DecryptionError)?; - - Ok(SecurePayload { - inner_data: plaintext, - private_key: Secret::from_bytes(self.private_key.as_bytes()).unwrap(), - }) - } -} diff --git a/src/util/file_util.rs b/src/util/file_util.rs deleted file mode 100644 index cd214b1..0000000 --- a/src/util/file_util.rs +++ /dev/null @@ -1,185 +0,0 @@ -use std::fs::{self, File}; -use std::io::{self, BufReader, Read}; -use std::path::{Path, PathBuf}; - -use crate::log; -use crate::util::logger::PrintType; - -#[allow(dead_code)] -pub fn delete_directory(path: &str) -> bool { - let dir = Path::new(&get_directory()).join(path); - delete_dir_recursive(&dir) -} - -#[allow(dead_code)] -fn delete_dir_recursive(directory: &Path) -> bool { - if !directory.exists() { - return false; - } - if let Err(e) = fs::remove_dir_all(directory) { - log!( - 0, - PrintType::General, - "[IMPORTANT] Couldn't delete directory {}: {}", - directory.display(), - e, - ); - return false; - } - true -} - -#[allow(dead_code)] -pub fn delete_user_directory(user_id: i64) { - let user_dir = Path::new(&get_directory()) - .join("users") - .join(user_id.to_string()); - let _ = delete_dir_recursive(&user_dir); -} - -#[allow(dead_code)] -pub fn load_file_buf(path: &str, name: &str) -> io::Result> { - let dir = Path::new(&get_directory()).join(path); - let file_path = dir.join(name); - - // Ensure the directory exists, create if necessary - if !dir.exists() { - if let Err(_) = fs::create_dir_all(&dir) { - return Err(io::Error::new( - io::ErrorKind::NotFound, - "Directory creation failed", - )); - } - } - - // Create the file if it doesn't exist - if !file_path.exists() { - return Err(io::Error::new( - io::ErrorKind::NotFound, - "File creation failed", - )); - } - - // Open the file and return a BufReader for efficient reading - let file = File::open(&file_path)?; - Ok(BufReader::new(file)) -} -#[allow(dead_code)] -pub fn has_file(path: &str, name: &str) -> bool { - let dir = Path::new(&get_directory()).join(path); - let file_path = dir.join(name); - - if !dir.exists() { - return false; - } - - if !file_path.exists() { - return false; - } - - true -} -#[allow(dead_code)] -pub fn has_dir(path: &str) -> bool { - let dir = Path::new(&get_directory()).join(path); - - if !dir.exists() { - return false; - } - - true -} - -#[allow(dead_code)] -pub fn load_file(path: &str, name: &str) -> String { - let dir = Path::new(&get_directory()).join(path); - let file_path = dir.join(name); - - if !dir.exists() { - if let Err(e) = fs::create_dir_all(&dir) { - log!( - 0, - PrintType::General, - "[IMPORTANT] Couldn't create directories: {}", - e - ); - return String::new(); - } - return String::new(); - } - - if !file_path.exists() { - if let Err(e) = File::create(&file_path) { - log!( - 0, - PrintType::General, - "[IMPORTANT] Couldn't create file: {}", - e - ); - } - return String::new(); - } - - let mut content = String::new(); - if let Ok(mut f) = File::open(&file_path) { - let _ = f.read_to_string(&mut content); - } - content -} - -pub fn load_file_vec(path: &str, name: &str) -> Result, std::io::Error> { - let dir = Path::new(&get_directory()).join(path); - let file_path = dir.join(name); - - std::fs::read(file_path) -} - -#[allow(dead_code)] -pub fn save_file(path: &str, name: &str, value: &str) { - let dir = Path::new(&get_directory()).join(path); - let file_path = dir.join(name); - - if !dir.exists() { - if let Err(e) = fs::create_dir_all(&dir) { - log!( - 0, - PrintType::General, - "[IMPORTANT] Couldn't create directories: {}", - e - ); - return; - } - } - - if let Err(e) = fs::write(&file_path, value) { - log!( - 0, - PrintType::General, - "[IMPORTANT] Couldn't write file {}: {}", - file_path.display(), - e - ); - } -} - -#[allow(dead_code)] -pub fn get_children(path: &str) -> Vec { - let dir = Path::new(&get_directory()).join(path); - let mut children = Vec::new(); - if let Ok(entries) = fs::read_dir(&dir) { - for entry in entries { - if let Ok(entry) = entry { - children.push(entry.file_name().to_string_lossy().to_string()); - } - } - } - children -} - -pub fn get_directory() -> String { - let exe = std::env::current_exe().unwrap_or_else(|_| PathBuf::from(".")); - exe.parent() - .unwrap_or(Path::new(".")) - .to_string_lossy() - .to_string() -} diff --git a/src/util/logger.rs b/src/util/logger.rs deleted file mode 100644 index 9e9a085..0000000 --- a/src/util/logger.rs +++ /dev/null @@ -1,280 +0,0 @@ -use std::{ - collections::BTreeMap, - fs::{self, OpenOptions}, - io::Write, - path::Path, - sync::{OnceLock, mpsc}, - thread, - time::{SystemTime, UNIX_EPOCH}, -}; - -use ansi_term::Color; -use ttp_core::{CommunicationValue, DataTypes, DataValue}; - -static LOGGER: OnceLock> = OnceLock::new(); - -#[allow(dead_code)] -#[derive(Clone, Copy)] -pub enum PrintType { - Call, - Client, - Iota, - Omikron, - Omega, - General, -} - -struct LogMessage { - timestamp_ms: u128, - sender: Option, - prefix: &'static str, - kind: PrintType, - is_error: bool, - message: String, -} - -pub fn startup() { - let (tx, rx) = mpsc::channel::(); - LOGGER.set(tx).expect("Logger already initialized"); - - thread::spawn(move || { - let log_dir = Path::new("logs"); - fs::create_dir_all(log_dir).expect("Failed to create log directory"); - - let start_ts = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs(); - - let path = log_dir.join(format!("log_{}.txt", start_ts)); - let mut file = OpenOptions::new() - .create(true) - .append(true) - .open(path) - .expect("Failed to open log file"); - - for msg in rx { - let ts = fixed_box(&msg.timestamp_ms.to_string(), 13); - let sender = match msg.sender { - Some(id) => fixed_box(&id.to_string(), 19), - _ => fixed_box("", 19), - }; - - let line = format!("{} {} {} {}", ts, sender, msg.prefix, msg.message); - - println!("{}", colorize(msg.kind, msg.is_error).paint(&line)); - - let _ = writeln!(file, "{}", line); - } - }); -} - -fn colorize(kind: PrintType, is_error: bool) -> Color { - if is_error { - return Color::Red; - } - - match kind { - PrintType::Call => Color::Purple, - PrintType::Client => Color::Green, - PrintType::Iota => Color::Yellow, - PrintType::Omikron => Color::Blue, - PrintType::Omega => Color::Cyan, - PrintType::General => Color::White, - } -} - -fn fixed_box(content: &str, width: usize) -> String { - let s: String = content.chars().take(width).collect(); - let len = s.chars().count(); - if len < width { - format!("[{}{}]", " ".repeat(width - len), s) - } else { - s - } -} - -pub fn log_internal( - sender: i64, - kind: PrintType, - prefix: &'static str, - is_error: bool, - message: String, -) { - let sender = if sender == 0 { None } else { Some(sender) }; - - if let Some(tx) = LOGGER.get() { - let _ = tx.send(LogMessage { - timestamp_ms: SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis(), - sender, - prefix, - kind, - is_error, - message, - }); - } -} -#[macro_export] -macro_rules! log { - ($sender: expr, $kind:expr, $($arg:tt)*) => { - $crate::util::logger::log_internal($sender, $kind, "", false, format!($($arg)*)) - }; -} -#[macro_export] -macro_rules! log_in { - ($sender: expr, $kind:expr, $($arg:tt)*) => { - $crate::util::logger::log_internal($sender, $kind, ">", false, format!($($arg)*)) - }; -} -#[macro_export] -macro_rules! log_out { - ($sender:expr, $kind:expr, $($arg:tt)*) => { - $crate::util::logger::log_internal($sender, $kind, "<", false, format!($($arg)*)) - }; -} -#[macro_export] -macro_rules! log_err { - ($sender:expr, $kind:expr, $($arg:tt)*) => { - $crate::util::logger::log_internal($sender, $kind, ">>", true, format!($($arg)*)) - }; -} - -// ******** COMMUNICATION VALUES ******** -pub fn log_cv_internal( - prefix: &'static str, - cv: &CommunicationValue, - print_type: Option, -) { - let formatted = format_cv(cv); - - log_internal( - cv.get_sender() as i64, - 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 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) - }; -} diff --git a/src/util/mod.rs b/src/util/mod.rs deleted file mode 100644 index 1897223..0000000 --- a/src/util/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod crypto_helper; -pub mod crypto_util; -pub mod file_util; -pub mod logger;