From d29d910ac6269f8615376c777935795c0104c3d6 Mon Sep 17 00:00:00 2001 From: Geometrically <18202329+Geometrically@users.noreply.github.com> Date: Thu, 26 May 2022 10:08:19 -0700 Subject: [PATCH] Add mod lists for modpacks, liteloader support, update actix, fix moderation webhook (#357) --- Cargo.lock | 476 +++++++++---------- Cargo.toml | 6 +- migrations/20220526040434_dep-file-names.sql | 2 + sqlx-data.json | 342 +++++-------- src/database/models/version_item.rs | 12 +- src/main.rs | 29 -- src/models/mod.rs | 1 + src/models/pack.rs | 111 +++++ src/models/projects.rs | 7 +- src/routes/project_creation.rs | 9 + src/routes/projects.rs | 14 - src/routes/version_creation.rs | 104 +++- src/routes/versions.rs | 16 + src/search/indexing/local_import.rs | 72 --- src/search/indexing/mod.rs | 1 - src/search/indexing/queue.rs | 36 -- src/util/webhook.rs | 9 +- src/validate/liteloader.rs | 38 ++ src/validate/mod.rs | 18 +- src/validate/pack.rs | 119 +---- 20 files changed, 667 insertions(+), 755 deletions(-) create mode 100644 migrations/20220526040434_dep-file-names.sql create mode 100644 src/models/pack.rs delete mode 100644 src/search/indexing/queue.rs create mode 100644 src/validate/liteloader.rs diff --git a/Cargo.lock b/Cargo.lock index d40724332..aa20f472d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", - "tokio-util 0.7.1", + "tokio-util 0.7.2", ] [[package]] @@ -40,14 +40,13 @@ dependencies = [ "memchr", "pin-project-lite", "tokio", - "tokio-util 0.7.1", + "tokio-util 0.7.2", ] [[package]] name = "actix-cors" version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414360eed71ba2d5435b185ba43ecbe281dfab5df3898286d6b7be8074372c92" +source = "git+https://github.com/modrinth/actix-extras.git?rev=34d301f#34d301f173c1e7dd5d835ffe29ea46b3e0e4bb8c" dependencies = [ "actix-utils", "actix-web", @@ -90,7 +89,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rand", - "sha-1 0.10.0", + "sha-1", "smallvec", "zstd", ] @@ -108,8 +107,7 @@ dependencies = [ [[package]] name = "actix-multipart" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9edfb0e7663d7fe18c8d5b668c9c1bcf79176b1dcc9d4da9592503209a6bfb0" +source = "git+https://github.com/modrinth/actix-web?rev=88c7c18#88c7c184abeed2b3d8765af2d7d1a9345010b9eb" dependencies = [ "actix-utils", "actix-web", @@ -190,8 +188,7 @@ dependencies = [ [[package]] name = "actix-web" version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e5ebffd51d50df56a3ae0de0e59487340ca456f05dd0b90c0a7a6dd6a74d31" +source = "git+https://github.com/modrinth/actix-web?rev=88c7c18#88c7c184abeed2b3d8765af2d7d1a9345010b9eb" dependencies = [ "actix-codec", "actix-http", @@ -311,9 +308,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "arrayvec" @@ -412,9 +409,9 @@ dependencies = [ [[package]] name = "base-x" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" +checksum = "dc19a4937b4fbd3fe3379793130e42060d10627a360f2127802b10b87e7baf74" [[package]] name = "base64" @@ -454,9 +451,9 @@ dependencies = [ [[package]] name = "brotli" -version = "3.3.3" +version = "3.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f838e47a451d5a8fa552371f80024dd6ace9b7acdf25c4c3d0f9bc6816fb1c39" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -711,9 +708,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.53+curl-7.82.0" +version = "0.4.55+curl-7.83.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8092905a5a9502c312f223b2775f57ec5c5b715f9a15ee9d2a8591d1364a0352" +checksum = "23734ec77368ec583c2e61dd3f0b0e5c98b93abe6d2a004ca06b91dd7e3e2762" dependencies = [ "cc", "libc", @@ -727,9 +724,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -737,9 +734,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", @@ -751,9 +748,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", @@ -762,13 +759,13 @@ dependencies = [ [[package]] name = "dashmap" -version = "5.2.0" +version = "5.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c" +checksum = "391b56fbd302e585b7a9494fb70e40949567b1cf9003a8e4a6041a1687c26573" dependencies = [ "cfg-if", - "num_cpus", - "parking_lot 0.12.0", + "hashbrown 0.12.1", + "lock_api", ] [[package]] @@ -856,9 +853,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if", ] @@ -893,15 +890,15 @@ dependencies = [ [[package]] name = "firestorm" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3d6188b8804df28032815ea256b6955c9625c24da7525f387a7af02fbb8f01" +checksum = "2c5f6c2c942da57e2aaaa84b8a521489486f14e75e7fa91dab70aba913975f98" [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" dependencies = [ "cfg-if", "crc32fast", @@ -1104,9 +1101,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62eeb471aa3e3c9197aa4bfeabfe02982f6dc96f750486c0bb0009ac58b26d2b" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" dependencies = [ "bytes", "fnv", @@ -1117,7 +1114,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.6.9", + "tokio-util 0.7.2", "tracing", ] @@ -1139,6 +1136,12 @@ dependencies = [ "ahash 0.7.6", ] +[[package]] +name = "hashbrown" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" + [[package]] name = "hashlink" version = "0.7.0" @@ -1148,20 +1151,14 @@ dependencies = [ "hashbrown 0.11.2", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "hermit-abi" @@ -1178,6 +1175,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", +] + [[package]] name = "hmac" version = "0.11.0" @@ -1199,9 +1205,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" dependencies = [ "bytes", "fnv", @@ -1210,9 +1216,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -1221,9 +1227,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9100414882e15fb7feccb4897e5f0ff0ff1ca7d1a86a23208ada4d7a18e6c6c4" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" [[package]] name = "httpdate" @@ -1299,9 +1305,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown 0.11.2", @@ -1318,15 +1324,15 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e70ee094dc02fd9c13fdad4940090f22dbd6ac7c9e7094a46cf0232a50bc7c" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "isahc" -version = "1.7.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437f8808009c031df3c1d532c8fd7e3d73239dfe522ebf0b94b5e34d5d01044b" +checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" dependencies = [ "async-channel", "castaway", @@ -1369,9 +1375,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "jobserver" @@ -1384,9 +1390,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" dependencies = [ "wasm-bindgen", ] @@ -1464,9 +1470,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.121" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libnghttp2-sys" @@ -1480,9 +1486,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f35facd4a5673cb5a48822be2be1d4236c1c99cb4113cab7061ac720d5bf859" +checksum = "92e7e15d7610cce1d9752e137625f14e61a28cd45929b6e12e47b50fe154ee2e" dependencies = [ "cc", "libc", @@ -1492,9 +1498,9 @@ dependencies = [ [[package]] name = "local-channel" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6246c68cf195087205a0512559c97e15eaf95198bf0e206d662092cdcb03fe9f" +checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" dependencies = [ "futures-core", "futures-sink", @@ -1504,24 +1510,25 @@ dependencies = [ [[package]] name = "local-waker" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902eb695eb0591864543cbfbf6d742510642a605a61fc5e97fe6ceb5a30ac4fb" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -1545,13 +1552,11 @@ dependencies = [ [[package]] name = "md-5" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" +checksum = "658646b21e0b72f7866c7038ab086d3d5e1cd6271f060fd37defb241949d0582" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", + "digest 0.10.3", ] [[package]] @@ -1582,9 +1587,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" @@ -1609,35 +1614,23 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" dependencies = [ "adler", - "autocfg", ] [[package]] name = "mio" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" dependencies = [ "libc", "log", - "miow", - "ntapi", "wasi 0.11.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "windows-sys", ] [[package]] @@ -1679,20 +1672,11 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "ntapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" -dependencies = [ - "winapi", -] - [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -1709,18 +1693,18 @@ dependencies = [ [[package]] name = "num_threads" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" dependencies = [ "libc", ] [[package]] name = "once_cell" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" [[package]] name = "opaque-debug" @@ -1730,18 +1714,30 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.38" +version = "0.10.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", + "openssl-macros", "openssl-sys", ] +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -1750,9 +1746,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.72" +version = "0.9.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0" dependencies = [ "autocfg", "cc", @@ -1795,7 +1791,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ "lock_api", - "parking_lot_core 0.9.1", + "parking_lot_core 0.9.3", ] [[package]] @@ -1814,9 +1810,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" dependencies = [ "cfg-if", "libc", @@ -1882,9 +1878,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -1894,9 +1890,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "polling" @@ -1949,11 +1945,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1967,9 +1963,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -2006,18 +2002,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7776223e2696f1aa4c6b0170e83212f47296a00424305117d013dfe86fb0fe55" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall", @@ -2026,9 +2022,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.5" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", @@ -2037,9 +2033,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "remove_dir_all" @@ -2079,7 +2075,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", - "tokio-util 0.6.9", + "tokio-util 0.6.10", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -2158,7 +2154,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.7", + "semver 1.0.9", ] [[package]] @@ -2182,18 +2178,18 @@ checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "winapi", + "windows-sys", ] [[package]] @@ -2246,9 +2242,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" +checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" [[package]] name = "semver-parser" @@ -2258,9 +2254,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] @@ -2279,9 +2275,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -2290,9 +2286,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "itoa", "ryu", @@ -2313,9 +2309,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1e6ec4d8950e5b1e894eac0d360742f3b1407a6078a604a731c4b3f49cefbc" +checksum = "b827f2113224f3f19a665136f006709194bdfdcb1fdc1e4b2b5cbac8e0cced54" dependencies = [ "rustversion", "serde", @@ -2324,9 +2320,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling", "proc-macro2", @@ -2334,19 +2330,6 @@ dependencies = [ "syn", ] -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha-1" version = "0.10.0" @@ -2419,9 +2402,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "sluice" @@ -2469,9 +2452,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc15591eb44ffb5816a4a70a7efd5dd87bfd3aa84c4c200401c4396140525826" +checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2479,9 +2462,9 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195183bf6ff8328bb82c0511a83faf60aacf75840103388851db61d7a9854ae3" +checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" dependencies = [ "ahash 0.7.6", "atoi", @@ -2493,13 +2476,15 @@ dependencies = [ "crossbeam-queue", "dirs", "either", + "event-listener", "futures-channel", "futures-core", "futures-intrusive", "futures-util", "hashlink", "hex", - "hmac 0.11.0", + "hkdf", + "hmac 0.12.1", "indexmap", "itoa", "libc", @@ -2513,8 +2498,8 @@ dependencies = [ "rustls", "serde", "serde_json", - "sha-1 0.9.8", - "sha2 0.9.9", + "sha-1", + "sha2 0.10.2", "smallvec", "sqlformat", "sqlx-rt", @@ -2530,20 +2515,20 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee35713129561f5e55c554bba1c378e2a7e67f81257b7311183de98c50e6f94" +checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" dependencies = [ "dotenv", "either", - "heck 0.3.3", + "heck", "hex", "once_cell", "proc-macro2", "quote", "serde", "serde_json", - "sha2 0.9.9", + "sha2 0.10.2", "sqlx-core", "sqlx-rt", "syn", @@ -2552,9 +2537,9 @@ dependencies = [ [[package]] name = "sqlx-rt" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b555e70fbbf84e269ec3858b7a6515bcfe7a166a7cc9c636dd6efd20431678b6" +checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" dependencies = [ "actix-rt", "once_cell", @@ -2650,13 +2635,13 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.90" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" +checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -2684,18 +2669,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -2762,9 +2747,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -2777,9 +2762,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.17.0" +version = "1.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee" +checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395" dependencies = [ "bytes", "libc", @@ -2828,9 +2813,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" dependencies = [ "bytes", "futures-core", @@ -2842,9 +2827,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" +checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c" dependencies = [ "bytes", "futures-core", @@ -2862,9 +2847,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if", "log", @@ -2875,9 +2860,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" dependencies = [ "proc-macro2", "quote", @@ -2886,9 +2871,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.23" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" dependencies = [ "lazy_static", ] @@ -2933,9 +2918,15 @@ checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" [[package]] name = "unicode-normalization" @@ -2952,12 +2943,6 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "unicode_categories" version = "0.1.1" @@ -3073,9 +3058,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3083,9 +3068,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" dependencies = [ "bumpalo", "lazy_static", @@ -3098,9 +3083,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" +checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" dependencies = [ "cfg-if", "js-sys", @@ -3110,9 +3095,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3120,9 +3105,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ "proc-macro2", "quote", @@ -3133,15 +3118,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" dependencies = [ "js-sys", "wasm-bindgen", @@ -3224,9 +3209,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ "windows_aarch64_msvc", "windows_i686_gnu", @@ -3237,33 +3222,33 @@ dependencies = [ [[package]] name = "windows_aarch64_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_i686_gnu" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_x86_64_gnu" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_msvc" -version = "0.32.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "winreg" @@ -3296,7 +3281,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab8bd5c76eebb8380b26833d30abddbdd885b00dd06178412e0d51d5bfc221f" dependencies = [ - "heck 0.4.0", + "heck", "log", "proc-macro2", "quote", @@ -3306,15 +3291,16 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6fa4aa90e99fb8d701bda16fb040d8ed2f9c7176fb44de750e880a74b580315" +checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d" dependencies = [ "aes", "byteorder", "bzip2", "constant_time_eq", "crc32fast", + "crossbeam-utils", "flate2", "hmac 0.12.1", "pbkdf2", @@ -3325,18 +3311,18 @@ dependencies = [ [[package]] name = "zstd" -version = "0.10.0+zstd.1.5.2" +version = "0.10.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd" +checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "4.1.4+zstd.1.5.2" +version = "4.1.6+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee" +checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb" dependencies = [ "libc", "zstd-sys", diff --git a/Cargo.toml b/Cargo.toml index 68f9ec296..c8b6be8ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,11 +14,11 @@ path = "src/main.rs" [dependencies] actix = "0.13.0" -actix-web = "4.0.1" +actix-web = { git = "https://github.com/modrinth/actix-web", rev = "88c7c18" } actix-rt = "2.7.0" tokio-stream = "0.1.8" -actix-multipart = "0.4.0" -actix-cors = "0.6.1" +actix-multipart = { git = "https://github.com/modrinth/actix-web", rev = "88c7c18" } +actix-cors = { git = "https://github.com/modrinth/actix-extras.git", rev = "34d301f" } meilisearch-sdk = "0.15.0" reqwest = { version = "0.11.10", features = ["json"] } diff --git a/migrations/20220526040434_dep-file-names.sql b/migrations/20220526040434_dep-file-names.sql new file mode 100644 index 000000000..f6b94187b --- /dev/null +++ b/migrations/20220526040434_dep-file-names.sql @@ -0,0 +1,2 @@ +ALTER TABLE dependencies +ADD COLUMN dependency_file_name varchar(1024) NULL; \ No newline at end of file diff --git a/sqlx-data.json b/sqlx-data.json index c416dd427..ad45ae6cc 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -1862,6 +1862,22 @@ ] } }, + "5f94e9e767ec4be7f9136b991b4a29373dbe48feb2f61281e3212721095ed675": { + "query": "\n INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id, dependency_file_name)\n VALUES ($1, $2, $3, $4, $5)\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Varchar", + "Int8", + "Int8", + "Varchar" + ] + }, + "nullable": [] + } + }, "5ff8fd471ff62f86aa95e52cee2723b31ec3d7fc53c3ef1454df40eef0ceff53": { "query": "\n SELECT version.id FROM (\n SELECT DISTINCT ON(v.id) v.id, v.date_published FROM versions v\n INNER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n INNER JOIN game_versions gv on gvv.game_version_id = gv.id AND (cardinality($2::varchar[]) = 0 OR gv.version = ANY($2::varchar[]))\n INNER JOIN loaders_versions lv ON lv.version_id = v.id\n INNER JOIN loaders l on lv.loader_id = l.id AND (cardinality($3::varchar[]) = 0 OR l.loader = ANY($3::varchar[]))\n WHERE v.mod_id = $1\n ) AS version\n ORDER BY version.date_published ASC\n ", "describe": { @@ -1986,6 +2002,44 @@ ] } }, + "6347536d5bf9c2c9bd830fbdc03457df7eafcb2d58a4846589316e5bc72a2020": { + "query": "\n SELECT dependency_id, mod_dependency_id, dependency_file_name, dependency_type\n FROM dependencies\n WHERE dependent_id = $1\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "dependency_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "mod_dependency_id", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "dependency_file_name", + "type_info": "Varchar" + }, + { + "ordinal": 3, + "name": "dependency_type", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [ + true, + true, + true, + false + ] + } + }, "67d021f0776276081d3c50ca97afa6b78b98860bf929009e845e9c00a192e3b5": { "query": "\n SELECT id FROM report_types\n WHERE name = $1\n ", "describe": { @@ -2457,6 +2511,27 @@ ] } }, + "7cae1137ab3aaa8de1617d820fb5635eb7498e61174e79da3cdd0da7e99aaca3": { + "query": "SELECT EXISTS(SELECT 1 FROM versions WHERE (version_number = $1) AND (mod_id = $2))", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Int8" + ] + }, + "nullable": [ + null + ] + } + }, "8129255d25bf0624d83f50558b668ed7b7f9c264e380d276522fc82bc871939b": { "query": "\n INSERT INTO notifications_actions (\n notification_id, title, action_route, action_route_method\n )\n VALUES (\n $1, $2, $3, $4\n )\n ", "describe": { @@ -2849,153 +2924,6 @@ "nullable": [] } }, - "90bc0bbac72f7b8b8433555309adee07610ae9ae2438610e3adf55909b9f2794": { - "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.published published,\n m.updated updated,\n m.team_id team_id, m.license license, m.slug slug,\n s.status status_name, cs.name client_side_type, ss.name server_side_type, l.short short, pt.name project_type_name, u.username username,\n STRING_AGG(DISTINCT c.category, ',') categories, STRING_AGG(DISTINCT lo.loader, ',') loaders, STRING_AGG(DISTINCT gv.version, ',') versions,\n STRING_AGG(DISTINCT mg.image_url, ',') gallery\n FROM mods m\n LEFT OUTER JOIN mods_categories mc ON joining_mod_id = m.id\n LEFT OUTER JOIN categories c ON mc.joining_category_id = c.id\n LEFT OUTER JOIN versions v ON v.mod_id = m.id\n LEFT OUTER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n LEFT OUTER JOIN game_versions gv ON gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv ON lv.version_id = v.id\n LEFT OUTER JOIN loaders lo ON lo.id = lv.loader_id\n LEFT OUTER JOIN mods_gallery mg ON mg.mod_id = m.id\n INNER JOIN statuses s ON s.id = m.status\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n INNER JOIN licenses l ON m.license = l.id\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.role = $2 AND tm.accepted = TRUE\n INNER JOIN users u ON tm.user_id = u.id\n WHERE m.id = $1\n GROUP BY m.id, s.id, cs.id, ss.id, l.id, pt.id, u.id;\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "project_type", - "type_info": "Int4" - }, - { - "ordinal": 2, - "name": "title", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "description", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "downloads", - "type_info": "Int4" - }, - { - "ordinal": 5, - "name": "follows", - "type_info": "Int4" - }, - { - "ordinal": 6, - "name": "icon_url", - "type_info": "Varchar" - }, - { - "ordinal": 7, - "name": "published", - "type_info": "Timestamptz" - }, - { - "ordinal": 8, - "name": "updated", - "type_info": "Timestamptz" - }, - { - "ordinal": 9, - "name": "team_id", - "type_info": "Int8" - }, - { - "ordinal": 10, - "name": "license", - "type_info": "Int4" - }, - { - "ordinal": 11, - "name": "slug", - "type_info": "Varchar" - }, - { - "ordinal": 12, - "name": "status_name", - "type_info": "Varchar" - }, - { - "ordinal": 13, - "name": "client_side_type", - "type_info": "Varchar" - }, - { - "ordinal": 14, - "name": "server_side_type", - "type_info": "Varchar" - }, - { - "ordinal": 15, - "name": "short", - "type_info": "Varchar" - }, - { - "ordinal": 16, - "name": "project_type_name", - "type_info": "Varchar" - }, - { - "ordinal": 17, - "name": "username", - "type_info": "Varchar" - }, - { - "ordinal": 18, - "name": "categories", - "type_info": "Text" - }, - { - "ordinal": 19, - "name": "loaders", - "type_info": "Text" - }, - { - "ordinal": 20, - "name": "versions", - "type_info": "Text" - }, - { - "ordinal": 21, - "name": "gallery", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Int8", - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - false, - true, - false, - false, - false, - false, - false, - false, - null, - null, - null, - null - ] - } - }, "9348309884811e8b22f33786ae7c0f259f37f3c90e545f00761a641570107160": { "query": "\n SELECT m.title title, m.id id, pt.name project_type\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n WHERE m.team_id = $1\n ", "describe": { @@ -3028,16 +2956,6 @@ ] } }, - "94a823b6e8b2610d72843008706c448432aab21690b4727aea77ad687a98f634": { - "query": "\n DELETE FROM dependencies WHERE mod_dependency_id = NULL AND dependency_id = NULL\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [] - }, - "nullable": [] - } - }, "94ca18bf5244b0add2e6a12edfdc8d67159eed8c5afdf690f9b702faed249a4c": { "query": "\n SELECT gv.version game_version\n FROM game_versions_versions gvv\n INNER JOIN game_versions gv on gvv.game_version_id = gv.id\n WHERE gvv.joining_version_id = $1\n ORDER BY gv.created\n ", "describe": { @@ -3271,38 +3189,6 @@ "nullable": [] } }, - "9dfee6ef2fd11e7664b73b72611670c2a2f8f0b8887a6cabbc3f115b1de4675d": { - "query": "\n SELECT dependency_id, mod_dependency_id, dependency_type\n FROM dependencies\n WHERE dependent_id = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "dependency_id", - "type_info": "Int8" - }, - { - "ordinal": 1, - "name": "mod_dependency_id", - "type_info": "Int8" - }, - { - "ordinal": 2, - "name": "dependency_type", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int8" - ] - }, - "nullable": [ - true, - true, - false - ] - } - }, "9f1f1039e8e360092e046b219fe6861368f5b4a338041d426ef689981f0cb9df": { "query": "\n SELECT id, filename, is_primary, url, size\n FROM files\n WHERE version_id = $1\n ", "describe": { @@ -3870,6 +3756,16 @@ ] } }, + "ae1686b8b566dd7ecc57c653c9313a4b324a2ec3a63aa6a44ed1d8ea7999b115": { + "query": "\n DELETE FROM dependencies WHERE mod_dependency_id = NULL AND dependency_id = NULL AND dependency_file_name = NULL\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + } + }, "b030a9e0fdb75eee8ee50aafdcb6063a073e2aa53cc70d40ed46437c1d0dfe80": { "query": "\n INSERT INTO mods_gallery (\n mod_id, image_url, featured, title, description\n )\n VALUES (\n $1, $2, $3, $4, $5\n )\n ", "describe": { @@ -4370,21 +4266,6 @@ "nullable": [] } }, - "c11f52e25edd7239a7a499c55d7127b4f51786e1b7666e3c61925c49fb41e05e": { - "query": "\n INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id)\n VALUES ($1, $2, $3, $4)\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Int8", - "Int8" - ] - }, - "nullable": [] - } - }, "c1a3f6dcef6110d6ea884670fb82bac14b98e922bb5673c048ccce7b7300539b": { "query": "\n SELECT EXISTS(SELECT 1 FROM reports WHERE id = $1)\n ", "describe": { @@ -4738,6 +4619,38 @@ "nullable": [] } }, + "cfcc6970c0b469c4afd37bedfd386def7980f6b7006030d4783723861d0e3a38": { + "query": "\n SELECT v.id version_id, v.mod_id project_id, h.hash hash FROM hashes h\n INNER JOIN files f on h.file_id = f.id\n INNER JOIN versions v on f.version_id = v.id\n WHERE h.algorithm = 'sha1' AND h.hash = ANY($1)\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "version_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "project_id", + "type_info": "Int8" + }, + { + "ordinal": 2, + "name": "hash", + "type_info": "Bytea" + } + ], + "parameters": { + "Left": [ + "ByteaArray" + ] + }, + "nullable": [ + true, + true, + true + ] + } + }, "d03630ab0ff37f5f0a8c088558fdc8a1955bad78bea282c40f72d15e5cf77a79": { "query": "\n SELECT v.id id\n FROM versions v\n INNER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id AND gvv.game_version_id = ANY($2)\n INNER JOIN loaders_versions lv ON lv.version_id = v.id AND lv.loader_id = ANY($3)\n WHERE v.mod_id = $1\n ORDER BY v.date_published DESC\n LIMIT 1\n ", "describe": { @@ -5990,27 +5903,6 @@ ] } }, - "fcb0ceeacfa2fa0f8f1f1987e744dabb73c26ac0fb8178ad9b3b9ebb3bd0acac": { - "query": "SELECT EXISTS(SELECT 1 FROM versions WHERE (version_number=$1) AND (mod_id=$2))", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "exists", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text", - "Int8" - ] - }, - "nullable": [ - null - ] - } - }, "fd00809bd75662a8f21d812fd00071b4208f88186d9f86badece97c9c95ad3b9": { "query": "\n SELECT id\n FROM versions\n WHERE mod_id = $1\n ", "describe": { diff --git a/src/database/models/version_item.rs b/src/database/models/version_item.rs index 95db02a42..d9356ae5a 100644 --- a/src/database/models/version_item.rs +++ b/src/database/models/version_item.rs @@ -21,6 +21,7 @@ pub struct VersionBuilder { pub struct DependencyBuilder { pub project_id: Option, pub version_id: Option, + pub file_name: Option, pub dependency_type: String, } @@ -59,13 +60,14 @@ impl DependencyBuilder { sqlx::query!( " - INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id) - VALUES ($1, $2, $3, $4) + INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id, dependency_file_name) + VALUES ($1, $2, $3, $4, $5) ", version_id as VersionId, self.dependency_type, version_dependency_id.map(|x| x.0), project_dependency_id.map(|x| x.0), + self.file_name, ) .execute(&mut *transaction) .await?; @@ -455,7 +457,7 @@ impl Version { sqlx::query!( " - DELETE FROM dependencies WHERE mod_dependency_id = NULL AND dependency_id = NULL + DELETE FROM dependencies WHERE mod_dependency_id = NULL AND dependency_id = NULL AND dependency_file_name = NULL ", ) .execute(&mut *transaction) @@ -659,7 +661,7 @@ impl Version { ).fetch_all(executor), sqlx::query!( " - SELECT dependency_id, mod_dependency_id, dependency_type + SELECT dependency_id, mod_dependency_id, dependency_file_name, dependency_type FROM dependencies WHERE dependent_id = $1 ", @@ -716,6 +718,7 @@ impl Version { .map(|x| QueryDependency { project_id: x.mod_dependency_id.map(ProjectId), version_id: x.dependency_id.map(VersionId), + file_name: x.dependency_file_name, dependency_type: x.dependency_type, }) .collect(), @@ -779,6 +782,7 @@ pub struct QueryVersion { pub struct QueryDependency { pub project_id: Option, pub version_id: Option, + pub file_name: Option, pub dependency_type: String, } diff --git a/src/main.rs b/src/main.rs index 758d30e48..e3c40b367 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,6 @@ use gumdrop::Options; use log::{error, info, warn}; use search::indexing::index_projects; use search::indexing::IndexingSettings; -use std::sync::atomic::Ordering; use std::sync::Arc; mod database; @@ -182,33 +181,6 @@ async fn main() -> std::io::Result<()> { } }); - let indexing_queue = - Arc::new(search::indexing::queue::CreationQueue::new()); - - let mut skip = skip_initial; - let queue_ref = indexing_queue.clone(); - let search_config_ref = search_config.clone(); - scheduler.run(std::time::Duration::from_secs(15 * 60), move || { - let queue_ref = queue_ref.clone(); - let search_config_ref = search_config_ref.clone(); - let local_skip = skip; - if skip { - skip = false; - } - async move { - if local_skip { - return; - } - info!("Indexing created project queue"); - let result = queue_ref.index(&search_config_ref).await; - if let Err(e) = result { - warn!("Indexing created projects failed: {:?}", e); - } - crate::health::SEARCH_READY.store(true, Ordering::Release); - info!("Done indexing created project queue"); - } - }); - scheduler::schedule_versions(&mut scheduler, pool.clone(), skip_initial); let ip_salt = Pepper { @@ -270,7 +242,6 @@ async fn main() -> std::io::Result<()> { ) .app_data(web::Data::new(pool.clone())) .app_data(web::Data::new(file_host.clone())) - .app_data(web::Data::new(indexing_queue.clone())) .app_data(web::Data::new(search_config.clone())) .app_data(web::Data::new(ip_salt.clone())) .configure(routes::v1_config) diff --git a/src/models/mod.rs b/src/models/mod.rs index 0c9b7c58e..a46084523 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,6 +1,7 @@ pub mod error; pub mod ids; pub mod notifications; +pub mod pack; pub mod projects; pub mod reports; pub mod teams; diff --git a/src/models/pack.rs b/src/models/pack.rs new file mode 100644 index 000000000..760d39eba --- /dev/null +++ b/src/models/pack.rs @@ -0,0 +1,111 @@ +use crate::models::projects::SideType; +use crate::parse_strings_from_var; +use serde::{Deserialize, Serialize}; +use validator::Validate; + +#[derive(Serialize, Deserialize, Validate, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct PackFormat { + pub game: String, + pub format_version: i32, + #[validate(length(min = 3, max = 512))] + pub version_id: String, + #[validate(length(min = 3, max = 512))] + pub name: String, + #[validate(length(max = 2048))] + pub summary: Option, + #[validate] + pub files: Vec, + pub dependencies: std::collections::HashMap, +} + +#[derive(Serialize, Deserialize, Validate, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct PackFile { + pub path: String, + pub hashes: std::collections::HashMap, + pub env: Option>, + #[validate(custom(function = "validate_download_url"))] + pub downloads: Vec, + pub file_size: u32, +} + +fn validate_download_url( + values: &[String], +) -> Result<(), validator::ValidationError> { + for value in values { + let url = url::Url::parse(value) + .ok() + .ok_or_else(|| validator::ValidationError::new("invalid URL"))?; + + if url.as_str() != value { + return Err(validator::ValidationError::new("invalid URL")); + } + + let domains = parse_strings_from_var("WHITELISTED_MODPACK_DOMAINS") + .unwrap_or_default(); + if !domains.contains( + &url.domain() + .ok_or_else(|| validator::ValidationError::new("invalid URL"))? + .to_string(), + ) { + return Err(validator::ValidationError::new( + "File download source is not from allowed sources", + )); + } + } + + Ok(()) +} + +#[derive(Serialize, Deserialize, Eq, PartialEq, Hash)] +#[serde(rename_all = "camelCase", from = "String")] +pub enum PackFileHash { + Sha1, + Sha512, + Unknown(String), +} + +impl From for PackFileHash { + fn from(s: String) -> Self { + return match s.as_str() { + "sha1" => PackFileHash::Sha1, + "sha512" => PackFileHash::Sha512, + _ => PackFileHash::Unknown(s), + }; + } +} + +#[derive(Serialize, Deserialize, Eq, PartialEq, Hash)] +#[serde(rename_all = "camelCase")] +pub enum EnvType { + Client, + Server, +} + +#[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +pub enum PackDependency { + Forge, + FabricLoader, + QuiltLoader, + Minecraft, +} + +impl std::fmt::Display for PackDependency { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fmt.write_str(self.as_str()) + } +} + +impl PackDependency { + // These are constant, so this can remove unnecessary allocations (`to_string`) + pub fn as_str(&self) -> &'static str { + match self { + PackDependency::Forge => "forge", + PackDependency::FabricLoader => "fabric-loader", + PackDependency::Minecraft => "minecraft", + PackDependency::QuiltLoader => "quilt-loader", + } + } +} diff --git a/src/models/projects.rs b/src/models/projects.rs index 2bae927c8..16f78c7bd 100644 --- a/src/models/projects.rs +++ b/src/models/projects.rs @@ -166,7 +166,7 @@ pub struct ModeratorMessage { pub body: Option, } -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] #[serde(rename_all = "kebab-case")] pub enum SideType { Required, @@ -368,6 +368,7 @@ impl From for Version { .map(|d| Dependency { 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(), ), @@ -399,7 +400,7 @@ pub struct VersionFile { pub size: u32, } -/// A dependency which describes what versions are required, break support, or are optional to the +/// A dendency which describes what versions are required, break support, or are optional to the /// version's functionality #[derive(Serialize, Deserialize, Clone)] pub struct Dependency { @@ -407,6 +408,8 @@ pub struct Dependency { pub version_id: Option, /// The project ID that the dependency is synced with and auto-updated pub project_id: Option, + /// The filename of the dependency. Used exclusively for external mods on modpacks + pub file_name: Option, /// The type of the dependency pub dependency_type: DependencyType, } diff --git a/src/routes/project_creation.rs b/src/routes/project_creation.rs index 1a1c7a9e4..0e52053eb 100644 --- a/src/routes/project_creation.rs +++ b/src/routes/project_creation.rs @@ -17,6 +17,7 @@ use actix_web::{post, HttpRequest, HttpResponse}; use futures::stream::StreamExt; use serde::{Deserialize, Serialize}; use sqlx::postgres::PgPool; +use std::collections::HashSet; use std::sync::Arc; use thiserror::Error; use time::OffsetDateTime; @@ -357,6 +358,12 @@ pub async fn project_create_inner( CreateError::InvalidInput(validation_errors_to_string(err, None)) })?; + let mut uniq = HashSet::new(); + create_data + .initial_versions + .iter() + .all(|x| uniq.insert(x.version_number.clone())); + let slug_project_id_option: Option = serde_json::from_str(&*format!("\"{}\"", create_data.slug)).ok(); @@ -542,6 +549,7 @@ pub async fn project_create_inner( file_host, uploaded_files, &mut created_version.files, + &mut created_version.dependencies, &cdn_url, &content_disposition, project_id, @@ -824,6 +832,7 @@ async fn create_initial_version( version_id: d.version_id.map(|x| x.into()), project_id: d.project_id.map(|x| x.into()), dependency_type: d.dependency_type.to_string(), + file_name: None, }) .collect::>(); diff --git a/src/routes/projects.rs b/src/routes/projects.rs index d2ff936cc..37609361c 100644 --- a/src/routes/projects.rs +++ b/src/routes/projects.rs @@ -6,12 +6,10 @@ use crate::models::projects::{ }; use crate::models::teams::Permissions; use crate::routes::ApiError; -use crate::search::indexing::queue::CreationQueue; use crate::search::{search_for_project, SearchConfig, SearchError}; use crate::util::auth::{get_user_from_headers, is_authorized}; use crate::util::routes::read_from_payload; use crate::util::validate::validation_errors_to_string; -use actix_web::web::Data; use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse}; use futures::StreamExt; use serde::{Deserialize, Serialize}; @@ -278,7 +276,6 @@ pub async fn project_edit( pool: web::Data, config: web::Data, new_project: web::Json, - indexing_queue: Data>, ) -> Result { let user = get_user_from_headers(req.headers(), &**pool).await?; @@ -442,17 +439,6 @@ pub async fn project_edit( && !status.is_searchable() { delete_from_index(id.into(), config).await?; - } else if !project_item.status.is_searchable() - && status.is_searchable() - { - // let index_project = - // crate::search::indexing::local_import::query_one( - // id, - // &mut *transaction, - // ) - // .await?; - // - // indexing_queue.add(index_project); } } diff --git a/src/routes/version_creation.rs b/src/routes/version_creation.rs index 0f1278ffc..df9fc0b08 100644 --- a/src/routes/version_creation.rs +++ b/src/routes/version_creation.rs @@ -1,12 +1,13 @@ use crate::database::models; use crate::database::models::notification_item::NotificationBuilder; use crate::database::models::version_item::{ - VersionBuilder, VersionFileBuilder, + DependencyBuilder, VersionBuilder, VersionFileBuilder, }; use crate::file_hosting::FileHost; +use crate::models::pack::PackFileHash; use crate::models::projects::{ - Dependency, GameVersion, Loader, ProjectId, Version, VersionFile, - VersionId, VersionType, + Dependency, DependencyType, GameVersion, Loader, ProjectId, Version, + VersionFile, VersionId, VersionType, }; use crate::models::teams::Permissions; use crate::routes::project_creation::{CreateError, UploadedFile}; @@ -171,7 +172,7 @@ async fn version_create_inner( // Check whether there is already a version of this project with the // same version number let results = sqlx::query!( - "SELECT EXISTS(SELECT 1 FROM versions WHERE (version_number=$1) AND (mod_id=$2))", + "SELECT EXISTS(SELECT 1 FROM versions WHERE (version_number = $1) AND (mod_id = $2))", version_create_data.version_number, project_id as models::ProjectId, ) @@ -262,6 +263,7 @@ async fn version_create_inner( version_id: d.version_id.map(|x| x.into()), project_id: d.project_id.map(|x| x.into()), dependency_type: d.dependency_type.to_string(), + file_name: None, }) .collect::>(); @@ -313,6 +315,7 @@ async fn version_create_inner( file_host, uploaded_files, &mut version.files, + &mut version.dependencies, &cdn_url, &content_disposition, version.project_id.into(), @@ -579,11 +582,23 @@ async fn upload_file_to_version_inner( )) })?; + let mut dependencies = version + .dependencies + .iter() + .map(|x| models::version_item::DependencyBuilder { + project_id: x.project_id, + version_id: x.version_id, + file_name: None, + dependency_type: x.dependency_type.clone(), + }) + .collect(); + upload_file( &mut field, file_host, uploaded_files, &mut file_builders, + &mut dependencies, &cdn_url, &content_disposition, project_id, @@ -625,6 +640,7 @@ pub async fn upload_file( file_host: &dyn FileHost, uploaded_files: &mut Vec, version_files: &mut Vec, + dependencies: &mut Vec, cdn_url: &str, content_disposition: &actix_web::http::header::ContentDisposition, project_id: crate::models::ids::ProjectId, @@ -680,6 +696,66 @@ pub async fn upload_file( ) .await?; + if let ValidationResult::PassWithPackData(ref data) = validation_result { + if dependencies.is_empty() { + let hashes: Vec> = data + .files + .iter() + .filter_map(|x| x.hashes.get(&PackFileHash::Sha1)) + .map(|x| x.as_bytes().to_vec()) + .collect(); + + let res = sqlx::query!( + " + SELECT v.id version_id, v.mod_id project_id, h.hash hash FROM hashes h + INNER JOIN files f on h.file_id = f.id + INNER JOIN versions v on f.version_id = v.id + WHERE h.algorithm = 'sha1' AND h.hash = ANY($1) + ", + &*hashes + ) + .fetch_all(&mut *transaction).await?; + + for file in &data.files { + if let Some(dep) = res.iter().find(|x| { + x.hash.as_deref() + == file + .hashes + .get(&PackFileHash::Sha1) + .map(|x| x.as_bytes()) + }) { + if let Some(project_id) = dep.project_id { + if let Some(version_id) = dep.version_id { + dependencies.push(DependencyBuilder { + project_id: Some(models::ProjectId(project_id)), + version_id: Some(models::VersionId(version_id)), + file_name: None, + dependency_type: DependencyType::Required + .to_string(), + }); + } + } + } else { + if let Some(first_download) = file.downloads.first() { + dependencies.push(DependencyBuilder { + project_id: None, + version_id: None, + file_name: Some( + first_download + .rsplit('/') + .next() + .unwrap_or(first_download) + .to_string(), + ), + dependency_type: DependencyType::Required + .to_string(), + }); + } + } + } + } + } + let file_path_encode = format!( "data/{}/versions/{}/{}", project_id, @@ -700,6 +776,20 @@ pub async fn upload_file( file_name: file_path, }); + let sha1_bytes = upload_data.content_sha1.into_bytes(); + let sha512_bytes = upload_data.content_sha512.into_bytes(); + + if version_files.iter().any(|x| { + x.hashes + .iter() + .any(|y| y.hash == sha1_bytes || y.hash == sha512_bytes) + }) { + return Err(CreateError::InvalidInput( + "Duplicate files are not allowed to be uploaded to Modrinth!" + .to_string(), + )); + } + version_files.push(models::version_item::VersionFileBuilder { filename: file_name.to_string(), url: format!("{}/{}", cdn_url, file_path_encode), @@ -708,16 +798,16 @@ pub async fn upload_file( algorithm: "sha1".to_string(), // This is an invalid cast - the database expects the hash's // bytes, but this is the string version. - hash: upload_data.content_sha1.into_bytes(), + hash: sha1_bytes, }, models::version_item::HashBuilder { algorithm: "sha512".to_string(), // This is an invalid cast - the database expects the hash's // bytes, but this is the string version. - hash: upload_data.content_sha512.into_bytes(), + hash: sha512_bytes, }, ], - primary: (validation_result == ValidationResult::Pass + primary: (validation_result.is_passed() && version_files.iter().all(|x| !x.primary) && !ignore_primary) || force_primary, diff --git a/src/routes/versions.rs b/src/routes/versions.rs index 75e83c14f..626886d1e 100644 --- a/src/routes/versions.rs +++ b/src/routes/versions.rs @@ -250,6 +250,21 @@ pub async fn version_edit( } if let Some(number) = &new_version.version_number { + let results = sqlx::query!( + "SELECT EXISTS(SELECT 1 FROM versions WHERE (version_number = $1) AND (mod_id = $2))", + number, + version_item.project_id as database::models::ids::ProjectId, + ) + .fetch_one(&mut *transaction) + .await?; + + if results.exists.unwrap_or(true) { + return Err(ApiError::InvalidInput( + "A version with that version_number already exists" + .to_string(), + )); + } + sqlx::query!( " UPDATE versions @@ -292,6 +307,7 @@ pub async fn version_edit( .map(|x| database::models::version_item::DependencyBuilder { project_id: x.project_id.map(|x| x.into()), version_id: x.version_id.map(|x| x.into()), + file_name: x.file_name.clone(), dependency_type: x.dependency_type.to_string(), }) .collect::>(); diff --git a/src/search/indexing/local_import.rs b/src/search/indexing/local_import.rs index 761a682cd..36a743dd9 100644 --- a/src/search/indexing/local_import.rs +++ b/src/search/indexing/local_import.rs @@ -86,78 +86,6 @@ pub async fn index_local( .await? ) } -pub async fn query_one( - id: ProjectId, - exec: &mut sqlx::PgConnection, -) -> Result { - let m = sqlx::query!( - //region query - " - SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows, - m.icon_url icon_url, m.published published, - m.updated updated, - m.team_id team_id, m.license license, m.slug slug, - s.status status_name, cs.name client_side_type, ss.name server_side_type, l.short short, pt.name project_type_name, u.username username, - STRING_AGG(DISTINCT c.category, ',') categories, STRING_AGG(DISTINCT lo.loader, ',') loaders, STRING_AGG(DISTINCT gv.version, ',') versions, - STRING_AGG(DISTINCT mg.image_url, ',') gallery - FROM mods m - LEFT OUTER JOIN mods_categories mc ON joining_mod_id = m.id - LEFT OUTER JOIN categories c ON mc.joining_category_id = c.id - LEFT OUTER JOIN versions v ON v.mod_id = m.id - LEFT OUTER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id - LEFT OUTER JOIN game_versions gv ON gvv.game_version_id = gv.id - LEFT OUTER JOIN loaders_versions lv ON lv.version_id = v.id - LEFT OUTER JOIN loaders lo ON lo.id = lv.loader_id - LEFT OUTER JOIN mods_gallery mg ON mg.mod_id = m.id - INNER JOIN statuses s ON s.id = m.status - INNER JOIN project_types pt ON pt.id = m.project_type - INNER JOIN side_types cs ON m.client_side = cs.id - INNER JOIN side_types ss ON m.server_side = ss.id - INNER JOIN licenses l ON m.license = l.id - INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.role = $2 AND tm.accepted = TRUE - INNER JOIN users u ON tm.user_id = u.id - WHERE m.id = $1 - GROUP BY m.id, s.id, cs.id, ss.id, l.id, pt.id, u.id; - ", - //endregion query - id as ProjectId, - crate::models::teams::OWNER_ROLE - ) - .fetch_one(exec) - .await?; - - let mut categories = split_to_strings(m.categories); - categories.append(&mut split_to_strings(m.loaders)); - let versions = split_to_strings(m.versions); - - let project_id: crate::models::projects::ProjectId = ProjectId(m.id).into(); - - Ok(UploadSearchProject { - project_id: format!("{}", project_id), - title: m.title, - description: m.description, - categories, - follows: m.follows, - downloads: m.downloads, - icon_url: m.icon_url.unwrap_or_default(), - author: m.username, - date_created: m.published, - created_timestamp: m.published.unix_timestamp(), - date_modified: m.updated, - modified_timestamp: m.updated.unix_timestamp(), - latest_version: versions - .last() - .cloned() - .unwrap_or_else(|| "None".to_string()), - versions, - license: m.short, - client_side: m.client_side_type, - server_side: m.server_side_type, - slug: m.slug, - project_type: m.project_type_name, - gallery: split_to_strings(m.gallery), - }) -} fn split_to_strings(s: Option) -> Vec { s.map(|x| x.split(',').map(ToString::to_string).collect()) diff --git a/src/search/indexing/mod.rs b/src/search/indexing/mod.rs index d9e7dec12..e8cf2a557 100644 --- a/src/search/indexing/mod.rs +++ b/src/search/indexing/mod.rs @@ -1,6 +1,5 @@ /// This module is used for the indexing from any source. pub mod local_import; -pub mod queue; use crate::search::{SearchConfig, UploadSearchProject}; use local_import::index_local; diff --git a/src/search/indexing/queue.rs b/src/search/indexing/queue.rs deleted file mode 100644 index 5db19eede..000000000 --- a/src/search/indexing/queue.rs +++ /dev/null @@ -1,36 +0,0 @@ -use super::{add_projects, IndexingError, UploadSearchProject}; -use crate::search::SearchConfig; -use std::sync::Mutex; - -pub struct CreationQueue { - // There's probably a better structure for this, but a mutex works - // and I don't think this can deadlock. This queue requires fast - // writes and then a single potentially slower read/write that - // empties the queue. - queue: Mutex>, -} - -impl CreationQueue { - pub fn new() -> Self { - CreationQueue { - queue: Mutex::new(Vec::with_capacity(10)), - } - } - pub fn add(&self, search_project: UploadSearchProject) { - // Can only panic if mutex is poisoned - self.queue.lock().unwrap().push(search_project); - } - pub fn take(&self) -> Vec { - std::mem::replace( - &mut *self.queue.lock().unwrap(), - Vec::with_capacity(10), - ) - } - pub async fn index( - &self, - config: &SearchConfig, - ) -> Result<(), IndexingError> { - let queue = self.take(); - add_projects(queue, config).await - } -} diff --git a/src/util/webhook.rs b/src/util/webhook.rs index e9b5a306c..a8ffc9f17 100644 --- a/src/util/webhook.rs +++ b/src/util/webhook.rs @@ -56,12 +56,15 @@ pub async fn send_discord_webhook( value: project.server_side.to_string(), inline: true, }, - DiscordEmbedField { + ]; + + if !project.categories.is_empty() { + fields.push(DiscordEmbedField { name: "categories", value: project.categories.join(", "), inline: true, - }, - ]; + }); + } if let Some(ref slug) = project.slug { fields.push(DiscordEmbedField { diff --git a/src/validate/liteloader.rs b/src/validate/liteloader.rs new file mode 100644 index 000000000..25b0f5d72 --- /dev/null +++ b/src/validate/liteloader.rs @@ -0,0 +1,38 @@ +use crate::validate::{ + SupportedGameVersions, ValidationError, ValidationResult, +}; +use std::io::Cursor; +use zip::ZipArchive; + +pub struct LiteLoaderValidator; + +impl super::Validator for LiteLoaderValidator { + fn get_file_extensions(&self) -> &[&str] { + &["litemod"] + } + + fn get_project_types(&self) -> &[&str] { + &["mod"] + } + + fn get_supported_loaders(&self) -> &[&str] { + &["liteloader"] + } + + fn get_supported_game_versions(&self) -> SupportedGameVersions { + SupportedGameVersions::All + } + + fn validate( + &self, + archive: &mut ZipArchive>, + ) -> Result { + archive.by_name("litemod.json").map_err(|_| { + ValidationError::InvalidInput( + "No litemod.json present for LiteLoader file.".into(), + ) + })?; + + Ok(ValidationResult::Pass) + } +} diff --git a/src/validate/mod.rs b/src/validate/mod.rs index e87d33ce0..b46d9f4ea 100644 --- a/src/validate/mod.rs +++ b/src/validate/mod.rs @@ -1,6 +1,8 @@ +use crate::models::pack::PackFormat; use crate::models::projects::{GameVersion, Loader}; use crate::validate::fabric::FabricValidator; use crate::validate::forge::{ForgeValidator, LegacyForgeValidator}; +use crate::validate::liteloader::LiteLoaderValidator; use crate::validate::pack::PackValidator; use crate::validate::quilt::QuiltValidator; use std::io::Cursor; @@ -10,6 +12,7 @@ use zip::ZipArchive; mod fabric; mod forge; +mod liteloader; mod pack; mod quilt; @@ -29,12 +32,24 @@ pub enum ValidationError { #[derive(Eq, PartialEq)] pub enum ValidationResult { + /// File should be marked as primary with pack file data + PassWithPackData(PackFormat), /// File should be marked as primary Pass, /// File should not be marked primary, the reason for which is inside the String Warning(&'static str), } +impl ValidationResult { + pub fn is_passed(&self) -> bool { + match self { + ValidationResult::PassWithPackData(_) => true, + ValidationResult::Pass => true, + ValidationResult::Warning(_) => false, + } + } +} + pub enum SupportedGameVersions { All, PastDate(OffsetDateTime), @@ -54,12 +69,13 @@ pub trait Validator: Sync { ) -> Result; } -static VALIDATORS: [&dyn Validator; 5] = [ +static VALIDATORS: [&dyn Validator; 6] = [ &PackValidator, &FabricValidator, &ForgeValidator, &LegacyForgeValidator, &QuiltValidator, + &LiteLoaderValidator, ]; /// The return value is whether this file should be marked as primary or not, based on the analysis of the file diff --git a/src/validate/pack.rs b/src/validate/pack.rs index c6b0abd1e..6b1c10836 100644 --- a/src/validate/pack.rs +++ b/src/validate/pack.rs @@ -1,120 +1,13 @@ -use crate::models::projects::SideType; -use crate::util::env::parse_strings_from_var; +use crate::models::pack::{PackFileHash, PackFormat}; use crate::util::validate::validation_errors_to_string; use crate::validate::{ SupportedGameVersions, ValidationError, ValidationResult, }; -use serde::{Deserialize, Serialize}; use std::io::{Cursor, Read}; use std::path::Component; use validator::Validate; use zip::ZipArchive; -#[derive(Serialize, Deserialize, Validate)] -#[serde(rename_all = "camelCase")] -pub struct PackFormat<'a> { - pub game: &'a str, - pub format_version: i32, - #[validate(length(min = 3, max = 512))] - pub version_id: &'a str, - #[validate(length(min = 3, max = 512))] - pub name: &'a str, - #[validate(length(max = 2048))] - pub summary: Option<&'a str>, - #[validate] - pub files: Vec>, - pub dependencies: std::collections::HashMap, -} - -#[derive(Serialize, Deserialize, Validate)] -#[serde(rename_all = "camelCase")] -pub struct PackFile<'a> { - pub path: &'a str, - pub hashes: std::collections::HashMap, - pub env: Option>, - #[validate(custom(function = "validate_download_url"))] - pub downloads: Vec<&'a str>, - pub file_size: u32, -} - -fn validate_download_url( - values: &[&str], -) -> Result<(), validator::ValidationError> { - for value in values { - let url = url::Url::parse(value) - .ok() - .ok_or_else(|| validator::ValidationError::new("invalid URL"))?; - - if &url.as_str() != value { - return Err(validator::ValidationError::new("invalid URL")); - } - - let domains = parse_strings_from_var("WHITELISTED_MODPACK_DOMAINS") - .unwrap_or_default(); - if !domains.contains( - &url.domain() - .ok_or_else(|| validator::ValidationError::new("invalid URL"))? - .to_string(), - ) { - return Err(validator::ValidationError::new( - "File download source is not from allowed sources", - )); - } - } - - Ok(()) -} - -#[derive(Serialize, Deserialize, Eq, PartialEq, Hash)] -#[serde(rename_all = "camelCase", from = "String")] -pub enum FileHash { - Sha1, - Sha512, - Unknown(String), -} - -impl From for FileHash { - fn from(s: String) -> Self { - return match s.as_str() { - "sha1" => FileHash::Sha1, - "sha512" => FileHash::Sha512, - _ => FileHash::Unknown(s), - }; - } -} - -#[derive(Serialize, Deserialize, Eq, PartialEq, Hash)] -#[serde(rename_all = "camelCase")] -pub enum EnvType { - Client, - Server, -} - -#[derive(Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] -#[serde(rename_all = "kebab-case")] -pub enum PackDependency { - Forge, - FabricLoader, - Minecraft, -} - -impl std::fmt::Display for PackDependency { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - fmt.write_str(self.as_str()) - } -} - -impl PackDependency { - // These are constant, so this can remove unnecessary allocations (`to_string`) - pub fn as_str(&self) -> &'static str { - match self { - PackDependency::Forge => "forge", - PackDependency::FabricLoader => "fabric-loader", - PackDependency::Minecraft => "minecraft", - } - } -} - pub struct PackValidator; impl super::Validator for PackValidator { @@ -162,20 +55,20 @@ impl super::Validator for PackValidator { )); } - for file in pack.files { - if file.hashes.get(&FileHash::Sha1).is_none() { + for file in &pack.files { + if file.hashes.get(&PackFileHash::Sha1).is_none() { return Err(ValidationError::InvalidInput( "All pack files must provide a SHA1 hash!".into(), )); } - if file.hashes.get(&FileHash::Sha512).is_none() { + if file.hashes.get(&PackFileHash::Sha512).is_none() { return Err(ValidationError::InvalidInput( "All pack files must provide a SHA512 hash!".into(), )); } - let path = std::path::Path::new(file.path) + let path = std::path::Path::new(&file.path) .components() .next() .ok_or_else(|| { @@ -194,6 +87,6 @@ impl super::Validator for PackValidator { }; } - Ok(ValidationResult::Pass) + Ok(ValidationResult::PassWithPackData(pack)) } }