From 40c651d99dd98a8a64bf25b584811c422c3e4166 Mon Sep 17 00:00:00 2001 From: Patrick Cleavelin Date: Fri, 28 Jul 2023 14:15:11 -0500 Subject: [PATCH] everything done except mod dashboard --- .gitignore | 1 + Cargo.lock | 1121 ++++++++++++++++++++++++++--------------------- Cargo.toml | 5 +- src/htmx.rs | 395 +++++++++++++++++ src/main.rs | 35 +- src/page.rs | 161 +++++++ src/routes.rs | 330 ++++++++++++-- src/settings.rs | 51 +++ 8 files changed, 1559 insertions(+), 540 deletions(-) create mode 100644 src/htmx.rs create mode 100644 src/page.rs diff --git a/.gitignore b/.gitignore index 5f25652..aaf15c0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ **/result result/ result +.env diff --git a/Cargo.lock b/Cargo.lock index 5d1c5e5..23788c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -19,14 +28,55 @@ dependencies = [ ] [[package]] -name = "aho-corasick" -version = "0.7.20" +name = "aead" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" +dependencies = [ + "aead 0.5.2", + "aes", + "cipher 0.4.4", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -38,19 +88,19 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-trait" -version = "0.1.64" +version = "0.1.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] @@ -64,7 +114,7 @@ dependencies = [ "log", "pin-project-lite", "tokio", - "tokio-rustls", + "tokio-rustls 0.23.4", "tungstenite", "webpki-roots", ] @@ -97,15 +147,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.9" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6137c6234afb339e75e764c866e3594900f0211e1315d33779f269bbe2ec6967" +checksum = "a6a1de45611fdb535bfde7b7de4fd54f4fd2b17b1737c0a59b69bf9b92074b8c" dependencies = [ "async-trait", "axum-core", - "bitflags", + "bitflags 1.3.2", "bytes", "futures-util", + "headers", "http", "http-body", "hyper", @@ -113,6 +164,7 @@ dependencies = [ "matchit", "memchr", "mime", + "multer", "percent-encoding", "pin-project-lite", "rustversion", @@ -123,16 +175,15 @@ dependencies = [ "sync_wrapper", "tokio", "tower", - "tower-http", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cae3e661676ffbacb30f1a824089a8c9150e71017f7e1e38f2aa32009188d34" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes", @@ -145,6 +196,44 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-extra" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cebbcd90f811f93fc2a993024caecc1e8270d9d1eb9d3359edb3069c2096ea6f" +dependencies = [ + "axum", + "axum-core", + "bytes", + "cookie", + "futures-util", + "http", + "http-body", + "mime", + "pin-project-lite", + "serde", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -153,9 +242,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "bitflags" @@ -164,25 +253,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "block-buffer" -version = "0.10.3" +name = "bitflags" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[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 = "bumpalo" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytemuck" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" [[package]] name = "byteorder" @@ -210,14 +305,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", - "num-traits 0.2.15", + "num-traits 0.2.16", "time 0.1.45", "wasm-bindgen", "winapi", @@ -233,22 +328,37 @@ dependencies = [ ] [[package]] -name = "cmake" -version = "0.1.49" +name = "cipher" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" dependencies = [ "cc", ] [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "cookie" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ - "termcolor", - "unicode-width", + "aes-gcm", + "base64 0.21.2", + "percent-encoding", + "rand", + "subtle", + "time 0.3.23", + "version_check", ] [[package]] @@ -263,15 +373,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -287,9 +397,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -301,61 +411,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] [[package]] -name = "cxx" -version = "1.0.91" +name = "ctr" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "cipher 0.4.4", ] [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.14.0", "lock_api", "once_cell", "parking_lot_core", @@ -370,14 +446,14 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", @@ -393,6 +469,12 @@ dependencies = [ "pnet_macros_support", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "encoding_rs" version = "0.8.32" @@ -413,13 +495,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys", ] [[package]] @@ -434,18 +516,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "miniz_oxide", @@ -461,7 +540,7 @@ dependencies = [ "futures-sink", "nanorand", "pin-project", - "spin 0.9.5", + "spin 0.9.8", ] [[package]] @@ -487,18 +566,18 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] [[package]] name = "futures" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -511,9 +590,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -521,15 +600,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -538,38 +617,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] name = "futures-sink" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -585,9 +664,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266041a359dfa931b370ef684cceb84b166beb14f7f0421f4a6a3d0c446d12e" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" dependencies = [ "cc", "libc", @@ -598,9 +677,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -608,9 +687,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "js-sys", @@ -620,10 +699,26 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.15" +name = "ghash" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -645,14 +740,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "hermit-abi" -version = "0.2.6" +name = "hashbrown" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "headers" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "libc", + "base64 0.13.1", + "bitflags 1.3.2", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", ] +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + [[package]] name = "http" version = "0.2.9" @@ -677,9 +800,9 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" @@ -695,9 +818,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.24" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -719,15 +842,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", - "rustls", + "rustls 0.21.5", "tokio", - "tokio-rustls", + "tokio-rustls 0.24.1", ] [[package]] @@ -745,33 +869,32 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "idna" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -779,50 +902,40 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] -name = "instant" -version = "0.1.12" +name = "inout" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" -dependencies = [ - "libc", - "windows-sys 0.45.0", + "generic-array", ] [[package]] name = "ipnet" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -835,30 +948,21 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -866,12 +970,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "loom" @@ -894,7 +995,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -913,8 +1014,11 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" name = "memejoin-rs" version = "0.1.1-alpha" dependencies = [ + "async-trait", "axum", + "axum-extra", "chrono", + "dotenv", "futures", "reqwest", "serde", @@ -926,14 +1030,14 @@ dependencies = [ "tower-http", "tracing", "tracing-subscriber", - "uuid 1.3.0", + "uuid 1.4.1", ] [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" @@ -947,23 +1051,40 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "log", + "memchr", + "mime", + "spin 0.9.8", + "version_check", ] [[package]] @@ -1003,49 +1124,48 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits 0.2.15", -] - [[package]] name = "num-traits" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" dependencies = [ - "num-traits 0.2.15", + "num-traits 0.2.16", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ "hermit-abi", "libc", ] [[package]] -name = "once_cell" -version = "1.17.0" +name = "object" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -1055,11 +1175,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.45" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1070,13 +1190,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] @@ -1087,11 +1207,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.80" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", @@ -1104,7 +1223,7 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" dependencies = [ - "num-traits 0.2.15", + "num-traits 0.2.16", ] [[package]] @@ -1125,48 +1244,48 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.45.0", + "windows-targets", ] [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -1176,9 +1295,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "pnet_base" @@ -1195,7 +1314,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn", + "syn 1.0.109", ] [[package]] @@ -1215,7 +1334,19 @@ checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash", + "universal-hash 0.4.1", +] + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash 0.5.1", ] [[package]] @@ -1226,18 +1357,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -1274,22 +1405,23 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.7.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-automata 0.3.3", + "regex-syntax 0.7.4", ] [[package]] @@ -1298,22 +1430,39 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.4", ] [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" -version = "0.11.14" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64 0.21.0", + "base64 0.21.2", "bytes", "encoding_rs", "futures-core", @@ -1333,14 +1482,14 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.21.5", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", - "tokio-rustls", + "tokio-rustls 0.24.1", "tokio-util", "tower-service", "url", @@ -1368,17 +1517,22 @@ dependencies = [ ] [[package]] -name = "rustix" -version = "0.36.8" +name = "rustc-demangle" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ - "bitflags", + "bitflags 2.3.3", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -1394,25 +1548,47 @@ dependencies = [ ] [[package]] -name = "rustls-pemfile" -version = "1.0.2" +name = "rustls" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" dependencies = [ - "base64 0.21.0", + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64 0.21.2", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" +dependencies = [ + "ring", + "untrusted", ] [[package]] name = "rustversion" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "salsa20" @@ -1420,17 +1596,17 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c0fbb5f676da676c260ba276a8f43a8dc67cf02d1438423aeb1c677a7212686" dependencies = [ - "cipher", + "cipher 0.3.0", "zeroize", ] [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -1441,15 +1617,9 @@ checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scratch" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -1463,11 +1633,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -1476,9 +1646,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -1486,9 +1656,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.152" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "63ba2516aa6bf82e0b19ca8b50019d52df58455d3cf9bdaf6315225fdd0c560a" dependencies = [ "serde_derive", ] @@ -1505,20 +1675,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "401797fe7833d72109fedec6bfcbe67c0eed9b99772f26eb8afd261f0abc6fd3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] name = "serde_json" -version = "1.0.93" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -1527,22 +1697,23 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.9" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b04f22b563c91331a10074bda3dd5492e3cc39d56bd557e91c0af42b6c7341" +checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" dependencies = [ + "itoa", "serde", ] [[package]] name = "serde_repr" -version = "0.1.10" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] @@ -1559,14 +1730,14 @@ dependencies = [ [[package]] name = "serenity" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fd5e7b5858ad96e99d440138f34f5b98e1b959ebcd3a1036203b30e78eb788" +checksum = "d007dc45584ecc47e791f2a9a7cf17bf98ac386728106f111159c846d624be3f" dependencies = [ "async-trait", "async-tungstenite", "base64 0.13.1", - "bitflags", + "bitflags 1.3.2", "bytes", "cfg-if", "dashmap", @@ -1580,7 +1751,7 @@ dependencies = [ "serde", "serde-value", "serde_json", - "time 0.3.17", + "time 0.3.23", "tokio", "tracing", "typemap_rev", @@ -1593,7 +1764,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be3aec8849ca2fde1e8a5dfbed96fbd68e9b5f4283fbe277d8694ce811d4952" dependencies = [ - "bitflags", + "bitflags 1.3.2", "enum_primitive", "serde", "serde_json", @@ -1611,6 +1782,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -1631,24 +1813,24 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -1695,9 +1877,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spin" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ "lock_api", ] @@ -1721,12 +1903,12 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "symphonia-core" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9567e2d8a5f866b2f94f5d366d811e0c6826babcff6d37de9e1a6690d38869" +checksum = "f7c73eb88fee79705268cc7b742c7bc93a7b76e092ab751d0833866970754142" dependencies = [ "arrayvec", - "bitflags", + "bitflags 1.3.2", "bytemuck", "lazy_static", "log", @@ -1734,9 +1916,20 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -1751,52 +1944,44 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "tempfile" -version = "3.4.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ "cfg-if", "fastrand", "redox_syscall", "rustix", - "windows-sys 0.42.0", -] - -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", + "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if", "once_cell", ] @@ -1813,9 +1998,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.17" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ "itoa", "serde", @@ -1825,15 +2010,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -1855,32 +2040,32 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.25.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", - "memchr", "mio", "num_cpus", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "1.8.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] @@ -1899,16 +2084,26 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls", + "rustls 0.20.8", "tokio", "webpki", ] [[package]] -name = "tokio-util" -version = "0.7.6" +name = "tokio-rustls" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6a3b08b64e6dfad376fa2432c7b1f01522e37a623c3050bc95db2d3ff21583" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.5", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -1936,11 +2131,11 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658" +checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" dependencies = [ - "bitflags", + "bitflags 2.3.3", "bytes", "futures-core", "futures-util", @@ -1948,7 +2143,6 @@ dependencies = [ "http-body", "http-range-header", "pin-project-lite", - "tower", "tower-layer", "tower-service", ] @@ -1980,20 +2174,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -2022,9 +2216,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", @@ -2057,7 +2251,7 @@ dependencies = [ "httparse", "log", "rand", - "rustls", + "rustls 0.20.8", "sha-1", "thiserror", "url", @@ -2088,15 +2282,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.10" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -2107,12 +2301,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - [[package]] name = "universal-hash" version = "0.4.1" @@ -2123,6 +2311,16 @@ dependencies = [ "subtle", ] +[[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" @@ -2131,9 +2329,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", @@ -2158,9 +2356,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", ] @@ -2185,11 +2383,10 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -2207,9 +2404,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2217,24 +2414,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.27", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -2244,9 +2441,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2254,22 +2451,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.27", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" @@ -2286,9 +2483,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -2329,15 +2526,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2346,127 +2534,78 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.39.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc 0.39.0", - "windows_i686_gnu 0.39.0", - "windows_i686_msvc 0.39.0", - "windows_x86_64_gnu 0.39.0", - "windows_x86_64_msvc 0.39.0", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.39.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.39.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.39.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.39.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.39.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winreg" @@ -2483,7 +2622,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e68bcb965d6c650091450b95cea12f07dcd299a01c15e2f9433b0813ea3c0886" dependencies = [ - "aead", + "aead 0.4.3", "poly1305", "rand_core", "salsa20", diff --git a/Cargo.toml b/Cargo.toml index 05eecb6..51d9552 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,11 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axum = "0.6.9" +async-trait = "0.1.72" +axum = { version = "0.6.9", features = ["headers", "multipart"] } +axum-extra = { version = "0.7.5", features = ["cookie-private", "cookie"] } chrono = "0.4.23" +dotenv = "0.15.0" futures = "0.3.26" reqwest = "0.11.14" serde = "1.0.152" diff --git a/src/htmx.rs b/src/htmx.rs new file mode 100644 index 0000000..98c5e4f --- /dev/null +++ b/src/htmx.rs @@ -0,0 +1,395 @@ +use std::collections::HashMap; + +pub trait Build { + fn build(self) -> String; +} + +#[derive(PartialEq)] +pub enum Tag { + Empty, + + Html, + Head, + Link, + Script, + Title, + Body, + Main, + Break, + + Details, + Summary, + + Dialog, + Article, + Header, + + Div, + + Table, + TableHead, + TableHeader, + TableBody, + TableRow, + TableData, + + Progress, + + Form, + Label, + FieldSet, + Input, + Select, + Option, + + Nav, + + OrderedList, + UnorderedList, + ListItem, + + Anchor, + Button, + + Header1, + Header2, + Header3, + Header4, + Header5, + Header6, + Strong, + Paragraph, + JustText, +} + +impl Tag { + fn as_str(&self) -> &'static str { + match self { + Self::Empty => "", + Self::JustText => "", + + Self::Html => "html", + Self::Head => "head", + Self::Link => "link", + Self::Script => "script", + Self::Title => "title", + Self::Body => "body", + Self::Main => "main", + Self::Break => "break", + + Self::Progress => "progress", + + Self::Details => "details", + Self::Summary => "summary", + + Self::Dialog => "dialog", + Self::Article => "article", + Self::Header => "header", + + Self::Div => "div", + + Self::Table => "table", + Self::TableHead => "thead", + Self::TableHeader => "th", + Self::TableBody => "tbody", + Self::TableRow => "tr", + Self::TableData => "td", + + Self::Form => "form", + Self::Label => "label", + Self::FieldSet => "fieldset", + Self::Input => "input", + Self::Select => "select", + Self::Option => "option", + + Self::Nav => "nav", + + Self::OrderedList => "ol", + Self::UnorderedList => "ul", + Self::ListItem => "li", + + Self::Anchor => "a", + Self::Button => "button", + + Self::Header1 => "h1", + Self::Header2 => "h2", + Self::Header3 => "h3", + Self::Header4 => "h4", + Self::Header5 => "h5", + Self::Header6 => "h6", + Self::Strong => "strong", + Self::Paragraph => "paragraph", + } + } + + fn start(&self) -> String { + if *self != Self::JustText && *self != Self::Empty { + format!("<{}>", self.as_str()) + } else { + String::new() + } + } + + fn end(&self) -> String { + if *self != Self::JustText + && *self != Self::Empty + && *self != Self::Link + && *self != Self::Input + { + format!("", self.as_str()) + } else { + String::new() + } + } +} + +pub enum SwapMethod { + InnerHtml, + OuterHtml, + BeforeEnd, + Refresh, +} + +impl SwapMethod { + fn as_str(&self) -> &'static str { + match self { + SwapMethod::InnerHtml => "innerHTML", + SwapMethod::OuterHtml => "outerHTML", + SwapMethod::BeforeEnd => "beforeend", + SwapMethod::Refresh => "refresh", + } + } +} + +pub struct HtmxBuilder { + tag: Tag, + attributes: HashMap, + children: Vec, + text: Option, +} + +impl Build for HtmxBuilder { + #[must_use] + fn build(self) -> String { + let mut string = String::new(); + + // TODO: do this better + { + if self.tag != Tag::JustText && self.tag != Tag::Empty { + string.push_str(&format!("<{}", self.tag.as_str())); + } + + for (attr, value) in self.attributes { + if value.is_empty() { + string.push_str(&format!(" {attr} ")); + } else { + string.push_str(&format!(" {attr}='{value}' ")); + } + } + if self.tag != Tag::JustText && self.tag != Tag::Empty { + string.push_str(">"); + } + } + + if let Some(text) = self.text { + string.push_str(&text); + } + + for child in self.children { + string.push_str(&child.build()); + } + + string.push_str(&self.tag.end()); + + string + } +} + +impl HtmxBuilder { + pub fn new(tag: Tag) -> Self { + Self { + tag, + attributes: HashMap::new(), + children: Vec::new(), + text: None, + } + } + + pub fn push_builder(mut self, builder: HtmxBuilder) -> Self { + self.children.push(builder); + self + } + + pub fn attribute(mut self, attr: &str, val: &str) -> Self { + self.attributes.insert(attr.to_string(), val.to_string()); + self + } + + pub fn hx_get(mut self, uri: &str) -> Self { + self.attribute("hx-get", uri) + } + + pub fn hx_post(mut self, uri: &str) -> Self { + self.attribute("hx-post", uri) + } + + pub fn hx_swap(mut self, swap_method: SwapMethod) -> Self { + self.attribute("hx-swap", swap_method.as_str()) + } + + pub fn hx_trigger(mut self, trigger: &str) -> Self { + self.attribute("hx-trigger", trigger) + } + + pub fn hx_target(mut self, target: &str) -> Self { + self.attribute("hx-target", target) + } + + pub fn html(mut self, builder_fn: F) -> Self + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(Tag::Html))); + self + } + + pub fn head(mut self, builder_fn: F) -> Self + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(Tag::Head))); + self + } + + pub fn title(mut self, text: &str) -> HtmxBuilder { + self.children.push(HtmxBuilder::new(Tag::Title).text(text)); + self + } + + pub fn body(mut self, builder_fn: F) -> Self + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(Tag::Body))); + self + } + + pub fn script(mut self, src: &str, integrity: Option<&str>) -> Self { + let mut b = HtmxBuilder::new(Tag::Script).attribute("src", src); + + if let Some(integrity) = integrity { + b = b + .attribute("integrity", integrity) + .attribute("crossorigin", "anonymous"); + } + + self.children.push(b); + self + } + + pub fn style_link(mut self, link: &str) -> Self { + self.children.push( + HtmxBuilder::new(Tag::Link) + .attribute("rel", "stylesheet") + .attribute("href", link), + ); + self + } + + pub fn flag(mut self, flag: &str) -> Self { + self.attributes.insert(flag.to_string(), "".to_string()); + self + } + + pub fn builder(mut self, tag: Tag, builder_fn: F) -> Self + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(tag))); + self + } + + pub fn builder_text(mut self, tag: Tag, text: &str) -> Self { + self.children.push(HtmxBuilder::new(tag).text(text)); + self + } + + pub fn nav(mut self, builder_fn: F) -> Self + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(Tag::Nav))); + self + } + + pub fn form(mut self, builder_fn: F) -> HtmxBuilder + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(Tag::Form))); + self + } + + pub fn label(mut self, builder_fn: F) -> HtmxBuilder + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(Tag::Label))); + self + } + + pub fn input(mut self, builder_fn: F) -> HtmxBuilder + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children.push(builder_fn(HtmxBuilder::new(Tag::Input))); + self + } + + pub fn button(mut self, builder_fn: F) -> HtmxBuilder + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children + .push(builder_fn(HtmxBuilder::new(Tag::Button))); + self + } + + pub fn ul(mut self, builder_fn: F) -> HtmxBuilder + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children + .push(builder_fn(HtmxBuilder::new(Tag::UnorderedList))); + self + } + + pub fn li(mut self, builder_fn: F) -> HtmxBuilder + where + F: FnOnce(HtmxBuilder) -> HtmxBuilder, + { + self.children + .push(builder_fn(HtmxBuilder::new(Tag::ListItem))); + self + } + + pub fn link(mut self, text: &str, href: &str) -> HtmxBuilder { + // TODO: add href attribute + self.children.push( + HtmxBuilder::new(Tag::Anchor) + .text(text) + .attribute("href", href), + ); + self + } + + pub fn text(mut self, text: &str) -> HtmxBuilder { + self.text = Some(text.to_string()); + self + } + + pub fn strong(mut self, text: &str) -> HtmxBuilder { + self.children.push(HtmxBuilder::new(Tag::Strong).text(text)); + self + } +} diff --git a/src/main.rs b/src/main.rs index 8709206..c0ce65b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,9 @@ #![feature(async_closure)] mod auth; +mod htmx; mod media; +mod page; mod routes; pub mod settings; @@ -133,6 +135,18 @@ fn spawn_api(settings: Arc>) { tokio::spawn(async move { let api = Router::new() + .route("/", get(page::home)) + .route("/index.html", get(page::home)) + .route("/login", get(page::login)) + .route("/guild/:guild_id", get(page::guild_dashboard)) + .route( + "/v2/intros/add/:guild_id/:channel", + post(routes::v2_add_intro_to_user), + ) + .route( + "/v2/intros/remove/:guild_id/:channel", + post(routes::v2_remove_intro_from_user), + ) .route("/health", get(routes::health)) .route("/me", get(routes::me)) .route("/intros/:guild", get(routes::intros)) @@ -148,6 +162,7 @@ fn spawn_api(settings: Arc>) { post(routes::remove_intro_to_user), ) .route("/auth", get(routes::auth)) + .route("/v2/auth", get(routes::v2_auth)) .layer( CorsLayer::new() // TODO: move this to env variable @@ -155,7 +170,7 @@ fn spawn_api(settings: Arc>) { .allow_headers(Any) .allow_methods([Method::GET, Method::POST, Method::DELETE]), ) - .with_state(Arc::new(state)); + .with_state(state); let addr = SocketAddr::from(([0, 0, 0, 0], 8100)); info!("socket listening on {addr}"); axum::Server::bind(&addr) @@ -233,21 +248,29 @@ async fn spawn_bot(settings: Arc>) { info!("Got PlaySound message"); let settings = settings.lock().await; - let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx.cache) else { + let Some(Channel::Guild(channel)) = channel_id.to_channel_cached(&ctx.cache) + else { error!("Failed to get cached channel from member!"); continue; }; - let Some(guild_settings) = settings.guilds.get(channel.guild_id.as_u64()) else { + let Some(guild_settings) = settings.guilds.get(channel.guild_id.as_u64()) + else { error!("couldn't get guild from id: {}", channel.guild_id.as_u64()); continue; }; let Some(channel_settings) = guild_settings.channels.get(channel.name()) else { - error!("couldn't get channel_settings from name: {}", channel.name()); + error!( + "couldn't get channel_settings from name: {}", + channel.name() + ); continue; }; let Some(user) = channel_settings.users.get(&member.user.name) else { - error!("couldn't get user settings from name: {}", &member.user.name); + error!( + "couldn't get user settings from name: {}", + &member.user.name + ); continue; }; @@ -310,6 +333,8 @@ async fn spawn_bot(settings: Arc>) { #[tokio::main] #[instrument] async fn main() -> std::io::Result<()> { + dotenv::dotenv().ok(); + tracing_subscriber::fmt::init(); let settings = serde_json::from_str::( diff --git a/src/page.rs b/src/page.rs new file mode 100644 index 0000000..f6c38db --- /dev/null +++ b/src/page.rs @@ -0,0 +1,161 @@ +use crate::{ + auth::{self, User}, + htmx::{Build, HtmxBuilder, SwapMethod, Tag}, + settings::{ApiState, Intro, IntroFriendlyName}, +}; +use axum::{ + extract::{Path, State}, + response::{Html, Redirect}, +}; +use tracing::error; + +pub(crate) async fn home(user: Option) -> Redirect { + if user.is_some() { + Redirect::to("/guild/588149178912473103") + } else { + Redirect::to("/login") + } +} + +fn intro_list<'a>( + intros: impl Iterator, + label: &str, + post: &str, +) -> HtmxBuilder { + HtmxBuilder::new(Tag::Empty).form(|b| { + b.attribute("class", "container") + .hx_post(post) + .attribute("hx-encoding", "multipart/form-data") + .builder(Tag::FieldSet, |b| { + let mut b = b + .attribute("class", "container") + .attribute("style", "max-height: 20%; overflow-y: scroll"); + for intro in intros { + b = b.builder(Tag::Label, |b| { + b.builder(Tag::Input, |b| { + b.attribute("type", "checkbox").attribute("name", &intro.0) + }) + .builder_text(Tag::Paragraph, intro.1.friendly_name()) + }); + } + + b + }) + .button(|b| b.attribute("type", "submit").text(label)) + }) +} + +pub(crate) async fn guild_dashboard( + State(state): State, + user: User, + Path(guild_id): Path, +) -> Result, Redirect> { + let settings = state.settings.lock().await; + + let Some(guild) = settings.guilds.get(&guild_id) else { + error!(%guild_id, "no such guild"); + return Err(Redirect::to("/")); + }; + let Some(guild_user) = guild.users.get(&user.name) else { + error!(%guild_id, %user.name, "no user in guild"); + return Err(Redirect::to("/")); + }; + + let is_moderator = guild_user.permissions.can(auth::Permission::DeleteSounds); + + Ok(Html( + HtmxBuilder::new(Tag::Html) + .head(|b| { + b.title("MemeJoin - Dashboard") + .script( + "https://unpkg.com/htmx.org@1.9.3", + Some("sha384-lVb3Rd/Ca0AxaoZg5sACe8FJKF0tnUgR2Kd7ehUOG5GCcROv5uBIZsOqovBAcWua"), + ) + .script("https://unpkg.com/hyperscript.org@0.9.9", None) + .style_link("https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css") + }) + .builder(Tag::Nav, |b| { + b.builder(Tag::Header1, |b| b.text("MemeJoin - A bot for user intros")) + .builder_text(Tag::Paragraph, &user.name) + }) + .builder(Tag::Main, |b| { + if is_moderator { + b.builder(Tag::Article, |b| { + b.builder_text(Tag::Header, "Wow, you're a moderator") + }) + } else { + b + } + .builder(Tag::Article, |b| { + let mut b = b.builder_text(Tag::Header, "Guild Settings"); + + for (channel_name, channel_settings) in &guild.channels { + if let Some(channel_user) = channel_settings.users.get(&user.name) { + let current_intros = + channel_user.intros.iter().filter_map(|intro_index| { + Some(( + &intro_index.index, + guild.intros.get(&intro_index.index)?, + )) + }); + let available_intros = guild.intros.iter().filter_map(|intro| { + if !channel_user + .intros + .iter() + .any(|intro_index| intro.0 == &intro_index.index) + { + Some((intro.0, intro.1)) + } else { + None + } + }); + b = b + .builder_text(Tag::Strong, channel_name) + .builder(Tag::Div, |b| { + b.builder_text(Tag::Strong, "Your Current Intros") + .push_builder(intro_list( + current_intros, + "Remove Intro", + &format!( + "/v2/intros/remove/{}/{}", + guild_id, channel_name + ), + )) + .builder_text(Tag::Strong, "Select Intros") + .push_builder(intro_list( + available_intros, + "Add Intro", + &format!( + "/v2/intros/add/{}/{}", + guild_id, channel_name + ), + )) + }); + } + } + + b + }) + }) + .build(), + )) +} + +pub(crate) async fn login(State(state): State) -> Html { + let authorize_uri = format!("https://discord.com/api/oauth2/authorize?client_id={}&redirect_uri={}/v2/auth&response_type=code&scope=guilds.members.read%20guilds%20identify", state.secrets.client_id, state.origin); + + Html( + HtmxBuilder::new(Tag::Html) + .head(|b| { + b.title("MemeJoin - Login") + .script( + "https://unpkg.com/htmx.org@1.9.3", + Some("sha384-lVb3Rd/Ca0AxaoZg5sACe8FJKF0tnUgR2Kd7ehUOG5GCcROv5uBIZsOqovBAcWua"), + ) + .script("https://unpkg.com/hyperscript.org@0.9.9", None) + .style_link("https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css") + }) + .link("Login", &authorize_uri) + .build(), + ) +} diff --git a/src/routes.rs b/src/routes.rs index 224e66d..dff6894 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -2,19 +2,23 @@ use std::{collections::HashMap, sync::Arc}; use axum::{ body::Bytes, - extract::{Path, Query, State}, - http::HeaderMap, - response::IntoResponse, - Json, + extract::{Multipart, Path, Query, State}, + http::{HeaderMap, HeaderValue}, + response::{IntoResponse, Redirect}, + Form, Json, }; -use reqwest::StatusCode; +use axum_extra::extract::{cookie::Cookie, CookieJar}; +use reqwest::{Proxy, StatusCode}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use tracing::{error, info}; use uuid::Uuid; -use crate::{auth, settings::FileIntro}; +use crate::{ + auth::{self, User}, + settings::FileIntro, +}; use crate::{ media, settings::{ApiState, GuildUser, Intro, IntroIndex, UserSettings}, @@ -123,8 +127,109 @@ struct DiscordUserGuild { pub owner: bool, } +pub(crate) async fn v2_auth( + State(state): State, + Query(params): Query>, + jar: CookieJar, +) -> Result<(CookieJar, Redirect), Error> { + let Some(code) = params.get("code") else { + return Err(Error::Auth("no code".to_string())); + }; + + info!("attempting to get access token with code {}", code); + + let mut data = HashMap::new(); + + let redirect_uri = format!("{}/v2/auth", state.origin); + data.insert("client_id", state.secrets.client_id.as_str()); + data.insert("client_secret", state.secrets.client_secret.as_str()); + data.insert("grant_type", "authorization_code"); + data.insert("code", code); + data.insert("redirect_uri", &redirect_uri); + + let client = reqwest::Client::new(); + + let auth: auth::Discord = client + .post("https://discord.com/api/oauth2/token") + .form(&data) + .send() + .await + .map_err(|err| Error::Auth(err.to_string()))? + .json() + .await + .map_err(|err| { + error!(?err, "auth error"); + Error::Auth(err.to_string()) + })?; + let token = Uuid::new_v4().to_string(); + + // Get authorized username + let user: DiscordUser = client + .get("https://discord.com/api/v10/users/@me") + .bearer_auth(&auth.access_token) + .send() + .await? + .json() + .await?; + + // TODO: get bot's guilds so we only save users who are able to use the bot + let discord_guilds: Vec = client + .get("https://discord.com/api/v10/users/@me/guilds") + .bearer_auth(&auth.access_token) + .send() + .await? + .json() + .await + .map_err(|err| Error::Auth(err.to_string()))?; + + let mut settings = state.settings.lock().await; + let mut in_a_guild = false; + for g in settings.guilds.iter_mut() { + let Some(discord_guild) = discord_guilds + .iter() + .find(|discord_guild| discord_guild.id == g.0.to_string()) + else { + continue; + }; + + in_a_guild = true; + + if !g.1.users.contains_key(&user.username) { + g.1.users.insert( + user.username.clone(), + GuildUser { + permissions: if discord_guild.owner { + auth::Permissions(auth::Permission::all()) + } else { + Default::default() + }, + }, + ); + } + } + + if !in_a_guild { + return Err(Error::NoGuildFound); + } + + settings.auth_users.insert( + token.clone(), + auth::User { + auth, + name: user.username.clone(), + }, + ); + // TODO: add permissions based on roles + + let mut cookie = Cookie::new("access_token", token.clone()); + cookie.set_path("/"); + cookie.set_secure(true); + + Ok((jar.add(cookie), Redirect::to("/"))) +} + pub(crate) async fn auth( - State(state): State>, + State(state): State, Query(params): Query>, ) -> Result, Error> { let Some(code) = params.get("code") else { @@ -179,7 +284,10 @@ pub(crate) async fn auth( for g in settings.guilds.iter_mut() { let Some(discord_guild) = discord_guilds .iter() - .find(|discord_guild| discord_guild.id == g.0.to_string()) else { continue; }; + .find(|discord_guild| discord_guild.id == g.0.to_string()) + else { + continue; + }; in_a_guild = true; @@ -213,21 +321,118 @@ pub(crate) async fn auth( Ok(Json(json!({"token": token, "username": user.username}))) } +pub(crate) async fn v2_add_intro_to_user( + State(state): State, + Path((guild_id, channel)): Path<(u64, String)>, + user: User, + mut form_data: Multipart, +) -> HeaderMap { + let mut headers = HeaderMap::new(); + headers.insert("HX-Refresh", HeaderValue::from_static("true")); + + let mut settings = state.settings.lock().await; + + let Some(guild) = settings.guilds.get_mut(&guild_id) else { + return headers; + }; + let Some(channel) = guild.channels.get_mut(&channel) else { + return headers; + }; + let Some(channel_user) = channel.users.get_mut(&user.name) else { + return headers; + }; + + while let Ok(Some(field)) = form_data.next_field().await { + let Some(field_name) = field.name() else { + continue; + }; + + if !channel_user + .intros + .iter() + .any(|intro| intro.index == field_name) + { + channel_user.intros.push(IntroIndex { + index: field_name.to_string(), + volume: 20, + }); + } + } + + // TODO: don't save on every change + if let Err(err) = settings.save() { + error!("Failed to save config: {err:?}"); + } + + headers +} + +pub(crate) async fn v2_remove_intro_from_user( + State(state): State, + Path((guild_id, channel)): Path<(u64, String)>, + user: User, + mut form_data: Multipart, +) -> HeaderMap { + let mut headers = HeaderMap::new(); + headers.insert("HX-Refresh", HeaderValue::from_static("true")); + + let mut settings = state.settings.lock().await; + + let Some(guild) = settings.guilds.get_mut(&guild_id) else { + return headers; + }; + let Some(channel) = guild.channels.get_mut(&channel) else { + return headers; + }; + let Some(channel_user) = channel.users.get_mut(&user.name) else { + return headers; + }; + + while let Ok(Some(field)) = form_data.next_field().await { + let Some(field_name) = field.name() else { + continue; + }; + + if let Some(index) = channel_user + .intros + .iter() + .position(|intro| intro.index == field_name) + { + channel_user.intros.remove(index); + } + } + + // TODO: don't save on every change + if let Err(err) = settings.save() { + error!("Failed to save config: {err:?}"); + } + + headers +} + pub(crate) async fn add_intro_to_user( - State(state): State>, + State(state): State, headers: HeaderMap, Path((guild, channel, intro_index)): Path<(u64, String, String)>, ) { let mut settings = state.settings.lock().await; - let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { return; }; + let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { + return; + }; let user = match settings.auth_users.get(token) { Some(user) => user.name.clone(), None => return, }; - let Some(guild) = settings.guilds.get_mut(&guild) else { return; }; - let Some(channel) = guild.channels.get_mut(&channel) else { return; }; - let Some(user) = channel.users.get_mut(&user) else { return; }; + let Some(guild) = settings.guilds.get_mut(&guild) else { + return; + }; + let Some(channel) = guild.channels.get_mut(&channel) else { + return; + }; + let Some(user) = channel.users.get_mut(&user) else { + return; + }; if !user.intros.iter().any(|intro| intro.index == intro_index) { user.intros.push(IntroIndex { @@ -243,20 +448,28 @@ pub(crate) async fn add_intro_to_user( } pub(crate) async fn remove_intro_to_user( - State(state): State>, + State(state): State, headers: HeaderMap, Path((guild, channel, intro_index)): Path<(u64, String, String)>, ) { let mut settings = state.settings.lock().await; - let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { return; }; + let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { + return; + }; let user = match settings.auth_users.get(token) { Some(user) => user.name.clone(), None => return, }; - let Some(guild) = settings.guilds.get_mut(&guild) else { return; }; - let Some(channel) = guild.channels.get_mut(&channel) else { return; }; - let Some(user) = channel.users.get_mut(&user) else { return; }; + let Some(guild) = settings.guilds.get_mut(&guild) else { + return; + }; + let Some(channel) = guild.channels.get_mut(&channel) else { + return; + }; + let Some(user) = channel.users.get_mut(&user) else { + return; + }; if let Some(index) = user .intros @@ -272,22 +485,23 @@ pub(crate) async fn remove_intro_to_user( } } -pub(crate) async fn intros( - State(state): State>, - Path(guild): Path, -) -> Json { +pub(crate) async fn intros(State(state): State, Path(guild): Path) -> Json { let settings = state.settings.lock().await; - let Some(guild) = settings.guilds.get(&guild) else { return Json(json!(IntroResponse::NoGuildFound)); }; + let Some(guild) = settings.guilds.get(&guild) else { + return Json(json!(IntroResponse::NoGuildFound)); + }; Json(json!(IntroResponse::Intros(&guild.intros))) } pub(crate) async fn me( - State(state): State>, + State(state): State, headers: HeaderMap, ) -> Result, Error> { let mut settings = state.settings.lock().await; - let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { return Err(Error::NoUserFound); }; + let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { + return Err(Error::NoUserFound); + }; let (username, access_token) = match settings.auth_users.get(token) { Some(user) => (user.name.clone(), user.auth.access_token.clone()), @@ -340,7 +554,7 @@ pub(crate) async fn me( } pub(crate) async fn upload_guild_intro( - State(state): State>, + State(state): State, Path(guild): Path, Query(mut params): Query>, headers: HeaderMap, @@ -348,23 +562,33 @@ pub(crate) async fn upload_guild_intro( ) -> Result<(), Error> { let mut settings = state.settings.lock().await; - let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { return Err(Error::NoUserFound); }; - let Some(friendly_name) = params.remove("name") else { return Err(Error::InvalidRequest); }; + let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { + return Err(Error::NoUserFound); + }; + let Some(friendly_name) = params.remove("name") else { + return Err(Error::InvalidRequest); + }; { - let Some(guild) = settings.guilds.get(&guild) else { return Err(Error::NoGuildFound); }; + let Some(guild) = settings.guilds.get(&guild) else { + return Err(Error::NoGuildFound); + }; let auth_user = match settings.auth_users.get(token) { Some(user) => user, None => return Err(Error::NoUserFound), }; - let Some(guild_user) = guild.users.get(&auth_user.name) else { return Err(Error::NoUserFound) }; + let Some(guild_user) = guild.users.get(&auth_user.name) else { + return Err(Error::NoUserFound); + }; if !guild_user.permissions.can(auth::Permission::UploadSounds) { return Err(Error::InvalidPermission); } } - let Some(guild) = settings.guilds.get_mut(&guild) else { return Err(Error::NoGuildFound); }; + let Some(guild) = settings.guilds.get_mut(&guild) else { + return Err(Error::NoGuildFound); + }; let uuid = Uuid::new_v4().to_string(); let temp_path = format!("./sounds/temp/{uuid}"); let dest_path = format!("./sounds/{uuid}.mp3"); @@ -386,31 +610,43 @@ pub(crate) async fn upload_guild_intro( } pub(crate) async fn add_guild_intro( - State(state): State>, + State(state): State, Path(guild): Path, Query(mut params): Query>, headers: HeaderMap, ) -> Result<(), Error> { let mut settings = state.settings.lock().await; // TODO: make this an impl on HeaderMap - let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { return Err(Error::NoUserFound); }; - let Some(url) = params.remove("url") else { return Err(Error::InvalidRequest); }; - let Some(friendly_name) = params.remove("name") else { return Err(Error::InvalidRequest); }; + let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { + return Err(Error::NoUserFound); + }; + let Some(url) = params.remove("url") else { + return Err(Error::InvalidRequest); + }; + let Some(friendly_name) = params.remove("name") else { + return Err(Error::InvalidRequest); + }; { - let Some(guild) = settings.guilds.get(&guild) else { return Err(Error::NoGuildFound); }; + let Some(guild) = settings.guilds.get(&guild) else { + return Err(Error::NoGuildFound); + }; let auth_user = match settings.auth_users.get(token) { Some(user) => user, None => return Err(Error::NoUserFound), }; - let Some(guild_user) = guild.users.get(&auth_user.name) else { return Err(Error::NoUserFound) }; + let Some(guild_user) = guild.users.get(&auth_user.name) else { + return Err(Error::NoUserFound); + }; if !guild_user.permissions.can(auth::Permission::UploadSounds) { return Err(Error::InvalidPermission); } } - let Some(guild) = settings.guilds.get_mut(&guild) else { return Err(Error::NoGuildFound); }; + let Some(guild) = settings.guilds.get_mut(&guild) else { + return Err(Error::NoGuildFound); + }; let uuid = Uuid::new_v4().to_string(); let child = tokio::process::Command::new("yt-dlp") @@ -439,29 +675,37 @@ pub(crate) async fn add_guild_intro( } pub(crate) async fn delete_guild_intro( - State(state): State>, + State(state): State, Path(guild): Path, headers: HeaderMap, Json(body): Json, ) -> Result<(), Error> { let mut settings = state.settings.lock().await; // TODO: make this an impl on HeaderMap - let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { return Err(Error::NoUserFound); }; + let Some(token) = headers.get("token").and_then(|v| v.to_str().ok()) else { + return Err(Error::NoUserFound); + }; { - let Some(guild) = settings.guilds.get(&guild) else { return Err(Error::NoGuildFound); }; + let Some(guild) = settings.guilds.get(&guild) else { + return Err(Error::NoGuildFound); + }; let auth_user = match settings.auth_users.get(token) { Some(user) => user, None => return Err(Error::NoUserFound), }; - let Some(guild_user) = guild.users.get(&auth_user.name) else { return Err(Error::NoUserFound) }; + let Some(guild_user) = guild.users.get(&auth_user.name) else { + return Err(Error::NoUserFound); + }; if !guild_user.permissions.can(auth::Permission::DeleteSounds) { return Err(Error::InvalidPermission); } } - let Some(guild) = settings.guilds.get_mut(&guild) else { return Err(Error::NoGuildFound); }; + let Some(guild) = settings.guilds.get_mut(&guild) else { + return Err(Error::NoGuildFound); + }; // Remove intro from any users for channel in guild.channels.iter_mut() { diff --git a/src/settings.rs b/src/settings.rs index e9ca564..9ef1a19 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,6 +1,8 @@ use std::{collections::HashMap, sync::Arc}; use crate::auth; +use axum::{async_trait, extract::FromRequestParts, http::request::Parts, response::Redirect}; +use axum_extra::extract::CookieJar; use serde::{Deserialize, Serialize}; use serenity::prelude::TypeMapKey; use tracing::trace; @@ -8,12 +10,36 @@ use uuid::Uuid; type UserToken = String; +// TODO: make this is wrapped type so cloning isn't happening +#[derive(Clone)] pub(crate) struct ApiState { pub settings: Arc>, pub secrets: auth::DiscordSecret, pub origin: String, } +#[async_trait] +impl FromRequestParts for crate::auth::User { + type Rejection = Redirect; + + async fn from_request_parts( + Parts { headers, .. }: &mut Parts, + state: &ApiState, + ) -> Result { + let jar = CookieJar::from_headers(&headers); + + if let Some(token) = jar.get("access_token") { + match state.settings.lock().await.auth_users.get(token.value()) { + // :vomit: + Some(user) => Ok(user.clone()), + None => Err(Redirect::to("/login")), + } + } else { + Err(Redirect::to("/login")) + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct Settings { @@ -70,12 +96,25 @@ pub(crate) struct GuildUser { pub(crate) permissions: auth::Permissions, } +pub(crate) trait IntroFriendlyName { + fn friendly_name(&self) -> &str; +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) enum Intro { File(FileIntro), Online(OnlineIntro), } +impl IntroFriendlyName for Intro { + fn friendly_name(&self) -> &str { + match self { + Self::File(intro) => intro.friendly_name(), + Self::Online(intro) => intro.friendly_name(), + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct FileIntro { @@ -83,6 +122,12 @@ pub(crate) struct FileIntro { pub(crate) friendly_name: String, } +impl IntroFriendlyName for FileIntro { + fn friendly_name(&self) -> &str { + &self.friendly_name + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct OnlineIntro { @@ -90,6 +135,12 @@ pub(crate) struct OnlineIntro { pub(crate) friendly_name: String, } +impl IntroFriendlyName for OnlineIntro { + fn friendly_name(&self) -> &str { + &self.friendly_name + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct ChannelSettings {