diff --git a/.idea/labrinth.iml b/.idea/labrinth.iml index 5faf0f4e..280681b7 100644 --- a/.idea/labrinth.iml +++ b/.idea/labrinth.iml @@ -1,6 +1,7 @@ - + + @@ -144,6 +145,7 @@ + diff --git a/Cargo.lock b/Cargo.lock index 40237625..b2028f8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,13 +4,14 @@ version = 3 [[package]] name = "actix" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f728064aca1c318585bf4bb04ffcfac9e75e508ab4e8b1bd9ba5dfe04e2cbed5" +checksum = "cba56612922b907719d4a01cf11c8d5b458e7d3dba946d0435f20f58d6795ed2" dependencies = [ + "actix-macros", "actix-rt", "actix_derive", - "bitflags 1.3.2", + "bitflags 2.4.0", "bytes", "crossbeam-channel", "futures-core", @@ -92,7 +93,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash 0.8.3", - "base64 0.21.2", + "base64 0.21.4", "bitflags 2.4.0", "brotli", "bytes", @@ -112,29 +113,29 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rand", - "sha1 0.10.5", + "sha1 0.10.6", "smallvec", "tokio", "tokio-util", "tracing", - "zstd 0.12.3+zstd.1.5.2", + "zstd 0.12.4", ] [[package]] name = "actix-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "actix-multipart" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee489e3c01eae4d1c35b03c4493f71cb40d93f66b14558feb1b1a807671cc4e" +checksum = "3b960e2aea75f49c8f069108063d12a48d329fc8b60b786dfc7552a9d5918d2d" dependencies = [ "actix-multipart-derive", "actix-utils", @@ -157,15 +158,15 @@ dependencies = [ [[package]] name = "actix-multipart-derive" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ec592f234db8a253cf80531246a4407c8a70530423eea80688a6c5a44a110e7" +checksum = "0a0a77f836d869f700e5b47ac7c3c8b9c8bc82e4aec861954c6198abee3ebd4d" dependencies = [ - "darling 0.14.4", + "darling 0.20.3", "parse-size", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] @@ -183,9 +184,9 @@ dependencies = [ [[package]] name = "actix-rt" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" +checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" dependencies = [ "actix-macros", "futures-core", @@ -194,9 +195,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" +checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" dependencies = [ "actix-rt", "actix-service", @@ -204,8 +205,7 @@ dependencies = [ "futures-core", "futures-util", "mio", - "num_cpus", - "socket2", + "socket2 0.5.4", "tokio", "tracing", ] @@ -233,9 +233,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.3.1" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96" +checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" dependencies = [ "actix-codec", "actix-http", @@ -246,16 +246,15 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.7.6", + "ahash 0.8.3", "bytes", "bytestring", - "cfg-if 1.0.0", + "cfg-if", "cookie", "derive_more", "encoding_rs", "futures-core", "futures-util", - "http", "itoa", "language-tags", "log", @@ -267,21 +266,21 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2", - "time 0.3.22", + "socket2 0.5.4", + "time", "url", ] [[package]] name = "actix-web-codegen" -version = "4.2.0" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2262160a7ae29e3415554a3f1fc04c764b1540c116aa524683208078b7a75bc9" +checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] @@ -312,20 +311,20 @@ dependencies = [ [[package]] name = "actix_derive" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7" +checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -342,7 +341,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cipher", "cpufeatures", ] @@ -364,7 +363,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "getrandom", "once_cell", "version_check", @@ -372,9 +371,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -396,9 +395,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "android-tzdata" @@ -417,12 +416,13 @@ dependencies = [ [[package]] name = "argon2" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95c2fcf79ad1932ac6269a738109997a83c227c09b75842ae564dc8ede6a861c" +checksum = "17ba4cac0a46bc1d2912652a751c47f2a9f3a7fe89bcae2275d418f5270402f9" dependencies = [ "base64ct", "blake2", + "cpufeatures", "password-hash 0.5.0", ] @@ -438,18 +438,6 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" -[[package]] -name = "as-slice" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0" -dependencies = [ - "generic-array 0.12.4", - "generic-array 0.13.3", - "generic-array 0.14.7", - "stable_deref_trait", -] - [[package]] name = "askama_escape" version = "0.10.3" @@ -458,9 +446,9 @@ checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" [[package]] name = "async-channel" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", "event-listener", @@ -469,13 +457,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -520,7 +508,7 @@ dependencies = [ "rust-ini", "serde", "thiserror", - "time 0.3.22", + "time", "url", ] @@ -535,13 +523,13 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", @@ -562,9 +550,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64ct" @@ -641,7 +629,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -650,7 +638,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -700,9 +688,9 @@ dependencies = [ [[package]] name = "brotli" -version = "3.3.4" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -711,9 +699,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.4" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -721,31 +709,18 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" dependencies = [ "memchr", ] -[[package]] -name = "build_id" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6deb6795d8b4d2269c3fcf87a87bff9f4cd45a99e259806603ee8007077daf3" -dependencies = [ - "byteorder", - "once_cell", - "palaver", - "twox-hash", - "uuid 0.8.2", -] - [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" @@ -771,21 +746,21 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "bytestring" @@ -825,11 +800,12 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -841,12 +817,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -855,18 +825,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] @@ -881,9 +850,9 @@ dependencies = [ [[package]] name = "clickhouse" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33816ee1fea4f60d97abfeb773b9b566ae85f8bfa891758d00a1fb1e5a606591" +checksum = "a0875e527e299fc5f4faba42870bf199a39ab0bb2dbba1b8aef0a2151451130f" dependencies = [ "bstr", "bytes", @@ -897,10 +866,10 @@ dependencies = [ "serde", "static_assertions", "thiserror", - "time 0.3.22", + "time", "tokio", "url", - "uuid 1.4.0", + "uuid", ] [[package]] @@ -955,9 +924,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" dependencies = [ "crossbeam-utils", ] @@ -996,7 +965,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.22", + "time", "version_check", ] @@ -1046,7 +1015,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1055,7 +1024,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -1065,7 +1034,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] @@ -1077,7 +1046,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", "memoffset", "scopeguard", @@ -1089,7 +1058,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", ] @@ -1099,7 +1068,7 @@ version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1114,7 +1083,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "typenum", ] @@ -1124,7 +1093,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.7", + "generic-array", "subtle", ] @@ -1139,15 +1108,15 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "socket2", + "socket2 0.4.9", "winapi", ] [[package]] name = "curl-sys" -version = "0.4.63+curl-8.1.2" +version = "0.4.67+curl-8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc" +checksum = "3cc35d066510b197a0f72de863736641539957628c8a42e70e27c66849e77c34" dependencies = [ "cc", "libc", @@ -1156,7 +1125,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "winapi", + "windows-sys", ] [[package]] @@ -1171,12 +1140,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core 0.20.1", - "darling_macro 0.20.1", + "darling_core 0.20.3", + "darling_macro 0.20.3", ] [[package]] @@ -1195,16 +1164,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -1220,23 +1189,23 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "darling_core 0.20.1", + "darling_core 0.20.3", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "cfg-if 1.0.0", - "hashbrown 0.12.3", + "cfg-if", + "hashbrown 0.14.1", "lock_api", "once_cell", "parking_lot_core 0.9.8", @@ -1267,9 +1236,9 @@ dependencies = [ [[package]] name = "deadpool-runtime" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1" +checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" dependencies = [ "tokio", ] @@ -1281,7 +1250,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ "serde", - "uuid 1.4.0", + "uuid", +] + +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +dependencies = [ + "serde", ] [[package]] @@ -1335,7 +1313,7 @@ dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version", "syn 1.0.109", ] @@ -1345,7 +1323,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -1393,9 +1371,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" dependencies = [ "serde", ] @@ -1406,7 +1384,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "memchr", ] @@ -1418,11 +1396,11 @@ checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -1439,24 +1417,19 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "errno" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "cc", "libc", + "windows-sys", ] [[package]] @@ -1467,9 +1440,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "exr" -version = "1.6.5" +version = "1.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a7b44a196573e272e0cf0bcf130281c71e9a0c67062954b3323fd364bfdac9" +checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" dependencies = [ "bit_field", "flume", @@ -1500,6 +1473,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "fdeflate" version = "0.3.0" @@ -1511,13 +1490,13 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "windows-sys", ] @@ -1533,11 +1512,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" dependencies = [ "crc32fast", "miniz_oxide", @@ -1545,14 +1530,10 @@ dependencies = [ [[package]] name = "flume" -version = "0.10.14" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", "spin 0.9.8", ] @@ -1657,7 +1638,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -1674,7 +1655,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -1713,24 +1694,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1747,11 +1710,9 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "cfg-if 1.0.0", - "js-sys", + "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", + "wasi", ] [[package]] @@ -1766,15 +1727,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -1782,7 +1743,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -1798,15 +1759,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hash32" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -1827,9 +1779,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" dependencies = [ "ahash 0.8.3", "allocator-api2", @@ -1837,23 +1789,11 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" -dependencies = [ - "hashbrown 0.14.0", -] - -[[package]] -name = "heapless" -version = "0.5.6" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "as-slice", - "generic-array 0.13.3", - "hash32", - "stable_deref_trait", + "hashbrown 0.14.1", ] [[package]] @@ -1876,9 +1816,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1961,9 +1901,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -1988,7 +1928,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -2065,9 +2005,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "image" -version = "0.24.6" +version = "0.24.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" dependencies = [ "bytemuck", "byteorder", @@ -2093,13 +2033,24 @@ dependencies = [ "serde", ] +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.1", + "serde", +] + [[package]] name = "inout" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -2108,18 +2059,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", + "cfg-if", ] [[package]] @@ -2144,7 +2084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.3", + "rustix", "windows-sys", ] @@ -2204,15 +2144,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] @@ -2241,8 +2181,8 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.2", - "ring", + "base64 0.21.4", + "ring 0.16.20", "serde", "serde_json", ] @@ -2262,8 +2202,8 @@ dependencies = [ "actix-ws", "argon2", "async-trait", - "base64 0.21.2", - "bitflags 1.3.2", + "base64 0.21.4", + "bitflags 2.4.0", "bytes", "censor", "chrono", @@ -2311,7 +2251,7 @@ dependencies = [ "totp-rs", "url", "urlencoding", - "uuid 1.4.0", + "uuid", "validator", "woothee", "xml-rs", @@ -2345,10 +2285,10 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76bd09637ae3ec7bd605b8e135e757980b3968430ff2b1a4a94fb7769e50166d" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "email-encoding", "email_address", - "fastrand", + "fastrand 1.9.0", "futures-util", "hostname", "httpdate", @@ -2358,7 +2298,7 @@ dependencies = [ "nom 7.1.3", "once_cell", "quoted_printable", - "socket2", + "socket2 0.4.9", "tokio", ] @@ -2370,22 +2310,22 @@ checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec 0.5.2", "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "ryu", "static_assertions", ] [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libnghttp2-sys" -version = "0.1.7+1.45.0" +version = "0.1.8+1.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f" +checksum = "4fae956c192dadcdb5dace96db71fa0b827333cce7c7b38dc71446f024d8a340" dependencies = [ "cc", "libc", @@ -2393,9 +2333,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.9" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" dependencies = [ "cc", "libc", @@ -2411,25 +2351,18 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - -[[package]] -name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "local-channel" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" +checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" dependencies = [ "futures-core", "futures-sink", - "futures-util", "local-waker", ] @@ -2451,9 +2384,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru-cache" @@ -2484,15 +2417,6 @@ dependencies = [ "libc", ] -[[package]] -name = "mach" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" -dependencies = [ - "libc", -] - [[package]] name = "match_cfg" version = "0.1.0" @@ -2524,10 +2448,11 @@ dependencies = [ [[package]] name = "md-5" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ + "cfg-if", "digest 0.10.7", ] @@ -2568,8 +2493,8 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.22", - "uuid 1.4.0", + "time", + "uuid", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2578,18 +2503,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memmap2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" -dependencies = [ - "libc", -] +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -2649,19 +2565,10 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", -] - [[package]] name = "native-tls" version = "0.2.11" @@ -2680,37 +2587,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nix" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" -dependencies = [ - "bitflags 1.3.2", - "cc", - "cfg-if 0.1.10", - "libc", - "void", -] - -[[package]] -name = "nix" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" -dependencies = [ - "bitflags 1.3.2", - "cfg-if 1.0.0", - "libc", - "static_assertions", -] - -[[package]] -name = "nom" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" - [[package]] name = "nom" version = "5.1.3" @@ -2734,9 +2610,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -2766,9 +2642,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -2785,9 +2661,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -2812,12 +2688,12 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", - "cfg-if 1.0.0", + "bitflags 2.4.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -2833,7 +2709,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -2844,9 +2720,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -2875,28 +2751,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "palaver" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49dfc200733ac34dcd9a1e4a7e454b521723936010bef3710e2d8024a32d685f" -dependencies = [ - "bitflags 1.3.2", - "heapless", - "lazy_static", - "libc", - "mach", - "nix 0.15.0", - "procinfo", - "typenum", - "winapi", -] - [[package]] name = "parking" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" [[package]] name = "parking_lot" @@ -2925,7 +2784,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", "redox_syscall 0.2.16", @@ -2939,7 +2798,7 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall 0.3.5", "smallvec", @@ -2976,9 +2835,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pbkdf2" @@ -2989,7 +2848,7 @@ dependencies = [ "digest 0.10.7", "hmac 0.12.1", "password-hash 0.4.2", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -3000,14 +2859,14 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "phonenumber" -version = "0.3.2+8.13.9" +version = "0.3.3+8.13.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34749f64ea9d76f10cdc8a859588b57775f59177c7dd91f744d620bd62982d6f" +checksum = "635f3e6288e4f01c049d89332a031bd74f25d64b6fb94703ca966e819488cd06" dependencies = [ "bincode", "either", "fnv", - "itertools 0.10.5", + "itertools 0.11.0", "lazy_static", "nom 7.1.3", "quick-xml 0.28.2", @@ -3015,34 +2874,35 @@ dependencies = [ "regex-cache", "serde", "serde_derive", + "strum", "thiserror", ] [[package]] name = "pin-project" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -3058,9 +2918,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "png" -version = "0.17.9" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3077,7 +2937,7 @@ checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg", "bitflags 1.3.2", - "cfg-if 1.0.0", + "cfg-if", "concurrent-queue", "libc", "log", @@ -3085,26 +2945,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "pprof" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196ded5d4be535690899a4631cc9f18cdc41b7ebf24a79400f46f48e49a11059" -dependencies = [ - "backtrace", - "cfg-if 1.0.0", - "findshlibs", - "libc", - "log", - "nix 0.26.2", - "once_cell", - "parking_lot 0.12.1", - "smallvec", - "symbolic-demangle", - "tempfile", - "thiserror", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -3146,32 +2986,20 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] -[[package]] -name = "procinfo" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab1427f3d2635891f842892dda177883dca0639e05fe66796a62c9d2f23b49c" -dependencies = [ - "byteorder", - "libc", - "nom 2.2.1", - "rustc_version 0.2.3", -] - [[package]] name = "prometheus" version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "fnv", "lazy_static", "memchr", @@ -3235,9 +3063,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -3297,9 +3125,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -3307,21 +3135,19 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redis" -version = "0.23.0" +version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea8c51b5dc1d8e5fd3350ec8167f464ec0995e79f2e90a075b63371500d557f" +checksum = "4f49cdc0bb3f412bf8e7d1bd90fe1d9eb10bc5c399ba90973c14662a27b3f8ba" dependencies = [ "ahash 0.7.6", "async-trait", @@ -3334,6 +3160,7 @@ dependencies = [ "r2d2", "ryu", "sha1_smol", + "socket2 0.4.9", "tokio", "tokio-util", "url", @@ -3370,25 +3197,25 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.7.3", + "regex-syntax 0.8.0", ] [[package]] name = "regex-automata" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaecc05d5c4b5f7da074b9a0d1a0867e71fd36e7fc0482d8bcfe8e8fc56290" +checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.3", + "regex-syntax 0.8.0", ] [[package]] @@ -3411,26 +3238,26 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" [[package]] name = "rend" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -3452,6 +3279,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", "tokio-util", @@ -3489,11 +3317,25 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + [[package]] name = "rkyv" version = "0.7.42" @@ -3508,7 +3350,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid 1.4.0", + "uuid", ] [[package]] @@ -3528,7 +3370,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "ordered-multimap", ] @@ -3543,7 +3385,7 @@ dependencies = [ "aws-region", "base64 0.13.1", "bytes", - "cfg-if 1.0.0", + "cfg-if", "futures", "hex", "hmac 0.12.1", @@ -3557,9 +3399,9 @@ dependencies = [ "reqwest", "serde", "serde_derive", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", - "time 0.3.22", + "time", "tokio", "tokio-stream", "url", @@ -3567,14 +3409,12 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.30.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0446843641c69436765a35a5a77088e28c2e6a12da93e84aa3ab1cd4aa5a042" +checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd" dependencies = [ "arrayvec 0.7.4", "borsh", - "bytecheck", - "byteorder", "bytes", "num-traits", "rand", @@ -3589,69 +3429,36 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.17", -] - -[[package]] -name = "rustc_version_runtime" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d31b7153270ebf48bf91c65ae5b0c00e749c4cfad505f66530ac74950249582f" -dependencies = [ - "rustc_version 0.2.3", - "semver 0.9.0", -] - -[[package]] -name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys", + "semver", ] [[package]] name = "rustix" -version = "0.38.3" +version = "0.38.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys", ] [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", - "ring", + "ring 0.16.20", "sct", "webpki", ] @@ -3662,9 +3469,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "rxml" version = "0.9.1" @@ -3684,9 +3497,9 @@ checksum = "22a197350ece202f19a166d1ad6d9d6de145e1d2a8ef47db299abe164dbd7530" [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schannel" @@ -3708,9 +3521,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" @@ -3718,8 +3531,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -3742,9 +3555,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -3755,9 +3568,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -3765,30 +3578,15 @@ dependencies = [ [[package]] name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" - -[[package]] -name = "semver-parser" -version = "0.7.0" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "sentry" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b0ad16faa5d12372f914ed40d00bda21a6d1bdcc99264c5e5e1c9495cf3654" +checksum = "0097a48cd1999d983909f07cb03b15241c5af29e5e679379efac1c06296abecc" dependencies = [ "httpdate", "native-tls", @@ -3805,9 +3603,9 @@ dependencies = [ [[package]] name = "sentry-actix" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f81ee4dfb8e109fd99f0eb036fec548e66fd1db17a0224304c4a31ab0749ef" +checksum = "856a0131ca91c402aba7ce3b4f199b4fabc0b2d2b7fe0e8fdeac2a131ae75126" dependencies = [ "actix-web", "futures-util", @@ -3816,9 +3614,9 @@ dependencies = [ [[package]] name = "sentry-backtrace" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f2ee8f147bb5f22ac59b5c35754a759b9a6f6722402e2a14750b2a63fc59bd" +checksum = "18a7b80fa1dd6830a348d38a8d3a9761179047757b7dca29aef82db0118b9670" dependencies = [ "backtrace", "once_cell", @@ -3828,44 +3626,36 @@ dependencies = [ [[package]] name = "sentry-contexts" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcd133362c745151eeba0ac61e3ba8350f034e9fe7509877d08059fe1d7720c6" +checksum = "7615dc588930f1fd2e721774f25844ae93add2dbe2d3c2f995ce5049af898147" dependencies = [ "hostname", "libc", "os_info", - "rustc_version 0.4.0", + "rustc_version", "sentry-core", "uname", ] [[package]] name = "sentry-core" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7163491708804a74446642ff2c80b3acd668d4b9e9f497f85621f3d250fd012b" +checksum = "8f51264e4013ed9b16558cce43917b983fa38170de2ca480349ceb57d71d6053" dependencies = [ - "build_id", - "findshlibs", - "indexmap", - "libc", "once_cell", - "pprof", "rand", - "rustc_version_runtime", "sentry-types", "serde", "serde_json", - "sys-info", - "uuid 1.4.0", ] [[package]] name = "sentry-debug-images" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5003d7ff08aa3b2b76994080b183e8cfa06c083e280737c9cee02ca1c70f5e" +checksum = "2fe6180fa564d40bb942c9f0084ffb5de691c7357ead6a2b7a3154fae9e401dd" dependencies = [ "findshlibs", "once_cell", @@ -3874,9 +3664,9 @@ dependencies = [ [[package]] name = "sentry-panic" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4dfe8371c9b2e126a8b64f6fefa54cef716ff2a50e63b5558a48b899265bccd" +checksum = "323160213bba549f9737317b152af116af35c0410f4468772ee9b606d3d6e0fa" dependencies = [ "sentry-backtrace", "sentry-core", @@ -3884,9 +3674,9 @@ dependencies = [ [[package]] name = "sentry-tracing" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca8b88978677a27ee1a91beafe4052306c474c06f582321fde72d2e2cc2f7f" +checksum = "38033822128e73f7b6ca74c1631cef8868890c6cb4008a291cf73530f87b4eac" dependencies = [ "sentry-backtrace", "sentry-core", @@ -3896,39 +3686,39 @@ dependencies = [ [[package]] name = "sentry-types" -version = "0.31.5" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e7a88e0c1922d19b3efee12a8215f6a8a806e442e665ada71cc222cab72985f" +checksum = "0e663b3eb62ddfc023c9cf5432daf5f1a4f6acb1df4d78dd80b740b32dd1a740" dependencies = [ "debugid", - "getrandom", "hex", + "rand", "serde", "serde_json", "thiserror", - "time 0.3.22", + "time", "url", - "uuid 1.4.0", + "uuid", ] [[package]] name = "serde" -version = "1.0.167" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.167" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -3944,9 +3734,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -3955,9 +3745,9 @@ dependencies = [ [[package]] name = "serde_plain" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" dependencies = [ "serde", ] @@ -3976,30 +3766,31 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.0.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513" +checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", + "indexmap 2.0.2", "serde", "serde_json", "serde_with_macros", - "time 0.3.22", + "time", ] [[package]] name = "serde_with_macros" -version = "3.0.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070" +checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" dependencies = [ - "darling 0.20.1", + "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -4013,11 +3804,11 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.10.7", ] @@ -4035,7 +3826,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.9.0", "opaque-debug", @@ -4043,11 +3834,11 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.10.7", ] @@ -4063,9 +3854,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "simdutf8" @@ -4075,9 +3866,9 @@ checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -4095,9 +3886,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smartstring" @@ -4120,11 +3911,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spdx" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2971cb691ca629f46174f73b1f95356c5617f89b4167f04107167c3dccb8dd89" +checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71" dependencies = [ "smallvec", ] @@ -4146,11 +3947,11 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" dependencies = [ - "itertools 0.10.5", + "itertools 0.11.0", "nom 7.1.3", "unicode_categories", ] @@ -4192,7 +3993,7 @@ dependencies = [ "hex", "hkdf", "hmac 0.12.1", - "indexmap", + "indexmap 1.9.3", "itoa", "libc", "log", @@ -4208,8 +4009,8 @@ dependencies = [ "rustls-pemfile", "serde", "serde_json", - "sha1 0.10.5", - "sha2 0.10.7", + "sha1 0.10.6", + "sha2 0.10.8", "smallvec", "sqlformat", "sqlx-rt", @@ -4236,7 +4037,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "sqlx-core", "sqlx-rt", "syn 1.0.109", @@ -4254,12 +4055,6 @@ dependencies = [ "tokio-rustls", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static_assertions" version = "1.1.0" @@ -4268,10 +4063,11 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" dependencies = [ + "finl_unicode", "unicode-bidi", "unicode-normalization", ] @@ -4283,32 +4079,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] -name = "subtle" -version = "2.4.1" +name = "strum" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] [[package]] -name = "symbolic-common" -version = "10.2.1" +name = "strum_macros" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b55cdc318ede251d0957f07afe5fed912119b8c1bc5a7804151826db999e737" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "debugid", - "memmap2", - "stable_deref_trait", - "uuid 1.4.0", + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", ] [[package]] -name = "symbolic-demangle" -version = "10.2.1" +name = "subtle" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79be897be8a483a81fff6a3a4e195b4ac838ef73ca42d348b3f722da9902e489" -dependencies = [ - "rustc-demangle", - "symbolic-common", -] +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" @@ -4323,9 +4119,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -4333,12 +4129,23 @@ dependencies = [ ] [[package]] -name = "sys-info" -version = "0.9.1" +name = "system-configuration" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "cc", + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", "libc", ] @@ -4350,9 +4157,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96d2ffad078296368d46ff1cb309be1c23c513b4ab0e22a45de0185275ac96" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" dependencies = [ "filetime", "libc", @@ -4361,52 +4168,51 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", - "cfg-if 1.0.0", - "fastrand", + "cfg-if", + "fastrand 2.0.1", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix", "windows-sys", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] name = "tiff" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" dependencies = [ "flate2", "jpeg-decoder", @@ -4415,21 +4221,11 @@ dependencies = [ [[package]] name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.22" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" dependencies = [ + "deranged", "itoa", "serde", "time-core", @@ -4438,15 +4234,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -4468,11 +4264,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", @@ -4481,7 +4276,7 @@ dependencies = [ "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.4", "tokio-macros", "windows-sys", ] @@ -4494,7 +4289,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -4531,9 +4326,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -4554,16 +4349,16 @@ dependencies = [ [[package]] name = "totp-rs" -version = "5.0.2" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad5e73765ff14ae797c1a61ee0c7beaf21b4e4a0047844300e332c6c24df1fc" +checksum = "df3504f96adf86d28e7eb16fa236a7951ec72c15ee100d1b5318e225944bc8cb" dependencies = [ "base32", "constant_time_eq 0.2.6", "hmac 0.12.1", "rand", - "sha1 0.10.5", - "sha2 0.10.7", + "sha1 0.10.6", + "sha2 0.10.8", ] [[package]] @@ -4578,7 +4373,7 @@ version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -4593,7 +4388,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", ] [[package]] @@ -4631,21 +4426,11 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "twox-hash" -version = "1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" -dependencies = [ - "cfg-if 1.0.0", - "static_assertions", -] - [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uname" @@ -4658,9 +4443,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] @@ -4673,9 +4458,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -4704,13 +4489,19 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "ureq" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9" +checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "log", "native-tls", "once_cell", @@ -4719,9 +4510,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna 0.4.0", @@ -4731,21 +4522,15 @@ dependencies = [ [[package]] name = "urlencoding" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" - -[[package]] -name = "uuid" -version = "0.8.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "uuid" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", "rand", @@ -4813,17 +4598,11 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "waker-fn" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "want" @@ -4834,12 +4613,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4852,7 +4625,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -4867,7 +4640,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", "wasm-bindgen-shared", ] @@ -4877,7 +4650,7 @@ version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -4901,7 +4674,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4914,9 +4687,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ "futures-util", "js-sys", @@ -4937,12 +4710,12 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.0" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring", - "untrusted", + "ring 0.17.3", + "untrusted 0.9.0", ] [[package]] @@ -4988,9 +4761,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -5021,9 +4794,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -5036,53 +4809,54 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys", ] [[package]] @@ -5106,18 +4880,18 @@ dependencies = [ [[package]] name = "xattr" -version = "0.2.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" dependencies = [ "libc", ] [[package]] name = "xml-rs" -version = "0.8.15" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a56c84a8ccd4258aed21c92f70c0f6dea75356b6892ae27c24139da456f9336" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" [[package]] name = "yaserde" @@ -5168,8 +4942,8 @@ dependencies = [ "flate2", "hmac 0.12.1", "pbkdf2", - "sha1 0.10.5", - "time 0.3.22", + "sha1 0.10.6", + "time", "zstd 0.11.2+zstd.1.5.2", ] @@ -5184,11 +4958,11 @@ dependencies = [ [[package]] name = "zstd" -version = "0.12.3+zstd.1.5.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" dependencies = [ - "zstd-safe 6.0.5+zstd.1.5.4", + "zstd-safe 6.0.6", ] [[package]] @@ -5203,9 +4977,9 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "6.0.5+zstd.1.5.4" +version = "6.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" dependencies = [ "libc", "zstd-sys", @@ -5244,5 +5018,5 @@ dependencies = [ "lazy_static", "quick-error", "regex", - "time 0.3.22", + "time", ] diff --git a/Cargo.toml b/Cargo.toml index 898a4ae4..819d1484 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ sha1 = { version = "0.6.1", features = ["std"] } sha2 = "0.9.9" hmac = "0.11.0" argon2 = { version = "0.5.0", features = ["std"] } -bitflags = "1.3.2" +bitflags = "2.4.0" hex = "0.4.3" zxcvbn = "2.2.2" totp-rs = { version = "5.0.2", features = ["gen_secret"] } @@ -96,7 +96,7 @@ maxminddb = "0.23.0" flate2 = "1.0.25" tar = "0.4.38" -sentry = { version = "0.31.5", features = ["profiling"] } +sentry = { version = "0.31.5" } sentry-actix = "0.31.5" image = "0.24.6" diff --git a/migrations/20230919183129_trolley.sql b/migrations/20230919183129_trolley.sql new file mode 100644 index 00000000..8dfb148f --- /dev/null +++ b/migrations/20230919183129_trolley.sql @@ -0,0 +1,16 @@ +ALTER TABLE users + ADD COLUMN trolley_id text NULL, + ADD COLUMN trolley_account_status text NULL, + DROP COLUMN midas_expires, + DROP COLUMN is_overdue, + DROP COLUMN stripe_customer_id, + DROP COLUMN payout_wallet, + DROP COLUMN payout_wallet_type, + DROP COLUMN payout_address; + +ALTER TABLE historical_payouts + ADD COLUMN batch_id text NULL, + ADD COLUMN payment_id text NULL; + +UPDATE historical_payouts +SET status = 'processed' \ No newline at end of file diff --git a/sqlx-data.json b/sqlx-data.json index 9549939c..3d99d453 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -144,25 +144,25 @@ }, "query": "\n UPDATE versions\n SET status = $1, date_published = $2\n WHERE (id = $3)\n " }, - "03284fe5b045e2cf93f160863c4d121439382b348b728fffb5ac588dee980731": { + "04128dd06489004e0d0305bfd0f4ca5ee4b4a6b9f610de6e1b9ef9c8543cc025": { "describe": { "columns": [ { - "name": "exists", + "name": "id", "ordinal": 0, - "type_info": "Bool" + "type_info": "Int8" } ], "nullable": [ - null + false ], "parameters": { "Left": [ - "Int8" + "Text" ] } }, - "query": "\n SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND email IS NULL)\n " + "query": "SELECT id FROM users WHERE trolley_id = $1" }, "04345d9c23430267f755b1420520df91bd403524fd60ba1a94e3a239ea70cae7": { "describe": { @@ -1609,6 +1609,18 @@ }, "query": "\n UPDATE mods\n SET follows = follows - 1\n WHERE id = $1\n " }, + "382753714620109f2ad1a4cacbb6f699732db321a2dcb1f9d83e57332e32357d": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Int8" + ] + } + }, + "query": "\n UPDATE users\n SET trolley_account_status = NULL, trolley_id = NULL\n WHERE id = $1\n " + }, "38429340be03cc5f539d9d14c156e6b6710051d2826b53a5ccfdbd231af964ca": { "describe": { "columns": [ @@ -1756,6 +1768,20 @@ }, "query": "\n UPDATE mods\n SET title = $1\n WHERE (id = $2)\n " }, + "3f525e05e94ccaea4abc059d54f48011517bd8997df0c7d42cc4caae62194ae6": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Int8" + ] + } + }, + "query": "\n UPDATE users\n SET trolley_id = $1, trolley_account_status = $2\n WHERE id = $3\n " + }, "40f7c5bec98fe3503d6bd6db2eae5a4edb8d5d6efda9b9dc124f344ae5c60e08": { "describe": { "columns": [], @@ -1986,20 +2012,6 @@ }, "query": "\n INSERT INTO mods_donations (\n joining_mod_id, joining_platform_id, url\n )\n SELECT * FROM UNNEST($1::bigint[], $2::int[], $3::varchar[])\n " }, - "4778d2f5994fda2f978fa53e0840c1a9a2582ef0434a5ff7f21706f1dc4edcf4": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Numeric", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO historical_payouts (user_id, amount, status)\n VALUES ($1, $2, $3)\n " - }, "4838777a8ef4371f4f5bb4f4f038bb6d041455f0849a3972a5418d75165ae9c7": { "describe": { "columns": [ @@ -2032,6 +2044,22 @@ }, "query": "\n SELECT d.dependency_id, COALESCE(vd.mod_id, 0) mod_id, d.mod_dependency_id\n FROM versions v\n INNER JOIN dependencies d ON d.dependent_id = v.id\n LEFT JOIN versions vd ON d.dependency_id = vd.id\n WHERE v.mod_id = $1\n " }, + "48dc011567c5d50ee734fd0bdd1f5d07d9ef066c485a9b34495120c9947489f8": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Int8", + "Numeric", + "Varchar", + "Text", + "Text" + ] + } + }, + "query": "\n INSERT INTO historical_payouts (user_id, amount, status, batch_id, payment_id)\n VALUES ($1, $2, $3, $4, $5)\n " + }, "49813a96f007216072d69468aae705d73d5b85dcdd64a22060009b12d947ed5a": { "describe": { "columns": [], @@ -2706,153 +2734,6 @@ }, "query": "\n UPDATE mods_gallery\n SET ordering = $2\n WHERE id = $1\n " }, - "60a251aea1efbc7d9357255e520f0ac13f3697fecb84b1e9edd5d9ea61fe0cb0": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "email", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "avatar_url", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "username", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "bio", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "created", - "ordinal": 6, - "type_info": "Timestamptz" - }, - { - "name": "role", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "badges", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "balance", - "ordinal": 9, - "type_info": "Numeric" - }, - { - "name": "payout_wallet", - "ordinal": 10, - "type_info": "Varchar" - }, - { - "name": "payout_wallet_type", - "ordinal": 11, - "type_info": "Varchar" - }, - { - "name": "payout_address", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "github_id", - "ordinal": 13, - "type_info": "Int8" - }, - { - "name": "discord_id", - "ordinal": 14, - "type_info": "Int8" - }, - { - "name": "gitlab_id", - "ordinal": 15, - "type_info": "Int8" - }, - { - "name": "google_id", - "ordinal": 16, - "type_info": "Varchar" - }, - { - "name": "steam_id", - "ordinal": 17, - "type_info": "Int8" - }, - { - "name": "microsoft_id", - "ordinal": 18, - "type_info": "Varchar" - }, - { - "name": "email_verified", - "ordinal": 19, - "type_info": "Bool" - }, - { - "name": "password", - "ordinal": 20, - "type_info": "Text" - }, - { - "name": "totp_secret", - "ordinal": 21, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - true, - true, - true, - false, - true, - false, - false, - false, - false, - true, - true, - true, - true, - true, - true, - true, - true, - true, - false, - true, - true - ], - "parameters": { - "Left": [ - "Int8Array", - "TextArray" - ] - } - }, - "query": "\n SELECT id, name, email,\n avatar_url, username, bio,\n created, role, badges,\n balance, payout_wallet, payout_wallet_type, payout_address,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n " - }, "61a7f29e024bf2f1368370e3f6e8ef70317c7e8545b5b6d4235f21164948ba27": { "describe": { "columns": [], @@ -3953,20 +3834,20 @@ }, "query": "\n SELECT tm.id, tm.team_id, tm.user_id, tm.role, tm.permissions, tm.organization_permissions, tm.accepted, tm.payouts_split, tm.ordering, v.mod_id \n FROM versions v\n INNER JOIN mods m ON m.id = v.mod_id\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.user_id = $2 AND tm.accepted = TRUE\n WHERE v.id = $1\n " }, - "8cbd74dad7a21128d99fd32b430c2e0427480f910e1f125ff56b893c67a6e8a4": { + "8f45a48700b8836f4ba8626b25b7be7f838d35d260430a46817729d9787e2013": { "describe": { "columns": [], "nullable": [], "parameters": { "Left": [ "Varchar", - "Varchar", - "Varchar", + "Bool", + "Text", "Int8" ] } }, - "query": "\n UPDATE users\n SET payout_wallet = $1, payout_wallet_type = $2, payout_address = $3\n WHERE (id = $4)\n " + "query": "\n UPDATE users\n SET email = $1, email_verified = $2, trolley_account_status = $3\n WHERE id = $4\n " }, "8f5e2a570cf35b2d158182bac37fd40bcec277bbdeddaece5efaa88600048a70": { "describe": { @@ -4188,6 +4069,19 @@ }, "query": "SELECT EXISTS(SELECT 1 FROM reports WHERE id=$1)" }, + "9774f59e5d5ce6ba00ca7e3a4a81f80f78b908bdf664a4cdfad592a1b14c0d44": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Varchar", + "Text" + ] + } + }, + "query": "\n UPDATE historical_payouts\n SET status = $1\n WHERE payment_id = $2\n " + }, "99a1eac69d7f5a5139703df431e6a5c3012a90143a8c635f93632f04d0bc41d4": { "describe": { "columns": [], @@ -5104,18 +4998,6 @@ }, "query": "\n SELECT n.id, n.user_id, n.title, n.text, n.link, n.created, n.read, n.type notification_type, n.body,\n JSONB_AGG(DISTINCT jsonb_build_object('id', na.id, 'notification_id', na.notification_id, 'title', na.title, 'action_route_method', na.action_route_method, 'action_route', na.action_route)) filter (where na.id is not null) actions\n FROM notifications n\n LEFT OUTER JOIN notifications_actions na on n.id = na.notification_id\n WHERE n.user_id = $1\n GROUP BY n.id, n.user_id;\n " }, - "c4b167ec7452cc92be0e33f7e4f3908f0c4109291511c94909e9105fc62a432f": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET payout_wallet = NULL, payout_wallet_type = NULL, payout_address = NULL\n WHERE (id = $1)\n " - }, "c55d2132e3e6e92dd50457affab758623dca175dc27a2d3cd4aace9cfdecf789": { "describe": { "columns": [], @@ -6051,6 +5933,44 @@ }, "query": "\n UPDATE versions\n SET featured = $1\n WHERE (id = $2)\n " }, + "e5adaf219c52ec828b72bd89c6b86a475f73181abf180a024dfe05f918e58edb": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "amount", + "ordinal": 1, + "type_info": "Numeric" + }, + { + "name": "user_id", + "ordinal": 2, + "type_info": "Int8" + }, + { + "name": "status", + "ordinal": 3, + "type_info": "Varchar" + } + ], + "nullable": [ + false, + false, + false, + false + ], + "parameters": { + "Left": [ + "Text" + ] + } + }, + "query": "SELECT id, amount, user_id, status FROM historical_payouts WHERE payment_id = $1" + }, "e60ea75112db37d3e73812e21b1907716e4762e06aa883af878e3be82e3f87d3": { "describe": { "columns": [ @@ -6417,6 +6337,19 @@ }, "query": "\n INSERT INTO collections_mods (collection_id, mod_id)\n SELECT * FROM UNNEST($1::bigint[], $2::bigint[])\n ON CONFLICT DO NOTHING\n " }, + "f141cc6711123b4fe5a5d9a7337a0b009b80e5d8fbda664b8d62b1a3f38eb936": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Left": [ + "Numeric", + "Int8" + ] + } + }, + "query": "\n UPDATE users\n SET balance = balance + $1\n WHERE id = $2\n " + }, "f1525930830e17b5ee8feb796d9950dd3741131965f050840fa75423b5a54f01": { "describe": { "columns": [], @@ -6648,6 +6581,147 @@ }, "query": "\n INSERT INTO game_versions_versions (game_version_id, joining_version_id)\n SELECT * FROM UNNEST($1::integer[], $2::bigint[])\n " }, + "faec0a606ccaeb3f21c81e60a1749640b929e97db40252118fb72610df64a457": { + "describe": { + "columns": [ + { + "name": "id", + "ordinal": 0, + "type_info": "Int8" + }, + { + "name": "name", + "ordinal": 1, + "type_info": "Varchar" + }, + { + "name": "email", + "ordinal": 2, + "type_info": "Varchar" + }, + { + "name": "avatar_url", + "ordinal": 3, + "type_info": "Varchar" + }, + { + "name": "username", + "ordinal": 4, + "type_info": "Varchar" + }, + { + "name": "bio", + "ordinal": 5, + "type_info": "Varchar" + }, + { + "name": "created", + "ordinal": 6, + "type_info": "Timestamptz" + }, + { + "name": "role", + "ordinal": 7, + "type_info": "Varchar" + }, + { + "name": "badges", + "ordinal": 8, + "type_info": "Int8" + }, + { + "name": "balance", + "ordinal": 9, + "type_info": "Numeric" + }, + { + "name": "github_id", + "ordinal": 10, + "type_info": "Int8" + }, + { + "name": "discord_id", + "ordinal": 11, + "type_info": "Int8" + }, + { + "name": "gitlab_id", + "ordinal": 12, + "type_info": "Int8" + }, + { + "name": "google_id", + "ordinal": 13, + "type_info": "Varchar" + }, + { + "name": "steam_id", + "ordinal": 14, + "type_info": "Int8" + }, + { + "name": "microsoft_id", + "ordinal": 15, + "type_info": "Varchar" + }, + { + "name": "email_verified", + "ordinal": 16, + "type_info": "Bool" + }, + { + "name": "password", + "ordinal": 17, + "type_info": "Text" + }, + { + "name": "totp_secret", + "ordinal": 18, + "type_info": "Varchar" + }, + { + "name": "trolley_id", + "ordinal": 19, + "type_info": "Text" + }, + { + "name": "trolley_account_status", + "ordinal": 20, + "type_info": "Text" + } + ], + "nullable": [ + false, + true, + true, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + true, + true, + true, + true + ], + "parameters": { + "Left": [ + "Int8Array", + "TextArray" + ] + } + }, + "query": "\n SELECT id, name, email,\n avatar_url, username, bio,\n created, role, badges,\n balance,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret, trolley_id, trolley_account_status\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n " + }, "fb955ca41b95120f66c98c0b528b1db10c4be4a55e9641bb104d772e390c9bb7": { "describe": { "columns": [ diff --git a/src/auth/flows.rs b/src/auth/flows.rs index 03771312..7b54f5b1 100644 --- a/src/auth/flows.rs +++ b/src/auth/flows.rs @@ -8,7 +8,8 @@ use crate::file_hosting::FileHost; use crate::models::ids::base62_impl::{parse_base62, to_base62}; use crate::models::ids::random_base62_rng; use crate::models::pats::Scopes; -use crate::models::users::{Badges, Role}; +use crate::models::users::{Badges, RecipientStatus, Role, UserPayoutData}; +use crate::queue::payouts::{AccountUser, PayoutsQueue}; use crate::queue::session::AuthQueue; use crate::queue::socket::ActiveSockets; use crate::routes::ApiError; @@ -30,7 +31,7 @@ use serde::{Deserialize, Serialize}; use sqlx::postgres::PgPool; use std::collections::HashMap; use std::sync::Arc; -use tokio::sync::RwLock; +use tokio::sync::{Mutex, RwLock}; use validator::Validate; pub fn config(cfg: &mut ServiceConfig) { @@ -51,7 +52,8 @@ pub fn config(cfg: &mut ServiceConfig) { .service(resend_verify_email) .service(set_email) .service(verify_email) - .service(subscribe_newsletter), + .service(subscribe_newsletter) + .service(link_trolley), ); } @@ -225,9 +227,8 @@ impl TempUser { role: Role::Developer.to_string(), badges: Badges::default(), balance: Decimal::ZERO, - payout_wallet: None, - payout_wallet_type: None, - payout_address: None, + trolley_id: None, + trolley_account_status: None, } .insert(transaction) .await?; @@ -1013,7 +1014,7 @@ pub async fn auth_callback( let sockets = active_sockets.clone(); let state = state_string.clone(); - let res: Result = (|| async move { + let res: Result = async move { let flow = Flow::get(&state, &redis).await?; @@ -1175,7 +1176,7 @@ pub async fn auth_callback( } else { Err::(AuthenticationError::InvalidCredentials) } - })().await; + }.await; // Because this is callback route, if we have an error, we need to ensure we close the original socket if it exists if let Err(ref e) = res { @@ -1385,9 +1386,8 @@ pub async fn create_account_with_password( role: Role::Developer.to_string(), badges: Badges::default(), balance: Decimal::ZERO, - payout_wallet: None, - payout_wallet_type: None, - payout_address: None, + trolley_id: None, + trolley_account_status: None, } .insert(&mut transaction) .await?; @@ -2011,6 +2011,7 @@ pub async fn set_email( redis: Data, email: web::Json, session_queue: Data, + payouts_queue: Data>, ) -> Result { email .0 @@ -2064,6 +2065,17 @@ pub async fn set_email( "We need to verify your email address.", )?; + if let Some(UserPayoutData { + trolley_id: Some(trolley_id), + .. + }) = user.payout_data + { + let queue = payouts_queue.lock().await; + queue + .update_recipient_email(&trolley_id, &email.email) + .await?; + } + crate::database::models::User::clear_caches(&[(user.id.into(), None)], &redis).await?; transaction.commit().await?; @@ -2206,3 +2218,59 @@ fn send_email_verify( Some(("Verify email", &format!("{}/{}?flow={}", dotenvy::var("SITE_URL")?, dotenvy::var("SITE_VERIFY_EMAIL_PATH")?, flow))), ) } + +#[post("trolley/link")] +pub async fn link_trolley( + req: HttpRequest, + pool: Data, + redis: Data, + session_queue: Data, + payouts_queue: Data>, + body: web::Json, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::PAYOUTS_WRITE]), + ) + .await? + .1; + + if let Some(payout_data) = user.payout_data { + if payout_data.trolley_id.is_some() { + return Err(ApiError::InvalidInput( + "User already has a trolley account.".to_string(), + )); + } + } + + if let Some(email) = user.email { + let id = payouts_queue.lock().await.register_recipient(&email, body.0).await?; + + let mut transaction = pool.begin().await?; + + sqlx::query!( + " + UPDATE users + SET trolley_id = $1, trolley_account_status = $2 + WHERE id = $3 + ", + id, + RecipientStatus::Incomplete.as_str(), + user.id.0 as i64, + ) + .execute(&mut transaction) + .await?; + + transaction.commit().await?; + crate::database::models::User::clear_caches(&[(user.id.into(), None)], &redis).await?; + + Ok(HttpResponse::NoContent().finish()) + } else { + Err(ApiError::InvalidInput( + "User needs to have an email set on account.".to_string(), + )) + } +} diff --git a/src/auth/validate.rs b/src/auth/validate.rs index 34a0d128..cb979354 100644 --- a/src/auth/validate.rs +++ b/src/auth/validate.rs @@ -56,16 +56,15 @@ where created: db_user.created, role: Role::from_string(&db_user.role), badges: db_user.badges, - payout_data: Some(UserPayoutData { - balance: db_user.balance, - payout_wallet: db_user.payout_wallet, - payout_wallet_type: db_user.payout_wallet_type, - payout_address: db_user.payout_address, - }), auth_providers: Some(auth_providers), has_password: Some(db_user.password.is_some()), has_totp: Some(db_user.totp_secret.is_some()), github_id: None, + payout_data: Some(UserPayoutData { + balance: db_user.balance, + trolley_id: db_user.trolley_id, + trolley_status: db_user.trolley_account_status, + }), }; if let Some(required_scopes) = required_scopes { diff --git a/src/clickhouse/fetch.rs b/src/clickhouse/fetch.rs index 7fddedd5..a17d69ff 100644 --- a/src/clickhouse/fetch.rs +++ b/src/clickhouse/fetch.rs @@ -76,10 +76,10 @@ pub async fn fetch_playtimes( .bind(start_date) .bind(end_date); - if projects.is_some() { - query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::>()); - } else if versions.is_some() { - query = query.bind(versions.unwrap().iter().map(|x| x.0).collect::>()); + if let Some(projects) = projects { + query = query.bind(projects.iter().map(|x| x.0).collect::>()); + } else if let Some(versions) = versions { + query = query.bind(versions.iter().map(|x| x.0).collect::>()); } Ok(query.fetch_all().await?) @@ -123,10 +123,10 @@ pub async fn fetch_views( .bind(start_date) .bind(end_date); - if projects.is_some() { - query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::>()); - } else if versions.is_some() { - query = query.bind(versions.unwrap().iter().map(|x| x.0).collect::>()); + if let Some(projects) = projects { + query = query.bind(projects.iter().map(|x| x.0).collect::>()); + } else if let Some(versions) = versions { + query = query.bind(versions.iter().map(|x| x.0).collect::>()); } Ok(query.fetch_all().await?) @@ -170,10 +170,10 @@ pub async fn fetch_downloads( .bind(start_date) .bind(end_date); - if projects.is_some() { - query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::>()); - } else if versions.is_some() { - query = query.bind(versions.unwrap().iter().map(|x| x.0).collect::>()); + if let Some(projects) = projects { + query = query.bind(projects.iter().map(|x| x.0).collect::>()); + } else if let Some(versions) = versions { + query = query.bind(versions.iter().map(|x| x.0).collect::>()); } Ok(query.fetch_all().await?) @@ -233,10 +233,10 @@ pub async fn fetch_countries( " )).bind(start_date).bind(end_date).bind(start_date).bind(end_date); - if projects.is_some() { - query = query.bind(projects.unwrap().iter().map(|x| x.0).collect::>()); - } else if versions.is_some() { - query = query.bind(versions.unwrap().iter().map(|x| x.0).collect::>()); + if let Some(projects) = projects { + query = query.bind(projects.iter().map(|x| x.0).collect::>()); + } else if let Some(versions) = versions { + query = query.bind(versions.iter().map(|x| x.0).collect::>()); } Ok(query.fetch_all().await?) diff --git a/src/database/models/collection_item.rs b/src/database/models/collection_item.rs index a24f5dcb..d0cf23e7 100644 --- a/src/database/models/collection_item.rs +++ b/src/database/models/collection_item.rs @@ -210,7 +210,7 @@ impl Collection { color: m.color.map(|x| x as u32), created: m.created, updated: m.updated, - status: CollectionStatus::from_str(&m.status), + status: CollectionStatus::from_string(&m.status), projects: m .mods .unwrap_or_default() diff --git a/src/database/models/project_item.rs b/src/database/models/project_item.rs index f214c9ad..68e44967 100644 --- a/src/database/models/project_item.rs +++ b/src/database/models/project_item.rs @@ -630,10 +630,10 @@ impl Project { license_url: m.license_url.clone(), discord_url: m.discord_url.clone(), client_side: SideTypeId(m.client_side), - status: ProjectStatus::from_str( + status: ProjectStatus::from_string( &m.status, ), - requested_status: m.requested_status.map(|x| ProjectStatus::from_str( + requested_status: m.requested_status.map(|x| ProjectStatus::from_string( &x, )), server_side: SideTypeId(m.server_side), @@ -647,7 +647,7 @@ impl Project { webhook_sent: m.webhook_sent, color: m.color.map(|x| x as u32), queued: m.queued, - monetization_status: MonetizationStatus::from_str( + monetization_status: MonetizationStatus::from_string( &m.monetization_status, ), loaders: m.loaders, @@ -685,8 +685,8 @@ impl Project { donation_urls: serde_json::from_value( m.donations.unwrap_or_default(), ).ok().unwrap_or_default(), - client_side: crate::models::projects::SideType::from_str(&m.client_side_type), - server_side: crate::models::projects::SideType::from_str(&m.server_side_type), + client_side: crate::models::projects::SideType::from_string(&m.client_side_type), + server_side: crate::models::projects::SideType::from_string(&m.server_side_type), thread_id: ThreadId(m.thread_id), }})) }) diff --git a/src/database/models/thread_item.rs b/src/database/models/thread_item.rs index b8582cee..afad3241 100644 --- a/src/database/models/thread_item.rs +++ b/src/database/models/thread_item.rs @@ -148,7 +148,7 @@ impl Thread { id: ThreadId(x.id), project_id: x.mod_id.map(ProjectId), report_id: x.report_id.map(ReportId), - type_: ThreadType::from_str(&x.thread_type), + type_: ThreadType::from_string(&x.thread_type), messages: { let mut messages: Vec = serde_json::from_value( x.messages.unwrap_or_default(), diff --git a/src/database/models/user_item.rs b/src/database/models/user_item.rs index 5f732e2c..4f73aab7 100644 --- a/src/database/models/user_item.rs +++ b/src/database/models/user_item.rs @@ -3,7 +3,7 @@ use super::CollectionId; use crate::database::models::DatabaseError; use crate::database::redis::RedisPool; use crate::models::ids::base62_impl::{parse_base62, to_base62}; -use crate::models::users::{Badges, RecipientType, RecipientWallet}; +use crate::models::users::{Badges, RecipientStatus}; use chrono::{DateTime, Utc}; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; @@ -35,10 +35,10 @@ pub struct User { pub created: DateTime, pub role: String, pub badges: Badges, + pub balance: Decimal, - pub payout_wallet: Option, - pub payout_wallet_type: Option, - pub payout_address: Option, + pub trolley_id: Option, + pub trolley_account_status: Option, } impl User { @@ -188,9 +188,9 @@ impl User { SELECT id, name, email, avatar_url, username, bio, created, role, badges, - balance, payout_wallet, payout_wallet_type, payout_address, + balance, github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id, - email_verified, password, totp_secret + email_verified, password, totp_secret, trolley_id, trolley_account_status FROM users WHERE id = ANY($1) OR LOWER(username) = ANY($2) ", @@ -220,13 +220,13 @@ impl User { role: u.role, badges: Badges::from_bits(u.badges as u64).unwrap_or_default(), balance: u.balance, - payout_wallet: u.payout_wallet.map(|x| RecipientWallet::from_string(&x)), - payout_wallet_type: u - .payout_wallet_type - .map(|x| RecipientType::from_string(&x)), - payout_address: u.payout_address, password: u.password, totp_secret: u.totp_secret, + trolley_id: u.trolley_id, + trolley_account_status: u + .trolley_account_status + .as_ref() + .map(|x| RecipientStatus::from_string(x)), })) }) .try_collect::>() @@ -352,7 +352,7 @@ impl User { redis: &RedisPool, ) -> Result<(), DatabaseError> { redis - .delete_many(user_ids.into_iter().flat_map(|(id, username)| { + .delete_many(user_ids.iter().flat_map(|(id, username)| { [ (USERS_NAMESPACE, Some(id.0.to_string())), ( diff --git a/src/database/models/version_item.rs b/src/database/models/version_item.rs index 451f22f4..49933677 100644 --- a/src/database/models/version_item.rs +++ b/src/database/models/version_item.rs @@ -590,9 +590,9 @@ impl Version { downloads: v.downloads, version_type: v.version_type, featured: v.featured, - status: VersionStatus::from_str(&v.status), + status: VersionStatus::from_string(&v.status), requested_status: v.requested_status - .map(|x| VersionStatus::from_str(&x)), + .map(|x| VersionStatus::from_string(&x)), }, files: { #[derive(Deserialize)] @@ -803,7 +803,7 @@ impl Version { .unwrap_or_default().into_iter().map(|x| (x.algorithm, x.hash)).collect(), primary: f.is_primary, size: f.size as u32, - file_type: f.file_type.map(|x| FileType::from_str(&x)), + file_type: f.file_type.map(|x| FileType::from_string(&x)), } } )) diff --git a/src/file_hosting/mock.rs b/src/file_hosting/mock.rs index aa4706bf..c1b62c4c 100644 --- a/src/file_hosting/mock.rs +++ b/src/file_hosting/mock.rs @@ -4,6 +4,7 @@ use bytes::Bytes; use chrono::Utc; use sha2::Digest; +#[derive(Default)] pub struct MockHost(()); impl MockHost { diff --git a/src/lib.rs b/src/lib.rs index 01ff0bcd..fe4a8307 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -365,9 +365,9 @@ pub fn check_env_vars() -> bool { failed |= true; } - failed |= check_var::("PAYPAL_API_URL"); - failed |= check_var::("PAYPAL_CLIENT_ID"); - failed |= check_var::("PAYPAL_CLIENT_SECRET"); + failed |= check_var::("TROLLEY_ACCESS_KEY"); + failed |= check_var::("TROLLEY_SECRET_KEY"); + failed |= check_var::("TROLLEY_WEBHOOK_SIGNATURE"); failed |= check_var::("GITHUB_CLIENT_ID"); failed |= check_var::("GITHUB_CLIENT_SECRET"); diff --git a/src/main.rs b/src/main.rs index 67093c0e..4b25580e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,8 +31,6 @@ async fn main() -> std::io::Result<()> { let sentry = sentry::init(sentry::ClientOptions { release: sentry::release_name!(), traces_sample_rate: 0.1, - enable_profiling: true, - profiles_sample_rate: 0.1, ..Default::default() }); if sentry.is_enabled() { diff --git a/src/models/collections.rs b/src/models/collections.rs index cd8cd90c..63188183 100644 --- a/src/models/collections.rs +++ b/src/models/collections.rs @@ -80,7 +80,7 @@ impl std::fmt::Display for CollectionStatus { } impl CollectionStatus { - pub fn from_str(string: &str) -> CollectionStatus { + pub fn from_string(string: &str) -> CollectionStatus { match string { "listed" => CollectionStatus::Listed, "unlisted" => CollectionStatus::Unlisted, diff --git a/src/models/pats.rs b/src/models/pats.rs index 5d3f65ca..6ac2afc8 100644 --- a/src/models/pats.rs +++ b/src/models/pats.rs @@ -1,4 +1,5 @@ use super::ids::Base62Id; +use crate::bitflags_serde_impl; use crate::models::ids::UserId; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -10,8 +11,7 @@ use serde::{Deserialize, Serialize}; pub struct PatId(pub u64); bitflags::bitflags! { - #[derive(Serialize, Deserialize)] - #[serde(transparent)] + #[derive(Copy, Clone, Debug)] pub struct Scopes: u64 { // read a user's email const USER_READ_EMAIL = 1 << 0; @@ -107,6 +107,8 @@ bitflags::bitflags! { } } +bitflags_serde_impl!(Scopes, u64); + impl Scopes { // these scopes cannot be specified in a personal access token pub fn restricted() -> Scopes { diff --git a/src/models/projects.rs b/src/models/projects.rs index 716f8ac5..63f48f11 100644 --- a/src/models/projects.rs +++ b/src/models/projects.rs @@ -247,7 +247,7 @@ impl SideType { } } - pub fn from_str(string: &str) -> SideType { + pub fn from_string(string: &str) -> SideType { match string { "required" => SideType::Required, "optional" => SideType::Optional, @@ -308,7 +308,7 @@ impl std::fmt::Display for ProjectStatus { } impl ProjectStatus { - pub fn from_str(string: &str) -> ProjectStatus { + pub fn from_string(string: &str) -> ProjectStatus { match string { "processing" => ProjectStatus::Processing, "rejected" => ProjectStatus::Rejected, @@ -433,7 +433,7 @@ impl std::fmt::Display for MonetizationStatus { } impl MonetizationStatus { - pub fn from_str(string: &str) -> MonetizationStatus { + pub fn from_string(string: &str) -> MonetizationStatus { match string { "force-demonetized" => MonetizationStatus::ForceDemonetized, "demonetized" => MonetizationStatus::Demonetized, @@ -537,7 +537,7 @@ impl From for Version { version_id: d.version_id.map(|i| VersionId(i.0 as u64)), project_id: d.project_id.map(|i| ProjectId(i.0 as u64)), file_name: d.file_name, - dependency_type: DependencyType::from_str(d.dependency_type.as_str()), + dependency_type: DependencyType::from_string(d.dependency_type.as_str()), }) .collect(), game_versions: data.game_versions.into_iter().map(GameVersion).collect(), @@ -570,7 +570,7 @@ impl std::fmt::Display for VersionStatus { } impl VersionStatus { - pub fn from_str(string: &str) -> VersionStatus { + pub fn from_string(string: &str) -> VersionStatus { match string { "listed" => VersionStatus::Listed, "draft" => VersionStatus::Draft, @@ -718,7 +718,7 @@ impl DependencyType { } } - pub fn from_str(string: &str) -> DependencyType { + pub fn from_string(string: &str) -> DependencyType { match string { "required" => DependencyType::Required, "optional" => DependencyType::Optional, @@ -753,7 +753,7 @@ impl FileType { } } - pub fn from_str(string: &str) -> FileType { + pub fn from_string(string: &str) -> FileType { match string { "required-resource-pack" => FileType::RequiredResourcePack, "optional-resource-pack" => FileType::OptionalResourcePack, diff --git a/src/models/teams.rs b/src/models/teams.rs index 046a1f6b..9182474d 100644 --- a/src/models/teams.rs +++ b/src/models/teams.rs @@ -1,4 +1,5 @@ use super::ids::Base62Id; +use crate::bitflags_serde_impl; use crate::models::users::User; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; @@ -22,8 +23,7 @@ pub struct Team { } bitflags::bitflags! { - #[derive(Serialize, Deserialize)] - #[serde(transparent)] + #[derive(Copy, Clone, Debug)] pub struct ProjectPermissions: u64 { const UPLOAD_VERSION = 1 << 0; const DELETE_VERSION = 1 << 1; @@ -40,6 +40,8 @@ bitflags::bitflags! { } } +bitflags_serde_impl!(ProjectPermissions, u64); + impl Default for ProjectPermissions { fn default() -> ProjectPermissions { ProjectPermissions::UPLOAD_VERSION | ProjectPermissions::DELETE_VERSION @@ -77,8 +79,7 @@ impl ProjectPermissions { } bitflags::bitflags! { - #[derive(Serialize, Deserialize)] - #[serde(transparent)] + #[derive(Copy, Clone, Debug)] pub struct OrganizationPermissions: u64 { const EDIT_DETAILS = 1 << 0; const EDIT_BODY = 1 << 1; @@ -94,6 +95,8 @@ bitflags::bitflags! { } } +bitflags_serde_impl!(OrganizationPermissions, u64); + impl Default for OrganizationPermissions { fn default() -> OrganizationPermissions { OrganizationPermissions::NONE diff --git a/src/models/threads.rs b/src/models/threads.rs index 5a5a214d..2bcb706e 100644 --- a/src/models/threads.rs +++ b/src/models/threads.rs @@ -78,7 +78,7 @@ impl ThreadType { } } - pub fn from_str(string: &str) -> ThreadType { + pub fn from_string(string: &str) -> ThreadType { match string { "report" => ThreadType::Report, "project" => ThreadType::Project, diff --git a/src/models/users.rs b/src/models/users.rs index 4b2a0e90..8a012bf1 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -1,5 +1,6 @@ use super::ids::Base62Id; use crate::auth::flows::AuthProvider; +use crate::bitflags_serde_impl; use chrono::{DateTime, Utc}; use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; @@ -12,8 +13,7 @@ pub struct UserId(pub u64); pub const DELETED_USER: UserId = UserId(127155982985829); bitflags::bitflags! { - #[derive(Serialize, Deserialize)] - #[serde(transparent)] + #[derive(Copy, Clone, Debug)] pub struct Badges: u64 { // 1 << 0 unused - ignore + replace with something later const MIDAS = 1 << 0; @@ -29,6 +29,8 @@ bitflags::bitflags! { } } +bitflags_serde_impl!(Badges, u64); + impl Default for Badges { fn default() -> Badges { Badges::NONE @@ -46,12 +48,12 @@ pub struct User { pub role: Role, pub badges: Badges, - pub payout_data: Option, pub auth_providers: Option>, pub email: Option, pub email_verified: Option, pub has_password: Option, pub has_totp: Option, + pub payout_data: Option, // DEPRECATED. Always returns None pub github_id: Option, @@ -60,77 +62,8 @@ pub struct User { #[derive(Serialize, Deserialize, Clone, Debug)] pub struct UserPayoutData { pub balance: Decimal, - pub payout_wallet: Option, - pub payout_wallet_type: Option, - pub payout_address: Option, -} - -#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)] -#[serde(rename_all = "snake_case")] -pub enum RecipientType { - Email, - Phone, - UserHandle, -} - -impl std::fmt::Display for RecipientType { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - fmt.write_str(self.as_str()) - } -} - -impl RecipientType { - pub fn from_string(string: &str) -> RecipientType { - match string { - "user_handle" => RecipientType::UserHandle, - "phone" => RecipientType::Phone, - _ => RecipientType::Email, - } - } - - pub fn as_str(&self) -> &'static str { - match self { - RecipientType::Email => "email", - RecipientType::Phone => "phone", - RecipientType::UserHandle => "user_handle", - } - } -} - -#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Debug)] -#[serde(rename_all = "snake_case")] -pub enum RecipientWallet { - Venmo, - Paypal, -} - -impl std::fmt::Display for RecipientWallet { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - fmt.write_str(self.as_str()) - } -} - -impl RecipientWallet { - pub fn from_string(string: &str) -> RecipientWallet { - match string { - "venmo" => RecipientWallet::Venmo, - _ => RecipientWallet::Paypal, - } - } - - pub fn as_str(&self) -> &'static str { - match self { - RecipientWallet::Paypal => "paypal", - RecipientWallet::Venmo => "venmo", - } - } - - pub fn as_str_api(&self) -> &'static str { - match self { - RecipientWallet::Paypal => "PayPal", - RecipientWallet::Venmo => "Venmo", - } - } + pub trolley_id: Option, + pub trolley_status: Option, } use crate::database::models::user_item::User as DBUser; @@ -201,3 +134,89 @@ impl Role { } } } + +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] +#[serde(rename_all = "lowercase")] +pub enum RecipientStatus { + Active, + Incomplete, + Disabled, + Archived, + Suspended, + Blocked, +} + +impl RecipientStatus { + pub fn from_string(string: &str) -> RecipientStatus { + match string { + "active" => RecipientStatus::Active, + "incomplete" => RecipientStatus::Incomplete, + "disabled" => RecipientStatus::Disabled, + "archived" => RecipientStatus::Archived, + "suspended" => RecipientStatus::Suspended, + "blocked" => RecipientStatus::Blocked, + _ => RecipientStatus::Disabled, + } + } + + pub fn as_str(&self) -> &'static str { + match self { + RecipientStatus::Active => "active", + RecipientStatus::Incomplete => "incomplete", + RecipientStatus::Disabled => "disabled", + RecipientStatus::Archived => "archived", + RecipientStatus::Suspended => "suspended", + RecipientStatus::Blocked => "blocked", + } + } +} + +#[derive(Serialize)] +pub struct Payout { + pub created: DateTime, + pub amount: Decimal, + pub status: PayoutStatus, +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone)] +#[serde(rename_all = "lowercase")] +pub enum PayoutStatus { + Pending, + Failed, + Processed, + Returned, + Processing, +} + +impl PayoutStatus { + pub fn from_string(string: &str) -> PayoutStatus { + match string { + "pending" => PayoutStatus::Pending, + "failed" => PayoutStatus::Failed, + "processed" => PayoutStatus::Processed, + "returned" => PayoutStatus::Returned, + "processing" => PayoutStatus::Processing, + _ => PayoutStatus::Processing, + } + } + + pub fn as_str(&self) -> &'static str { + match self { + PayoutStatus::Pending => "pending", + PayoutStatus::Failed => "failed", + PayoutStatus::Processed => "processed", + PayoutStatus::Returned => "returned", + PayoutStatus::Processing => "processing", + } + } + + pub fn is_failed(&self) -> bool { + match self { + PayoutStatus::Pending => false, + PayoutStatus::Failed => true, + PayoutStatus::Processed => false, + PayoutStatus::Returned => true, + PayoutStatus::Processing => false, + } + } +} diff --git a/src/queue/analytics.rs b/src/queue/analytics.rs index 78a63ebc..8a02d99c 100644 --- a/src/queue/analytics.rs +++ b/src/queue/analytics.rs @@ -14,6 +14,12 @@ pub struct AnalyticsQueue { playtime_queue: DashSet, } +impl Default for AnalyticsQueue { + fn default() -> Self { + Self::new() + } +} + // Batches analytics data points + transactions every few minutes impl AnalyticsQueue { pub fn new() -> Self { diff --git a/src/queue/download.rs b/src/queue/download.rs index 05bad06b..6bd571f1 100644 --- a/src/queue/download.rs +++ b/src/queue/download.rs @@ -6,6 +6,12 @@ pub struct DownloadQueue { queue: Mutex>, } +impl Default for DownloadQueue { + fn default() -> Self { + Self::new() + } +} + // Batches download transactions every thirty seconds impl DownloadQueue { pub fn new() -> Self { diff --git a/src/queue/payouts.rs b/src/queue/payouts.rs index 737fe31b..2c9608a2 100644 --- a/src/queue/payouts.rs +++ b/src/queue/payouts.rs @@ -1,203 +1,332 @@ use crate::routes::ApiError; use crate::util::env::parse_var; use crate::{database::redis::RedisPool, models::projects::MonetizationStatus}; -use base64::Engine; use chrono::{DateTime, Datelike, Duration, Utc, Weekday}; +use hex::ToHex; +use hmac::{Hmac, Mac, NewMac}; +use reqwest::Method; use rust_decimal::Decimal; +use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; -use serde_json::json; +use serde_json::{json, Value}; +use sha2::Sha256; use sqlx::PgPool; use std::collections::HashMap; pub struct PayoutsQueue { - credential: PaypalCredential, - credential_expires: DateTime, + access_key: String, + secret_key: String, } -#[derive(Deserialize, Default)] -struct PaypalCredential { - access_token: String, - token_type: String, - expires_in: i64, +impl Default for PayoutsQueue { + fn default() -> Self { + Self::new() + } } -#[derive(Serialize)] -pub struct PayoutItem { - pub amount: PayoutAmount, - pub receiver: String, - pub note: String, - pub recipient_type: String, - pub recipient_wallet: String, - pub sender_item_id: String, +#[derive(Clone, Deserialize)] +#[serde(tag = "type", rename_all = "snake_case")] +pub enum AccountUser { + Business { name: String }, + Individual { first: String, last: String }, } -#[derive(Serialize, Deserialize)] -pub struct PayoutAmount { - pub currency: String, - #[serde(with = "rust_decimal::serde::str")] - pub value: Decimal, +#[derive(Serialize)] +pub struct PaymentInfo { + country: String, + payout_method: String, + route_minimum: Decimal, + estimated_fees: Decimal, + deduct_fees: Decimal, } // Batches payouts and handles token refresh impl PayoutsQueue { pub fn new() -> Self { PayoutsQueue { - credential: Default::default(), - credential_expires: Utc::now() - Duration::days(30), + access_key: dotenvy::var("TROLLEY_ACCESS_KEY").expect("missing trolley access key"), + secret_key: dotenvy::var("TROLLEY_SECRET_KEY").expect("missing trolley secret key"), } } - pub async fn refresh_token(&mut self) -> Result<(), ApiError> { + pub async fn make_trolley_request( + &self, + method: Method, + path: &str, + body: Option, + ) -> Result { + let timestamp = Utc::now().timestamp(); + + let mut mac: Hmac = Hmac::new_from_slice(self.secret_key.as_bytes()) + .map_err(|_| ApiError::Payments("error initializing HMAC".to_string()))?; + mac.update( + if let Some(body) = &body { + format!( + "{}\n{}\n{}\n{}\n", + timestamp, + method.as_str(), + path, + serde_json::to_string(&body)? + ) + } else { + format!("{}\n{}\n{}\n\n", timestamp, method.as_str(), path) + } + .as_bytes(), + ); + let request_signature = mac.finalize().into_bytes().encode_hex::(); + let client = reqwest::Client::new(); - let combined_key = format!( - "{}:{}", - dotenvy::var("PAYPAL_CLIENT_ID")?, - dotenvy::var("PAYPAL_CLIENT_SECRET")? - ); - let formatted_key = format!( - "Basic {}", - base64::engine::general_purpose::STANDARD.encode(combined_key) - ); + let mut request = client + .request(method, format!("https://api.trolley.com{path}")) + .header( + "Authorization", + format!("prsign {}:{}", self.access_key, request_signature), + ) + .header("X-PR-Timestamp", timestamp); - let mut form = HashMap::new(); - form.insert("grant_type", "client_credentials"); + if let Some(body) = body { + request = request.json(&body); + } - let credential: PaypalCredential = client - .post(&format!("{}oauth2/token", dotenvy::var("PAYPAL_API_URL")?)) - .header("Accept", "application/json") - .header("Accept-Language", "en_US") - .header("Authorization", formatted_key) - .form(&form) + let resp = request .send() .await - .map_err(|_| ApiError::Payments("Error while authenticating with PayPal".to_string()))? - .json() - .await - .map_err(|_| { - ApiError::Payments( - "Error while authenticating with PayPal (deser error)".to_string(), - ) - })?; + .map_err(|_| ApiError::Payments("could not communicate with Trolley".to_string()))?; + + let value = resp.json::().await.map_err(|_| { + ApiError::Payments("could not retrieve Trolley response body".to_string()) + })?; + + if let Some(obj) = value.as_object() { + if !obj.get("ok").and_then(|x| x.as_bool()).unwrap_or(true) { + #[derive(Deserialize)] + struct TrolleyError { + field: Option, + message: String, + } + + if let Some(array) = obj.get("errors") { + let err = serde_json::from_value::>(array.clone()).map_err( + |_| { + ApiError::Payments( + "could not retrieve Trolley error json body".to_string(), + ) + }, + )?; + + if let Some(first) = err.into_iter().next() { + return Err(ApiError::Payments(if let Some(field) = &first.field { + format!("error - field: {field} message: {}", first.message) + } else { + first.message + })); + } + } - self.credential_expires = Utc::now() + Duration::seconds(credential.expires_in); - self.credential = credential; + return Err(ApiError::Payments( + "could not retrieve Trolley error body".to_string(), + )); + } + } - Ok(()) + Ok(serde_json::from_value(value)?) } - pub async fn send_payout(&mut self, mut payout: PayoutItem) -> Result { - if self.credential_expires < Utc::now() { - self.refresh_token().await.map_err(|_| { - ApiError::Payments("Error while authenticating with PayPal".to_string()) - })?; + pub async fn send_payout( + &mut self, + recipient: &str, + amount: Decimal, + ) -> Result<(String, Option), ApiError> { + #[derive(Deserialize)] + struct TrolleyRes { + batch: Batch, } - let wallet = payout.recipient_wallet.clone(); + #[derive(Deserialize)] + struct Batch { + id: String, + payments: BatchPayments, + } - let fee = if wallet == *"Venmo" { - Decimal::ONE / Decimal::from(4) - } else { - std::cmp::min( - std::cmp::max( - Decimal::ONE / Decimal::from(4), - (Decimal::from(2) / Decimal::ONE_HUNDRED) * payout.amount.value, - ), - Decimal::from(20), - ) - }; + #[derive(Deserialize)] + struct Payment { + id: String, + } + + #[derive(Deserialize)] + struct BatchPayments { + payments: Vec, + } - payout.amount.value -= fee; - payout.amount.value = payout.amount.value.round_dp(2); + let fee = self.get_estimated_fees(recipient, amount).await?; - if payout.amount.value <= Decimal::ZERO { - return Err(ApiError::InvalidInput( - "You do not have enough funds to make this payout!".to_string(), + if fee.estimated_fees > amount || fee.route_minimum > amount { + return Err(ApiError::Payments( + "Account balance is too low to withdraw funds".to_string(), )); } - let client = reqwest::Client::new(); + let send_amount = amount - fee.deduct_fees; + + let res = self + .make_trolley_request::<_, TrolleyRes>( + Method::POST, + "/v1/batches/", + Some(json!({ + "currency": "USD", + "description": "labrinth payout", + "payments": [{ + "recipient": { + "id": recipient + }, + "amount": send_amount.to_string(), + "currency": "USD", + "memo": "Modrinth ad revenue payout" + }], + })), + ) + .await?; - let res = client.post(&format!("{}payments/payouts", dotenvy::var("PAYPAL_API_URL")?)) - .header("Authorization", format!("{} {}", self.credential.token_type, self.credential.access_token)) - .json(&json! ({ - "sender_batch_header": { - "sender_batch_id": format!("{}-payouts", Utc::now().to_rfc3339()), - "email_subject": "You have received a payment from Modrinth!", - "email_message": "Thank you for creating projects on Modrinth. Please claim this payment within 30 days.", - }, - "items": vec![payout] - })) - .send().await.map_err(|_| ApiError::Payments("Error while sending payout to PayPal".to_string()))?; - - if !res.status().is_success() { - #[derive(Deserialize)] - struct PayPalError { - pub body: PayPalErrorBody, - } + self.make_trolley_request::( + Method::POST, + &format!("/v1/batches/{}/start-processing", res.batch.id), + None, + ) + .await?; - #[derive(Deserialize)] - struct PayPalErrorBody { - pub message: String, - } + let payment_id = res.batch.payments.payments.into_iter().next().map(|x| x.id); - let body: PayPalError = res.json().await.map_err(|_| { - ApiError::Payments("Error while registering payment in PayPal!".to_string()) - })?; - - return Err(ApiError::Payments(format!( - "Error while registering payment in PayPal: {}", - body.body.message - ))); - } else if wallet != *"Venmo" { - #[derive(Deserialize)] - struct PayPalLink { - href: String, - } + Ok((res.batch.id, payment_id)) + } - #[derive(Deserialize)] - struct PayoutsResponse { - pub links: Vec, - } + pub async fn register_recipient( + &self, + email: &str, + user: AccountUser, + ) -> Result { + #[derive(Deserialize)] + struct TrolleyRes { + recipient: Recipient, + } - #[derive(Deserialize)] - struct PayoutDataItem { - payout_item_fee: PayoutAmount, - } + #[derive(Deserialize)] + struct Recipient { + id: String, + } - #[derive(Deserialize)] - struct PayoutData { - pub items: Vec, - } + let id = self + .make_trolley_request::<_, TrolleyRes>( + Method::POST, + "/v1/recipients/", + Some(match user { + AccountUser::Business { name } => json!({ + "type": "business", + "email": email, + "name": name, + }), + AccountUser::Individual { first, last } => json!({ + "type": "individual", + "firstName": first, + "lastName": last, + "email": email, + }), + }), + ) + .await?; - // Calculate actual fee + refund if we took too big of a fee. - if let Ok(res) = res.json::().await { - if let Some(link) = res.links.first() { - if let Ok(res) = client - .get(&link.href) - .header( - "Authorization", - format!( - "{} {}", - self.credential.token_type, self.credential.access_token - ), - ) - .send() - .await - { - if let Ok(res) = res.json::().await { - if let Some(data) = res.items.first() { - if (fee - data.payout_item_fee.value) > Decimal::ZERO { - return Ok(fee - data.payout_item_fee.value); - } - } - } - } - } - } + Ok(id.recipient.id) + } + + // lhs minimum, rhs estimate + pub async fn get_estimated_fees( + &self, + id: &str, + amount: Decimal, + ) -> Result { + #[derive(Deserialize)] + struct TrolleyRes { + recipient: Recipient, } - Ok(Decimal::ZERO) + #[derive(Deserialize)] + #[serde(rename_all = "camelCase")] + struct Recipient { + route_minimum: Option, + estimated_fees: Option, + address: RecipientAddress, + payout_method: String, + } + + #[derive(Deserialize)] + struct RecipientAddress { + country: String, + } + + let id = self + .make_trolley_request::( + Method::GET, + &format!("/v1/recipients/{id}"), + None, + ) + .await?; + + if &id.recipient.payout_method == "paypal" { + // based on https://www.paypal.com/us/webapps/mpp/merchant-fees. see paypal payouts section + let fee = if &id.recipient.address.country == "US" { + std::cmp::min( + std::cmp::max( + Decimal::ONE / Decimal::from(4), + (Decimal::from(2) / Decimal::ONE_HUNDRED) * amount, + ), + Decimal::from(1), + ) + } else { + std::cmp::min( + (Decimal::from(2) / Decimal::ONE_HUNDRED) * amount, + Decimal::from(20), + ) + }; + + Ok(PaymentInfo { + country: id.recipient.address.country, + payout_method: id.recipient.payout_method, + route_minimum: fee, + estimated_fees: fee, + deduct_fees: fee, + }) + } else if &id.recipient.payout_method == "venmo" { + let venmo_fee = Decimal::ONE / Decimal::from(4); + + Ok(PaymentInfo { + country: id.recipient.address.country, + payout_method: id.recipient.payout_method, + route_minimum: id.recipient.route_minimum.unwrap_or(Decimal::ZERO) + venmo_fee, + estimated_fees: id.recipient.estimated_fees.unwrap_or(Decimal::ZERO) + venmo_fee, + deduct_fees: venmo_fee, + }) + } else { + Ok(PaymentInfo { + country: id.recipient.address.country, + payout_method: id.recipient.payout_method, + route_minimum: id.recipient.route_minimum.unwrap_or(Decimal::ZERO), + estimated_fees: id.recipient.estimated_fees.unwrap_or(Decimal::ZERO), + deduct_fees: Decimal::ZERO, + }) + } + } + + pub async fn update_recipient_email(&self, id: &str, email: &str) -> Result<(), ApiError> { + self.make_trolley_request::<_, Value>( + Method::PATCH, + &format!("/v1/recipients/{}", id), + Some(json!({ + "email": email, + })), + ) + .await?; + + Ok(()) } } @@ -206,7 +335,7 @@ pub async fn process_payout( redis: &RedisPool, client: &clickhouse::Client, ) -> Result<(), ApiError> { - let start: DateTime = DateTime::from_utc( + let start: DateTime = DateTime::from_naive_utc_and_offset( (Utc::now() - Duration::days(1)) .date_naive() .and_hms_nano_opt(0, 0, 0, 0) diff --git a/src/queue/session.rs b/src/queue/session.rs index bbc2896e..8948810d 100644 --- a/src/queue/session.rs +++ b/src/queue/session.rs @@ -13,6 +13,12 @@ pub struct AuthQueue { pat_queue: Mutex>, } +impl Default for AuthQueue { + fn default() -> Self { + Self::new() + } +} + // Batches session accessing transactions every 30 seconds impl AuthQueue { pub fn new() -> Self { diff --git a/src/ratelimit/memory.rs b/src/ratelimit/memory.rs index 2e786835..ee52ca6a 100644 --- a/src/ratelimit/memory.rs +++ b/src/ratelimit/memory.rs @@ -15,6 +15,12 @@ pub struct MemoryStore { inner: Arc>, } +impl Default for MemoryStore { + fn default() -> Self { + Self::new() + } +} + impl MemoryStore { /// Create a new hashmap /// diff --git a/src/routes/analytics.rs b/src/routes/analytics.rs index 932cc8b7..36efdde0 100644 --- a/src/routes/analytics.rs +++ b/src/routes/analytics.rs @@ -6,10 +6,10 @@ use crate::queue::analytics::AnalyticsQueue; use crate::queue::maxmind::MaxMindIndexer; use crate::queue::session::AuthQueue; use crate::routes::ApiError; +use crate::util::date::get_current_tenths_of_ms; use crate::util::env::parse_strings_from_var; use actix_web::{post, web}; use actix_web::{HttpRequest, HttpResponse}; -use chrono::Utc; use serde::Deserialize; use sqlx::PgPool; use std::collections::HashMap; @@ -108,7 +108,7 @@ pub async fn page_view_ingest( let mut view = PageView { id: Uuid::new_v4(), - recorded: Utc::now().timestamp_nanos() / 100_000, + recorded: get_current_tenths_of_ms(), domain: domain.to_string(), site_path: url.path().to_string(), user_id: 0, @@ -204,7 +204,7 @@ pub async fn playtime_ingest( if let Some(version) = versions.iter().find(|x| id == x.inner.id.into()) { analytics_queue.add_playtime(Playtime { id: Default::default(), - recorded: Utc::now().timestamp_nanos() / 100_000, + recorded: get_current_tenths_of_ms(), seconds: playtime.seconds as u64, user_id: user.id.0, project_id: version.inner.project_id.0 as u64, diff --git a/src/routes/v2/admin.rs b/src/routes/v2/admin.rs index 439e83ec..cc5bd9e6 100644 --- a/src/routes/v2/admin.rs +++ b/src/routes/v2/admin.rs @@ -1,17 +1,23 @@ use crate::auth::validate::get_user_record_from_bearer_token; +use crate::database::models::User; use crate::database::redis::RedisPool; use crate::models::analytics::Download; use crate::models::ids::ProjectId; use crate::models::pats::Scopes; +use crate::models::users::{PayoutStatus, RecipientStatus}; use crate::queue::analytics::AnalyticsQueue; use crate::queue::download::DownloadQueue; use crate::queue::maxmind::MaxMindIndexer; use crate::queue::session::AuthQueue; use crate::routes::ApiError; +use crate::util::date::get_current_tenths_of_ms; use crate::util::guards::admin_key_guard; -use actix_web::{patch, web, HttpRequest, HttpResponse}; -use chrono::Utc; +use crate::util::routes::read_from_payload; +use actix_web::{patch, post, web, HttpRequest, HttpResponse}; +use hex::ToHex; +use hmac::{Hmac, Mac, NewMac}; use serde::Deserialize; +use sha2::Sha256; use sqlx::PgPool; use std::collections::HashMap; use std::net::Ipv4Addr; @@ -19,7 +25,11 @@ use std::sync::Arc; use uuid::Uuid; pub fn config(cfg: &mut web::ServiceConfig) { - cfg.service(web::scope("admin").service(count_download)); + cfg.service( + web::scope("admin") + .service(count_download) + .service(trolley_webhook), + ); } #[derive(Deserialize)] @@ -110,7 +120,7 @@ pub async fn count_download( analytics_queue.add_download(Download { id: Uuid::new_v4(), - recorded: Utc::now().timestamp_nanos() / 100_000, + recorded: get_current_tenths_of_ms(), domain: url.host_str().unwrap_or_default().to_string(), site_path: url.path().to_string(), user_id: user @@ -141,3 +151,171 @@ pub async fn count_download( Ok(HttpResponse::NoContent().body("")) } + +#[derive(Deserialize)] +pub struct TrolleyWebhook { + model: String, + action: String, + body: HashMap, +} + +#[post("/_trolley")] +#[allow(clippy::too_many_arguments)] +pub async fn trolley_webhook( + req: HttpRequest, + pool: web::Data, + redis: web::Data, + mut payload: web::Payload, +) -> Result { + if let Some(signature) = req.headers().get("X-PaymentRails-Signature") { + let payload = read_from_payload( + &mut payload, + 1 << 20, + "Webhook payload exceeds the maximum of 1MiB.", + ) + .await?; + + let mut signature = signature.to_str().ok().unwrap_or_default().split(','); + let timestamp = signature + .next() + .and_then(|x| x.split('=').nth(1)) + .unwrap_or_default(); + let v1 = signature + .next() + .and_then(|x| x.split('=').nth(1)) + .unwrap_or_default(); + + let mut mac: Hmac = + Hmac::new_from_slice(dotenvy::var("TROLLEY_WEBHOOK_SIGNATURE")?.as_bytes()) + .map_err(|_| ApiError::Payments("error initializing HMAC".to_string()))?; + mac.update(timestamp.as_bytes()); + mac.update(&payload); + let request_signature = mac.finalize().into_bytes().encode_hex::(); + + if &*request_signature == v1 { + let webhook = serde_json::from_slice::(&payload)?; + + if webhook.model == "recipient" { + #[derive(Deserialize)] + struct Recipient { + pub id: String, + pub email: Option, + pub status: Option, + } + + if let Some(body) = webhook.body.get("recipient") { + if let Ok(recipient) = serde_json::from_value::(body.clone()) { + let value = sqlx::query!( + "SELECT id FROM users WHERE trolley_id = $1", + recipient.id + ) + .fetch_optional(&**pool) + .await?; + + if let Some(user) = value { + let user = User::get_id( + crate::database::models::UserId(user.id), + &**pool, + &redis, + ) + .await?; + + if let Some(user) = user { + let mut transaction = pool.begin().await?; + + if webhook.action == "deleted" { + sqlx::query!( + " + UPDATE users + SET trolley_account_status = NULL, trolley_id = NULL + WHERE id = $1 + ", + user.id.0 + ) + .execute(&mut transaction) + .await?; + } else { + sqlx::query!( + " + UPDATE users + SET email = $1, email_verified = $2, trolley_account_status = $3 + WHERE id = $4 + ", + recipient.email.clone(), + user.email_verified && recipient.email == user.email, + recipient.status.map(|x| x.as_str()), + user.id.0 + ) + .execute(&mut transaction).await?; + } + + transaction.commit().await?; + User::clear_caches(&[(user.id, None)], &redis).await?; + } + } + } + } + } + + if webhook.model == "payment" { + #[derive(Deserialize)] + struct Payment { + pub id: String, + pub status: PayoutStatus, + } + + if let Some(body) = webhook.body.get("payment") { + if let Ok(payment) = serde_json::from_value::(body.clone()) { + let value = sqlx::query!( + "SELECT id, amount, user_id, status FROM historical_payouts WHERE payment_id = $1", + payment.id + ) + .fetch_optional(&**pool) + .await?; + + if let Some(payout) = value { + let mut transaction = pool.begin().await?; + + if payment.status.is_failed() + && !PayoutStatus::from_string(&payout.status).is_failed() + { + sqlx::query!( + " + UPDATE users + SET balance = balance + $1 + WHERE id = $2 + ", + payout.amount, + payout.user_id, + ) + .execute(&mut transaction) + .await?; + } + + sqlx::query!( + " + UPDATE historical_payouts + SET status = $1 + WHERE payment_id = $2 + ", + payment.status.as_str(), + payment.id, + ) + .execute(&mut transaction) + .await?; + + transaction.commit().await?; + User::clear_caches( + &[(crate::database::models::UserId(payout.user_id), None)], + &redis, + ) + .await?; + } + } + } + } + } + } + + Ok(HttpResponse::NoContent().finish()) +} diff --git a/src/routes/v2/mod.rs b/src/routes/v2/mod.rs index 622f2cab..3f95ae6d 100644 --- a/src/routes/v2/mod.rs +++ b/src/routes/v2/mod.rs @@ -32,7 +32,6 @@ pub fn config(cfg: &mut actix_web::web::ServiceConfig) { .configure(moderation::config) .configure(notifications::config) .configure(organizations::config) - //.configure(pats::config) .configure(project_creation::config) .configure(collections::config) .configure(images::config) diff --git a/src/routes/v2/users.rs b/src/routes/v2/users.rs index bda564a7..f2b483f3 100644 --- a/src/routes/v2/users.rs +++ b/src/routes/v2/users.rs @@ -1,4 +1,4 @@ -use crate::auth::{get_user_from_headers, AuthenticationError}; +use crate::auth::get_user_from_headers; use crate::database::models::User; use crate::database::redis::RedisPool; use crate::file_hosting::FileHost; @@ -6,14 +6,15 @@ use crate::models::collections::{Collection, CollectionStatus}; use crate::models::notifications::Notification; use crate::models::pats::Scopes; use crate::models::projects::Project; -use crate::models::users::{Badges, RecipientType, RecipientWallet, Role, UserId}; -use crate::queue::payouts::{PayoutAmount, PayoutItem, PayoutsQueue}; +use crate::models::users::{ + Badges, Payout, PayoutStatus, RecipientStatus, Role, UserId, UserPayoutData, +}; +use crate::queue::payouts::PayoutsQueue; use crate::queue::session::AuthQueue; use crate::routes::ApiError; use crate::util::routes::read_from_payload; use crate::util::validate::validation_errors_to_string; use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse}; -use chrono::{DateTime, Utc}; use lazy_static::lazy_static; use regex::Regex; use rust_decimal::Decimal; @@ -39,6 +40,7 @@ pub fn config(cfg: &mut web::ServiceConfig) { .service(user_notifications) .service(user_follows) .service(user_payouts) + .service(user_payouts_fees) .service(user_payouts_request), ); } @@ -218,21 +220,6 @@ pub struct EditUser { pub bio: Option>, pub role: Option, pub badges: Option, - #[serde( - default, - skip_serializing_if = "Option::is_none", - with = "::serde_with::rust::double_option" - )] - #[validate] - pub payout_data: Option>, -} - -#[derive(Serialize, Deserialize, Validate)] -pub struct EditPayoutData { - pub payout_wallet: RecipientWallet, - pub payout_wallet_type: RecipientType, - #[validate(length(max = 128))] - pub payout_address: String, } #[patch("{id}")] @@ -244,7 +231,7 @@ pub async fn user_edit( redis: web::Data, session_queue: web::Data, ) -> Result { - let (scopes, user) = get_user_from_headers( + let (_scopes, user) = get_user_from_headers( &req, &**pool, &redis, @@ -364,79 +351,6 @@ pub async fn user_edit( .await?; } - if let Some(payout_data) = &new_user.payout_data { - if let Some(payout_data) = payout_data { - if payout_data.payout_wallet_type == RecipientType::UserHandle - && payout_data.payout_wallet == RecipientWallet::Paypal - { - return Err(ApiError::InvalidInput( - "You cannot use a paypal wallet with a user handle!".to_string(), - )); - } - - if !scopes.contains(Scopes::PAYOUTS_WRITE) { - return Err(ApiError::Authentication( - AuthenticationError::InvalidCredentials, - )); - } - - if !match payout_data.payout_wallet_type { - RecipientType::Email => { - validator::validate_email(&payout_data.payout_address) - } - RecipientType::Phone => { - validator::validate_phone(&payout_data.payout_address) - } - RecipientType::UserHandle => true, - } { - return Err(ApiError::InvalidInput( - "Invalid wallet specified!".to_string(), - )); - } - - let results = sqlx::query!( - " - SELECT EXISTS(SELECT 1 FROM users WHERE id = $1 AND email IS NULL) - ", - id as crate::database::models::ids::UserId, - ) - .fetch_one(&mut *transaction) - .await?; - - if results.exists.unwrap_or(false) { - return Err(ApiError::InvalidInput( - "You must have an email set on your Modrinth account to enroll in the monetization program!" - .to_string(), - )); - } - - sqlx::query!( - " - UPDATE users - SET payout_wallet = $1, payout_wallet_type = $2, payout_address = $3 - WHERE (id = $4) - ", - payout_data.payout_wallet.as_str(), - payout_data.payout_wallet_type.as_str(), - payout_data.payout_address, - id as crate::database::models::ids::UserId, - ) - .execute(&mut *transaction) - .await?; - } else { - sqlx::query!( - " - UPDATE users - SET payout_wallet = NULL, payout_wallet_type = NULL, payout_address = NULL - WHERE (id = $1) - ", - id as crate::database::models::ids::UserId, - ) - .execute(&mut *transaction) - .await?; - } - } - User::clear_caches(&[(id, Some(actual_user.username))], &redis).await?; transaction.commit().await?; Ok(HttpResponse::NoContent().body("")) @@ -691,13 +605,6 @@ pub async fn user_notifications( } } -#[derive(Serialize)] -pub struct Payout { - pub created: DateTime, - pub amount: Decimal, - pub status: String, -} - #[get("{id}/payouts")] pub async fn user_payouts( req: HttpRequest, @@ -757,7 +664,7 @@ pub async fn user_payouts( Ok(e.right().map(|row| Payout { created: row.created, amount: row.amount, - status: row.status, + status: PayoutStatus::from_string(&row.status), })) }) .try_collect::>(), @@ -776,6 +683,61 @@ pub async fn user_payouts( } } +#[derive(Deserialize)] +pub struct FeeEstimateAmount { + amount: Decimal, +} + +#[get("{id}/payouts_fees")] +pub async fn user_payouts_fees( + req: HttpRequest, + info: web::Path<(String,)>, + web::Query(amount): web::Query, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, + payouts_queue: web::Data>, +) -> Result { + let user = get_user_from_headers( + &req, + &**pool, + &redis, + &session_queue, + Some(&[Scopes::PAYOUTS_READ]), + ) + .await? + .1; + let actual_user = User::get(&info.into_inner().0, &**pool, &redis).await?; + + if let Some(actual_user) = actual_user { + if !user.role.is_admin() && user.id != actual_user.id.into() { + return Err(ApiError::CustomAuthentication( + "You do not have permission to request payouts of this user!".to_string(), + )); + } + + if let Some(UserPayoutData { + trolley_id: Some(trolley_id), + .. + }) = user.payout_data + { + let payouts = payouts_queue + .lock() + .await + .get_estimated_fees(&trolley_id, amount.amount) + .await?; + + Ok(HttpResponse::Ok().json(payouts)) + } else { + Err(ApiError::InvalidInput( + "You must set up your trolley account first!".to_string(), + )) + } + } else { + Ok(HttpResponse::NotFound().body("")) + } +} + #[derive(Deserialize)] pub struct PayoutData { amount: Decimal, @@ -811,67 +773,60 @@ pub async fn user_payouts_request( )); } - if let Some(payouts_data) = user.payout_data { - if let Some(payout_address) = payouts_data.payout_address { - if let Some(payout_wallet_type) = payouts_data.payout_wallet_type { - if let Some(payout_wallet) = payouts_data.payout_wallet { - return if data.amount < payouts_data.balance { - let mut transaction = pool.begin().await?; - - let leftover = payouts_queue - .send_payout(PayoutItem { - amount: PayoutAmount { - currency: "USD".to_string(), - value: data.amount, - }, - receiver: payout_address, - note: "Payment from Modrinth creator monetization program" - .to_string(), - recipient_type: payout_wallet_type.to_string().to_uppercase(), - recipient_wallet: payout_wallet.as_str_api().to_string(), - sender_item_id: format!( - "{}-{}", - UserId::from(id), - Utc::now().timestamp() - ), - }) - .await?; + if let Some(UserPayoutData { + trolley_id: Some(trolley_id), + trolley_status: Some(trolley_status), + balance, + .. + }) = user.payout_data + { + if trolley_status == RecipientStatus::Active { + return if data.amount < balance { + let mut transaction = pool.begin().await?; - sqlx::query!( + let (batch_id, payment_id) = + payouts_queue.send_payout(&trolley_id, data.amount).await?; + + sqlx::query!( " - INSERT INTO historical_payouts (user_id, amount, status) - VALUES ($1, $2, $3) + INSERT INTO historical_payouts (user_id, amount, status, batch_id, payment_id) + VALUES ($1, $2, $3, $4, $5) ", id as crate::database::models::ids::UserId, data.amount, - "success" + "processing", + batch_id, + payment_id, ) - .execute(&mut *transaction) - .await?; + .execute(&mut *transaction) + .await?; - sqlx::query!( - " + sqlx::query!( + " UPDATE users SET balance = balance - $1 WHERE id = $2 ", - data.amount - leftover, - id as crate::database::models::ids::UserId - ) - .execute(&mut *transaction) - .await?; - User::clear_caches(&[(id, None)], &redis).await?; - - transaction.commit().await?; - - Ok(HttpResponse::NoContent().body("")) - } else { - Err(ApiError::InvalidInput( - "You do not have enough funds to make this payout!".to_string(), - )) - }; - } - } + data.amount, + id as crate::database::models::ids::UserId + ) + .execute(&mut *transaction) + .await?; + + User::clear_caches(&[(id, None)], &redis).await?; + + transaction.commit().await?; + + Ok(HttpResponse::NoContent().body("")) + } else { + Err(ApiError::InvalidInput( + "You do not have enough funds to make this payout!".to_string(), + )) + }; + } else { + return Err(ApiError::InvalidInput( + "Please complete payout information via the trolley dashboard!".to_string(), + )); } } diff --git a/src/scheduler.rs b/src/scheduler.rs index 30df2624..055601c3 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -5,6 +5,12 @@ pub struct Scheduler { arbiter: Arbiter, } +impl Default for Scheduler { + fn default() -> Self { + Self::new() + } +} + impl Scheduler { pub fn new() -> Self { Scheduler { diff --git a/src/util/bitflag.rs b/src/util/bitflag.rs new file mode 100644 index 00000000..08647ab6 --- /dev/null +++ b/src/util/bitflag.rs @@ -0,0 +1,18 @@ +#[macro_export] +macro_rules! bitflags_serde_impl { + ($type:ident, $int_type:ident) => { + impl serde::Serialize for $type { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_i64(self.bits() as i64) + } + } + + impl<'de> serde::Deserialize<'de> for $type { + fn deserialize>(deserializer: D) -> Result { + let v: i64 = Deserialize::deserialize(deserializer)?; + + Ok($type::from_bits_truncate(v as $int_type)) + } + } + }; +} diff --git a/src/util/date.rs b/src/util/date.rs new file mode 100644 index 00000000..3551307b --- /dev/null +++ b/src/util/date.rs @@ -0,0 +1,9 @@ +use chrono::Utc; + +// this converts timestamps to the timestamp format clickhouse requires/uses +pub fn get_current_tenths_of_ms() -> i64 { + Utc::now() + .timestamp_nanos_opt() + .expect("value can not be represented in a timestamp with nanosecond precision.") + / 100_000 +} diff --git a/src/util/mod.rs b/src/util/mod.rs index fa514c59..74588dd7 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,5 +1,7 @@ +pub mod bitflag; pub mod captcha; pub mod cors; +pub mod date; pub mod env; pub mod ext; pub mod guards; diff --git a/src/validate/fabric.rs b/src/validate/fabric.rs index 0a9b3a02..2ee44753 100644 --- a/src/validate/fabric.rs +++ b/src/validate/fabric.rs @@ -20,7 +20,7 @@ impl super::Validator for FabricValidator { fn get_supported_game_versions(&self) -> SupportedGameVersions { // Time since release of 18w49a, the first fabric version - SupportedGameVersions::PastDate(DateTime::from_utc( + SupportedGameVersions::PastDate(DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1543969469, 0).unwrap(), Utc, )) diff --git a/src/validate/forge.rs b/src/validate/forge.rs index 6a4907da..04355fcd 100644 --- a/src/validate/forge.rs +++ b/src/validate/forge.rs @@ -20,7 +20,7 @@ impl super::Validator for ForgeValidator { fn get_supported_game_versions(&self) -> SupportedGameVersions { // Time since release of 1.13, the first forge version which uses the new TOML system - SupportedGameVersions::PastDate(DateTime::::from_utc( + SupportedGameVersions::PastDate(DateTime::::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1540122067, 0).unwrap(), Utc, )) @@ -58,11 +58,11 @@ impl super::Validator for LegacyForgeValidator { fn get_supported_game_versions(&self) -> SupportedGameVersions { // Times between versions 1.5.2 to 1.12.2, which all use the legacy way of defining mods SupportedGameVersions::Range( - DateTime::from_utc( + DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1366818300, 0).unwrap(), Utc, ), - DateTime::from_utc( + DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1505810340, 0).unwrap(), Utc, ), diff --git a/src/validate/quilt.rs b/src/validate/quilt.rs index ddb885f5..66741b8b 100644 --- a/src/validate/quilt.rs +++ b/src/validate/quilt.rs @@ -19,7 +19,7 @@ impl super::Validator for QuiltValidator { } fn get_supported_game_versions(&self) -> SupportedGameVersions { - SupportedGameVersions::PastDate(DateTime::from_utc( + SupportedGameVersions::PastDate(DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1646070100, 0).unwrap(), Utc, )) diff --git a/src/validate/resourcepack.rs b/src/validate/resourcepack.rs index 8e9b1beb..97f041de 100644 --- a/src/validate/resourcepack.rs +++ b/src/validate/resourcepack.rs @@ -20,7 +20,7 @@ impl super::Validator for PackValidator { fn get_supported_game_versions(&self) -> SupportedGameVersions { // Time since release of 13w24a which replaced texture packs with resource packs - SupportedGameVersions::PastDate(DateTime::from_utc( + SupportedGameVersions::PastDate(DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1371137542, 0).unwrap(), Utc, )) @@ -58,11 +58,11 @@ impl super::Validator for TexturePackValidator { fn get_supported_game_versions(&self) -> SupportedGameVersions { // a1.2.2a to 13w23b SupportedGameVersions::Range( - DateTime::from_utc( + DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1289339999, 0).unwrap(), Utc, ), - DateTime::from_utc( + DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_opt(1370651522, 0).unwrap(), Utc, ), diff --git a/tests/scopes.rs b/tests/scopes.rs index 806905ab..d99614a1 100644 --- a/tests/scopes.rs +++ b/tests/scopes.rs @@ -70,24 +70,6 @@ async fn user_scopes() { .await .unwrap(); - // User payout info writing - let failure_write_user_payout = Scopes::all() ^ Scopes::PAYOUTS_WRITE; // Failure case should include USER_WRITE - let write_user_payout = Scopes::USER_WRITE | Scopes::PAYOUTS_WRITE; - let req_gen = || { - TestRequest::patch().uri("/v2/user/user").set_json(json!( { - "payout_data": { - "payout_wallet": "paypal", - "payout_wallet_type": "email", - "payout_address": "test@modrinth.com" - } - })) - }; - ScopeTest::new(&test_env) - .with_failure_scopes(failure_write_user_payout) - .test(req_gen, write_user_payout) - .await - .unwrap(); - // User deletion // (The failure is first, and this is the last test for this test function, we can delete it and use the same PAT for both tests) let delete_user = Scopes::USER_DELETE;