feat: scaffold services/january
This commit is contained in:
277
Cargo.lock
generated
277
Cargo.lock
generated
@@ -229,7 +229,7 @@ dependencies = [
|
|||||||
"async-channel 1.6.1",
|
"async-channel 1.6.1",
|
||||||
"async-executor",
|
"async-executor",
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"blocking",
|
"blocking",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -265,6 +265,17 @@ dependencies = [
|
|||||||
"event-listener 2.5.2",
|
"event-listener 2.5.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-lock"
|
||||||
|
version = "3.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
|
||||||
|
dependencies = [
|
||||||
|
"event-listener 5.3.1",
|
||||||
|
"event-listener-strategy",
|
||||||
|
"pin-project-lite 0.2.13",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-process"
|
name = "async-process"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -303,7 +314,7 @@ dependencies = [
|
|||||||
"async-channel 1.6.1",
|
"async-channel 1.6.1",
|
||||||
"async-global-executor",
|
"async-global-executor",
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"async-process",
|
"async-process",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@@ -435,7 +446,7 @@ dependencies = [
|
|||||||
"nanoid",
|
"nanoid",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest 0.11.10",
|
||||||
"revolt_okapi",
|
"revolt_okapi",
|
||||||
"revolt_rocket_okapi",
|
"revolt_rocket_okapi",
|
||||||
"rocket",
|
"rocket",
|
||||||
@@ -899,6 +910,29 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-extra"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"axum-core",
|
||||||
|
"bytes 1.5.0",
|
||||||
|
"futures-util",
|
||||||
|
"headers",
|
||||||
|
"http 1.1.0",
|
||||||
|
"http-body 1.0.0",
|
||||||
|
"http-body-util",
|
||||||
|
"mime",
|
||||||
|
"pin-project-lite 0.2.13",
|
||||||
|
"serde",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum_typed_multipart"
|
name = "axum_typed_multipart"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
@@ -1407,6 +1441,24 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.5.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-queue"
|
name = "crossbeam-queue"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
@@ -1997,7 +2049,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "fc9ed4ed7618b2f7581edb6ce28794a10fcc335e196fc2bcf56afee99ad63d10"
|
checksum = "fc9ed4ed7618b2f7581edb6ce28794a10fcc335e196fc2bcf56afee99ad63d10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"reqwest",
|
"reqwest 0.11.10",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"yup-oauth2",
|
"yup-oauth2",
|
||||||
@@ -2441,6 +2493,30 @@ dependencies = [
|
|||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "headers"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.21.3",
|
||||||
|
"bytes 1.5.0",
|
||||||
|
"headers-core",
|
||||||
|
"http 1.1.0",
|
||||||
|
"httpdate",
|
||||||
|
"mime",
|
||||||
|
"sha1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "headers-core"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
||||||
|
dependencies = [
|
||||||
|
"http 1.1.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@@ -2690,6 +2766,22 @@ dependencies = [
|
|||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-tls"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||||
|
dependencies = [
|
||||||
|
"bytes 1.5.0",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper 1.3.1",
|
||||||
|
"hyper-util",
|
||||||
|
"native-tls",
|
||||||
|
"tokio 1.35.1",
|
||||||
|
"tokio-native-tls",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@@ -2981,11 +3073,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"spin 0.5.2",
|
"spin 0.9.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3243,9 +3335,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.16"
|
version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
@@ -3303,6 +3395,30 @@ dependencies = [
|
|||||||
"redis 0.22.3",
|
"redis 0.22.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "moka"
|
||||||
|
version = "0.12.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f"
|
||||||
|
dependencies = [
|
||||||
|
"async-lock 3.4.0",
|
||||||
|
"async-trait",
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"event-listener 5.3.1",
|
||||||
|
"futures-util",
|
||||||
|
"once_cell",
|
||||||
|
"parking_lot",
|
||||||
|
"quanta",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
"smallvec",
|
||||||
|
"tagptr",
|
||||||
|
"thiserror",
|
||||||
|
"triomphe",
|
||||||
|
"uuid 1.4.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mongodb"
|
name = "mongodb"
|
||||||
version = "2.2.2"
|
version = "2.2.2"
|
||||||
@@ -4081,6 +4197,21 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quanta"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"raw-cpuid",
|
||||||
|
"wasi",
|
||||||
|
"web-sys",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "querystring"
|
name = "querystring"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
@@ -4251,6 +4382,15 @@ dependencies = [
|
|||||||
"rand_core 0.3.1",
|
"rand_core 0.3.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raw-cpuid"
|
||||||
|
version = "11.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rdrand"
|
name = "rdrand"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@@ -4424,7 +4564,7 @@ dependencies = [
|
|||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"http-body 0.4.5",
|
"http-body 0.4.5",
|
||||||
"hyper 0.14.30",
|
"hyper 0.14.30",
|
||||||
"hyper-tls",
|
"hyper-tls 0.5.0",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -4445,6 +4585,48 @@ dependencies = [
|
|||||||
"winreg 0.10.1",
|
"winreg 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwest"
|
||||||
|
version = "0.12.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"bytes 1.5.0",
|
||||||
|
"encoding_rs",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"h2 0.4.5",
|
||||||
|
"http 1.1.0",
|
||||||
|
"http-body 1.0.0",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper 1.3.1",
|
||||||
|
"hyper-tls 0.6.0",
|
||||||
|
"hyper-util",
|
||||||
|
"ipnet",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"native-tls",
|
||||||
|
"once_cell",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite 0.2.13",
|
||||||
|
"rustls-pemfile 2.1.2",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"sync_wrapper 0.1.2",
|
||||||
|
"system-configuration",
|
||||||
|
"tokio 1.35.1",
|
||||||
|
"tokio-native-tls",
|
||||||
|
"tower-service",
|
||||||
|
"url",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"winreg 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "resolv-conf"
|
name = "resolv-conf"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -4462,6 +4644,7 @@ dependencies = [
|
|||||||
"axum",
|
"axum",
|
||||||
"axum_typed_multipart",
|
"axum_typed_multipart",
|
||||||
"revolt-config",
|
"revolt-config",
|
||||||
|
"revolt-result",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@@ -4522,7 +4705,7 @@ dependencies = [
|
|||||||
name = "revolt-database"
|
name = "revolt-database"
|
||||||
version = "0.7.16"
|
version = "0.7.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock 2.8.0",
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
"async-std",
|
"async-std",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -4590,7 +4773,7 @@ dependencies = [
|
|||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"redis-kiss",
|
"redis-kiss",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest 0.11.10",
|
||||||
"revolt-config",
|
"revolt-config",
|
||||||
"revolt-database",
|
"revolt-database",
|
||||||
"revolt-models",
|
"revolt-models",
|
||||||
@@ -4621,6 +4804,28 @@ dependencies = [
|
|||||||
"aws-sdk-s3",
|
"aws-sdk-s3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "revolt-january"
|
||||||
|
version = "0.7.14"
|
||||||
|
dependencies = [
|
||||||
|
"axum",
|
||||||
|
"axum-extra",
|
||||||
|
"lazy_static",
|
||||||
|
"mime",
|
||||||
|
"moka",
|
||||||
|
"reqwest 0.12.4",
|
||||||
|
"revolt-config",
|
||||||
|
"revolt-models",
|
||||||
|
"revolt-result",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tokio 1.35.1",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"utoipa",
|
||||||
|
"utoipa-scalar",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "revolt-models"
|
name = "revolt-models"
|
||||||
version = "0.7.16"
|
version = "0.7.16"
|
||||||
@@ -4635,6 +4840,7 @@ dependencies = [
|
|||||||
"rocket",
|
"rocket",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
"utoipa",
|
||||||
"validator 0.16.0",
|
"validator 0.16.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4680,12 +4886,14 @@ dependencies = [
|
|||||||
name = "revolt-result"
|
name = "revolt-result"
|
||||||
version = "0.7.16"
|
version = "0.7.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"axum",
|
||||||
"revolt_okapi",
|
"revolt_okapi",
|
||||||
"revolt_rocket_okapi",
|
"revolt_rocket_okapi",
|
||||||
"rocket",
|
"rocket",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"utoipa",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5325,7 +5533,7 @@ checksum = "01b0ad16faa5d12372f914ed40d00bda21a6d1bdcc99264c5e5e1c9495cf3654"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"reqwest",
|
"reqwest 0.11.10",
|
||||||
"sentry-backtrace",
|
"sentry-backtrace",
|
||||||
"sentry-contexts",
|
"sentry-contexts",
|
||||||
"sentry-core",
|
"sentry-core",
|
||||||
@@ -5818,6 +6026,33 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "system-configuration"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||||
|
dependencies = [
|
||||||
|
"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",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tagptr"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "take_mut"
|
name = "take_mut"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@@ -6163,6 +6398,12 @@ dependencies = [
|
|||||||
"tracing-log",
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "triomphe"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trust-dns-proto"
|
name = "trust-dns-proto"
|
||||||
version = "0.21.2"
|
version = "0.21.2"
|
||||||
@@ -7029,6 +7270,16 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xmlparser"
|
name = "xmlparser"
|
||||||
version = "0.13.6"
|
version = "0.13.6"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ COPY crates/core/permissions/Cargo.toml ./crates/core/permissions/
|
|||||||
COPY crates/core/presence/Cargo.toml ./crates/core/presence/
|
COPY crates/core/presence/Cargo.toml ./crates/core/presence/
|
||||||
COPY crates/core/result/Cargo.toml ./crates/core/result/
|
COPY crates/core/result/Cargo.toml ./crates/core/result/
|
||||||
COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/
|
COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/
|
||||||
|
COPY crates/services/january/Cargo.toml ./crates/services/january/
|
||||||
RUN sh /tmp/build-image-layer.sh deps
|
RUN sh /tmp/build-image-layer.sh deps
|
||||||
|
|
||||||
# Build all apps
|
# Build all apps
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ COPY crates/core/permissions/Cargo.toml ./crates/core/permissions/
|
|||||||
COPY crates/core/presence/Cargo.toml ./crates/core/presence/
|
COPY crates/core/presence/Cargo.toml ./crates/core/presence/
|
||||||
COPY crates/core/result/Cargo.toml ./crates/core/result/
|
COPY crates/core/result/Cargo.toml ./crates/core/result/
|
||||||
COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/
|
COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/
|
||||||
|
COPY crates/services/january/Cargo.toml ./crates/services/january/
|
||||||
RUN sh /tmp/build-image-layer.sh deps
|
RUN sh /tmp/build-image-layer.sh deps
|
||||||
|
|
||||||
# Build all apps
|
# Build all apps
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ description = "Revolt Backend: API Models"
|
|||||||
[features]
|
[features]
|
||||||
serde = ["dep:serde", "revolt-permissions/serde", "indexmap/serde"]
|
serde = ["dep:serde", "revolt-permissions/serde", "indexmap/serde"]
|
||||||
schemas = ["dep:schemars", "revolt-permissions/schemas"]
|
schemas = ["dep:schemars", "revolt-permissions/schemas"]
|
||||||
|
utoipa = ["dep:utoipa"]
|
||||||
validator = ["dep:validator"]
|
validator = ["dep:validator"]
|
||||||
rocket = ["dep:rocket"]
|
rocket = ["dep:rocket"]
|
||||||
partials = ["dep:revolt_optional_struct", "serde", "schemas"]
|
partials = ["dep:revolt_optional_struct", "serde", "schemas", "utoipa"]
|
||||||
|
|
||||||
default = ["serde", "partials", "rocket"]
|
default = ["serde", "partials", "rocket"]
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ iso8601-timestamp = { version = "0.2.11", features = ["schema", "bson"] }
|
|||||||
|
|
||||||
# Spec Generation
|
# Spec Generation
|
||||||
schemars = { version = "0.8.8", optional = true, features = ["indexmap1"] }
|
schemars = { version = "0.8.8", optional = true, features = ["indexmap1"] }
|
||||||
|
utoipa = { version = "4.2.3", optional = true }
|
||||||
|
|
||||||
# Validation
|
# Validation
|
||||||
validator = { version = "0.16.0", optional = true, features = ["derive"] }
|
validator = { version = "0.16.0", optional = true, features = ["derive"] }
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ extern crate serde;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate schemars;
|
extern crate schemars;
|
||||||
|
|
||||||
|
#[cfg(feature = "utoipa")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate utoipa;
|
||||||
|
|
||||||
#[cfg(feature = "partials")]
|
#[cfg(feature = "partials")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate revolt_optional_struct;
|
extern crate revolt_optional_struct;
|
||||||
@@ -18,6 +22,7 @@ macro_rules! auto_derived {
|
|||||||
$(
|
$(
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||||
|
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
$item
|
$item
|
||||||
)+
|
)+
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ description = "Revolt Backend: Result and Error types"
|
|||||||
[features]
|
[features]
|
||||||
serde = ["dep:serde"]
|
serde = ["dep:serde"]
|
||||||
schemas = ["dep:schemars"]
|
schemas = ["dep:schemars"]
|
||||||
|
utoipa = ["dep:utoipa"]
|
||||||
rocket = ["dep:rocket", "dep:serde_json"]
|
rocket = ["dep:rocket", "dep:serde_json"]
|
||||||
|
axum = ["dep:axum", "dep:serde_json"]
|
||||||
okapi = ["dep:revolt_rocket_okapi", "dep:revolt_okapi", "schemas"]
|
okapi = ["dep:revolt_rocket_okapi", "dep:revolt_okapi", "schemas"]
|
||||||
|
|
||||||
default = ["serde"]
|
default = ["serde"]
|
||||||
@@ -23,8 +25,12 @@ serde = { version = "1", features = ["derive"], optional = true }
|
|||||||
|
|
||||||
# Spec Generation
|
# Spec Generation
|
||||||
schemars = { version = "0.8.8", optional = true }
|
schemars = { version = "0.8.8", optional = true }
|
||||||
|
utoipa = { version = "4.2.3", optional = true }
|
||||||
|
|
||||||
# Rocket
|
# Rocket
|
||||||
rocket = { optional = true, version = "0.5.0-rc.2", default-features = false }
|
rocket = { optional = true, version = "0.5.0-rc.2", default-features = false }
|
||||||
revolt_rocket_okapi = { version = "0.9.1", optional = true }
|
revolt_rocket_okapi = { version = "0.9.1", optional = true }
|
||||||
revolt_okapi = { version = "0.9.1", optional = true }
|
revolt_okapi = { version = "0.9.1", optional = true }
|
||||||
|
|
||||||
|
# Axum
|
||||||
|
axum = { version = "0.7.5", optional = true }
|
||||||
|
|||||||
81
crates/core/result/src/axum.rs
Normal file
81
crates/core/result/src/axum.rs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
use axum::{http::StatusCode, response::IntoResponse, Json};
|
||||||
|
|
||||||
|
use crate::{Error, ErrorType};
|
||||||
|
|
||||||
|
/// HTTP response builder for Error enum
|
||||||
|
impl IntoResponse for Error {
|
||||||
|
fn into_response(self) -> axum::response::Response {
|
||||||
|
let status = match self.error_type {
|
||||||
|
ErrorType::LabelMe => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
|
||||||
|
ErrorType::AlreadyOnboarded => StatusCode::FORBIDDEN,
|
||||||
|
|
||||||
|
ErrorType::UnknownUser => StatusCode::NOT_FOUND,
|
||||||
|
ErrorType::InvalidUsername => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::UsernameTaken => StatusCode::CONFLICT,
|
||||||
|
ErrorType::DiscriminatorChangeRatelimited => StatusCode::TOO_MANY_REQUESTS,
|
||||||
|
ErrorType::AlreadyFriends => StatusCode::CONFLICT,
|
||||||
|
ErrorType::AlreadySentRequest => StatusCode::CONFLICT,
|
||||||
|
ErrorType::Blocked => StatusCode::CONFLICT,
|
||||||
|
ErrorType::BlockedByOther => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::NotFriends => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::TooManyPendingFriendRequests { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
|
||||||
|
ErrorType::UnknownChannel => StatusCode::NOT_FOUND,
|
||||||
|
ErrorType::UnknownMessage => StatusCode::NOT_FOUND,
|
||||||
|
ErrorType::UnknownAttachment => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::CannotEditMessage => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::CannotJoinCall => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::TooManyAttachments { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::TooManyReplies { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::EmptyMessage => StatusCode::UNPROCESSABLE_ENTITY,
|
||||||
|
ErrorType::PayloadTooLarge => StatusCode::UNPROCESSABLE_ENTITY,
|
||||||
|
ErrorType::CannotRemoveYourself => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::GroupTooLarge { .. } => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::AlreadyInGroup => StatusCode::CONFLICT,
|
||||||
|
ErrorType::NotInGroup => StatusCode::NOT_FOUND,
|
||||||
|
ErrorType::AlreadyPinned => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::NotPinned => StatusCode::BAD_REQUEST,
|
||||||
|
|
||||||
|
ErrorType::UnknownServer => StatusCode::NOT_FOUND,
|
||||||
|
ErrorType::InvalidRole => StatusCode::NOT_FOUND,
|
||||||
|
ErrorType::Banned => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::AlreadyInServer => StatusCode::CONFLICT,
|
||||||
|
|
||||||
|
ErrorType::TooManyServers { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::TooManyEmbeds { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::TooManyEmoji { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::TooManyChannels { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::TooManyRoles { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
|
||||||
|
ErrorType::ReachedMaximumBots => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::IsBot => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::BotIsPrivate => StatusCode::FORBIDDEN,
|
||||||
|
|
||||||
|
ErrorType::CannotReportYourself => StatusCode::BAD_REQUEST,
|
||||||
|
|
||||||
|
ErrorType::MissingPermission { .. } => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::MissingUserPermission { .. } => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::NotElevated => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::NotPrivileged => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::CannotGiveMissingPermissions => StatusCode::FORBIDDEN,
|
||||||
|
ErrorType::NotOwner => StatusCode::FORBIDDEN,
|
||||||
|
|
||||||
|
ErrorType::DatabaseError { .. } => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
ErrorType::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
ErrorType::InvalidOperation => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::InvalidCredentials => StatusCode::UNAUTHORIZED,
|
||||||
|
ErrorType::InvalidProperty => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::InvalidSession => StatusCode::UNAUTHORIZED,
|
||||||
|
ErrorType::DuplicateNonce => StatusCode::CONFLICT,
|
||||||
|
ErrorType::VosoUnavailable => StatusCode::BAD_REQUEST,
|
||||||
|
ErrorType::NotFound => StatusCode::NOT_FOUND,
|
||||||
|
ErrorType::NoEffect => StatusCode::OK,
|
||||||
|
ErrorType::FailedValidation { .. } => StatusCode::BAD_REQUEST,
|
||||||
|
|
||||||
|
ErrorType::ProxyError => StatusCode::BAD_REQUEST,
|
||||||
|
};
|
||||||
|
|
||||||
|
(status, Json(&self)).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,9 +8,16 @@ extern crate serde;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate schemars;
|
extern crate schemars;
|
||||||
|
|
||||||
|
#[cfg(feature = "utoipa")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate utoipa;
|
||||||
|
|
||||||
#[cfg(feature = "rocket")]
|
#[cfg(feature = "rocket")]
|
||||||
pub mod rocket;
|
pub mod rocket;
|
||||||
|
|
||||||
|
#[cfg(feature = "axum")]
|
||||||
|
pub mod axum;
|
||||||
|
|
||||||
#[cfg(feature = "okapi")]
|
#[cfg(feature = "okapi")]
|
||||||
pub mod okapi;
|
pub mod okapi;
|
||||||
|
|
||||||
@@ -20,6 +27,7 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|||||||
/// Error information
|
/// Error information
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||||
|
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
/// Type of error and additional information
|
/// Type of error and additional information
|
||||||
@@ -42,6 +50,7 @@ impl std::error::Error for Error {}
|
|||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(tag = "type"))]
|
#[cfg_attr(feature = "serde", serde(tag = "type"))]
|
||||||
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
#[cfg_attr(feature = "schemas", derive(JsonSchema))]
|
||||||
|
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ErrorType {
|
pub enum ErrorType {
|
||||||
/// This error was not labeled :(
|
/// This error was not labeled :(
|
||||||
@@ -145,6 +154,9 @@ pub enum ErrorType {
|
|||||||
error: String,
|
error: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ? Micro-service errors
|
||||||
|
ProxyError,
|
||||||
|
|
||||||
// ? Legacy errors
|
// ? Legacy errors
|
||||||
VosoUnavailable,
|
VosoUnavailable,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ impl<'r> Responder<'r, 'static> for Error {
|
|||||||
ErrorType::NotFound => Status::NotFound,
|
ErrorType::NotFound => Status::NotFound,
|
||||||
ErrorType::NoEffect => Status::Ok,
|
ErrorType::NoEffect => Status::Ok,
|
||||||
ErrorType::FailedValidation { .. } => Status::BadRequest,
|
ErrorType::FailedValidation { .. } => Status::BadRequest,
|
||||||
|
|
||||||
|
ErrorType::ProxyError => Status::BadRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Serialize the error data structure into JSON.
|
// Serialize the error data structure into JSON.
|
||||||
|
|||||||
@@ -4,19 +4,29 @@ version = "0.7.14"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# Serialisation
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0.68"
|
serde_json = "1.0.68"
|
||||||
|
|
||||||
|
# Async runtime
|
||||||
tokio = { version = "1.0", features = ["full"] }
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
|
|
||||||
|
# Logging
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
|
||||||
|
# Core crates
|
||||||
revolt-config = { version = "0.7.16", path = "../../core/config" }
|
revolt-config = { version = "0.7.16", path = "../../core/config" }
|
||||||
|
revolt-result = { version = "0.7.16", path = "../../core/result", features = [
|
||||||
|
"utoipa",
|
||||||
|
"axum",
|
||||||
|
] }
|
||||||
|
|
||||||
|
# Axum / web server
|
||||||
tempfile = "3.12.0"
|
tempfile = "3.12.0"
|
||||||
axum_typed_multipart = "0.12.1"
|
axum_typed_multipart = "0.12.1"
|
||||||
axum = { version = "0.7.5", features = ["multipart"] }
|
axum = { version = "0.7.5", features = ["multipart"] }
|
||||||
|
|
||||||
|
# OpenAPI & documentation generation
|
||||||
utoipa-scalar = { version = "0.1.0", features = ["axum"] }
|
utoipa-scalar = { version = "0.1.0", features = ["axum"] }
|
||||||
utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] }
|
utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] }
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ async fn main() -> Result<(), std::io::Error> {
|
|||||||
),
|
),
|
||||||
components(
|
components(
|
||||||
schemas(
|
schemas(
|
||||||
|
revolt_result::Error,
|
||||||
|
revolt_result::ErrorType,
|
||||||
api::RootResponse,
|
api::RootResponse,
|
||||||
api::Tag,
|
api::Tag,
|
||||||
api::UploadPayload,
|
api::UploadPayload,
|
||||||
|
|||||||
40
crates/services/january/Cargo.toml
Normal file
40
crates/services/january/Cargo.toml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
[package]
|
||||||
|
name = "revolt-january"
|
||||||
|
version = "0.7.14"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# Utility
|
||||||
|
mime = "0.3.17"
|
||||||
|
lazy_static = "1.5.0"
|
||||||
|
moka = { version = "0.12.8", features = ["future"] }
|
||||||
|
|
||||||
|
# Serialisation
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0.68"
|
||||||
|
|
||||||
|
# Async runtime
|
||||||
|
tokio = { version = "1.0", features = ["full"] }
|
||||||
|
|
||||||
|
# Web requests
|
||||||
|
reqwest = { version = "0.12", features = ["json"] }
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
|
||||||
|
# Core crates
|
||||||
|
revolt-config = { version = "0.7.16", path = "../../core/config" }
|
||||||
|
revolt-models = { version = "0.7.16", path = "../../core/models" }
|
||||||
|
revolt-result = { version = "0.7.16", path = "../../core/result", features = [
|
||||||
|
"utoipa",
|
||||||
|
"axum",
|
||||||
|
] }
|
||||||
|
|
||||||
|
# Axum / web server
|
||||||
|
axum = { version = "0.7.5" }
|
||||||
|
axum-extra = { version = "0.9", features = ["typed-header"] }
|
||||||
|
|
||||||
|
# OpenAPI & documentation generation
|
||||||
|
utoipa-scalar = { version = "0.1.0", features = ["axum"] }
|
||||||
|
utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] }
|
||||||
85
crates/services/january/src/api.rs
Normal file
85
crates/services/january/src/api.rs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
use axum::{body::Bytes, extract::Query, routing::get, Json, Router};
|
||||||
|
use revolt_models::v0::Embed;
|
||||||
|
use revolt_result::Result;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
|
use axum_extra::{
|
||||||
|
headers::{authorization::Bearer, Authorization},
|
||||||
|
TypedHeader,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::requests::Request;
|
||||||
|
|
||||||
|
pub async fn router() -> Router {
|
||||||
|
Router::new()
|
||||||
|
.route("/", get(root))
|
||||||
|
.route("/proxy", get(proxy))
|
||||||
|
.route("/embed", get(embed))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Successful root response
|
||||||
|
#[derive(Serialize, Debug, ToSchema)]
|
||||||
|
pub struct RootResponse {
|
||||||
|
january: &'static str,
|
||||||
|
version: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Capture crate version from Cargo
|
||||||
|
static CRATE_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
/// Root response from service
|
||||||
|
#[utoipa::path(
|
||||||
|
get,
|
||||||
|
path = "/",
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Echo response", body = RootResponse)
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
async fn root() -> Json<RootResponse> {
|
||||||
|
Json(RootResponse {
|
||||||
|
january: "Hello, I am a media proxy server!",
|
||||||
|
version: CRATE_VERSION,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct UrlQuery {
|
||||||
|
url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Proxy a given URL and load media
|
||||||
|
#[utoipa::path(
|
||||||
|
get,
|
||||||
|
path = "/proxy",
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Requested media file", body = Vec<u8>)
|
||||||
|
),
|
||||||
|
params(
|
||||||
|
("url" = String, Query, description = "URL to fetch")
|
||||||
|
),
|
||||||
|
)]
|
||||||
|
async fn proxy(Query(UrlQuery { url }): Query<UrlQuery>) -> Result<Bytes> {
|
||||||
|
Request::proxy_file(&url).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate embed for a given URL
|
||||||
|
#[utoipa::path(
|
||||||
|
get,
|
||||||
|
path = "/embed",
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Generated embed information", body = Embed)
|
||||||
|
),
|
||||||
|
params(
|
||||||
|
("url" = String, Query, description = "URL to fetch")
|
||||||
|
),
|
||||||
|
security(
|
||||||
|
("api_key" = [])
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
async fn embed(
|
||||||
|
Query(UrlQuery { url }): Query<UrlQuery>,
|
||||||
|
TypedHeader(Authorization(_bearer)): TypedHeader<Authorization<Bearer>>,
|
||||||
|
) -> Result<Json<Embed>> {
|
||||||
|
Request::generate_embed(&url).await.map(Json)
|
||||||
|
}
|
||||||
71
crates/services/january/src/main.rs
Normal file
71
crates/services/january/src/main.rs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
|
|
||||||
|
use axum::Router;
|
||||||
|
|
||||||
|
use tokio::net::TcpListener;
|
||||||
|
use utoipa::{
|
||||||
|
openapi::security::{Http, HttpAuthScheme, SecurityScheme},
|
||||||
|
Modify, OpenApi,
|
||||||
|
};
|
||||||
|
use utoipa_scalar::{Scalar, Servable as ScalarServable};
|
||||||
|
|
||||||
|
mod api;
|
||||||
|
pub mod requests;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), std::io::Error> {
|
||||||
|
// Configure logging and environment
|
||||||
|
revolt_config::configure!(api);
|
||||||
|
|
||||||
|
// Configure API schema
|
||||||
|
#[derive(OpenApi)]
|
||||||
|
#[openapi(
|
||||||
|
modifiers(&SecurityAddon),
|
||||||
|
paths(
|
||||||
|
api::root,
|
||||||
|
api::proxy,
|
||||||
|
api::embed
|
||||||
|
),
|
||||||
|
components(
|
||||||
|
schemas(
|
||||||
|
api::RootResponse,
|
||||||
|
revolt_result::Error,
|
||||||
|
revolt_result::ErrorType,
|
||||||
|
revolt_models::v0::ImageSize,
|
||||||
|
revolt_models::v0::Image,
|
||||||
|
revolt_models::v0::Video,
|
||||||
|
revolt_models::v0::TwitchType,
|
||||||
|
revolt_models::v0::LightspeedType,
|
||||||
|
revolt_models::v0::BandcampType,
|
||||||
|
revolt_models::v0::Special,
|
||||||
|
revolt_models::v0::WebsiteMetadata,
|
||||||
|
revolt_models::v0::Text,
|
||||||
|
revolt_models::v0::Embed
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
struct ApiDoc;
|
||||||
|
|
||||||
|
struct SecurityAddon;
|
||||||
|
|
||||||
|
impl Modify for SecurityAddon {
|
||||||
|
fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
|
||||||
|
if let Some(components) = openapi.components.as_mut() {
|
||||||
|
components.add_security_scheme(
|
||||||
|
"api_key",
|
||||||
|
SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure Axum and router
|
||||||
|
let app = Router::new()
|
||||||
|
.merge(Scalar::with_url("/scalar", ApiDoc::openapi()))
|
||||||
|
.nest("/", api::router().await);
|
||||||
|
|
||||||
|
// Configure TCP listener and bind
|
||||||
|
let address = SocketAddr::from((Ipv4Addr::UNSPECIFIED, 3000));
|
||||||
|
let listener = TcpListener::bind(&address).await?;
|
||||||
|
axum::serve(listener, app.into_make_service()).await
|
||||||
|
}
|
||||||
91
crates/services/january/src/requests.rs
Normal file
91
crates/services/january/src/requests.rs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use axum::body::Bytes;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use mime::Mime;
|
||||||
|
use reqwest::{header::CONTENT_TYPE, redirect, Client, Response};
|
||||||
|
use revolt_models::v0::Embed;
|
||||||
|
use revolt_result::{create_error, Result};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CLIENT: Client = reqwest::Client::builder()
|
||||||
|
.user_agent("Mozilla/5.0 (compatible; January/2.0; +https://github.com/revoltchat/backend)")
|
||||||
|
.timeout(Duration::from_secs(10)) // TODO config
|
||||||
|
.connect_timeout(Duration::from_secs(5)) // TODO config
|
||||||
|
.redirect(redirect::Policy::custom(|attempt| {
|
||||||
|
if attempt.previous().len() > 5 { // TODO config
|
||||||
|
attempt.error("too many redirects")
|
||||||
|
} else if attempt.url().host_str() == Some("jan.revolt.chat") { // TODO config
|
||||||
|
attempt.stop()
|
||||||
|
} else {
|
||||||
|
attempt.follow()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.build()
|
||||||
|
.expect("reqwest Client");
|
||||||
|
|
||||||
|
/// Cache for proxy results
|
||||||
|
static ref PROXY_CACHE: moka::future::Cache<String, Result<Bytes>> = moka::future::Cache::builder()
|
||||||
|
.max_capacity(10_000) // TODO config
|
||||||
|
.time_to_live(Duration::from_secs(60)) // TODO config
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/// Cache for embed results
|
||||||
|
static ref EMBED_CACHE: moka::future::Cache<String, Result<Embed>> = moka::future::Cache::builder()
|
||||||
|
.max_capacity(1_000) // TODO config
|
||||||
|
.time_to_live(Duration::from_secs(60)) // TODO config
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information about a successful request
|
||||||
|
pub struct Request {
|
||||||
|
response: Response,
|
||||||
|
mime: Mime,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Request {
|
||||||
|
/// Proxy a given URL
|
||||||
|
pub async fn proxy_file(url: &str) -> Result<Bytes> {
|
||||||
|
if let Some(hit) = PROXY_CACHE.get(url).await {
|
||||||
|
hit
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate embed for a given URL
|
||||||
|
pub async fn generate_embed(url: &str) -> Result<Embed> {
|
||||||
|
if let Some(hit) = EMBED_CACHE.get(url).await {
|
||||||
|
hit
|
||||||
|
} else {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send a new request to a service
|
||||||
|
pub async fn new(url: &str) -> Result<Request> {
|
||||||
|
let response = CLIENT
|
||||||
|
.get(url)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|_| create_error!(ProxyError))?;
|
||||||
|
|
||||||
|
if !response.status().is_success() {
|
||||||
|
tracing::error!("{:?}", response);
|
||||||
|
return Err(create_error!(ProxyError));
|
||||||
|
}
|
||||||
|
|
||||||
|
let content_type = response
|
||||||
|
.headers()
|
||||||
|
.get(CONTENT_TYPE)
|
||||||
|
.ok_or(create_error!(ProxyError))?
|
||||||
|
.to_str()
|
||||||
|
.map_err(|_| create_error!(ProxyError))?;
|
||||||
|
|
||||||
|
let mime: mime::Mime = content_type
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| create_error!(ProxyError))?;
|
||||||
|
|
||||||
|
Ok(Request { response, mime })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,11 +32,13 @@ deps() {
|
|||||||
crates/core/permissions/src \
|
crates/core/permissions/src \
|
||||||
crates/core/presence/src \
|
crates/core/presence/src \
|
||||||
crates/core/result/src \
|
crates/core/result/src \
|
||||||
crates/services/autumn/src
|
crates/services/autumn/src \
|
||||||
|
crates/services/january/src
|
||||||
echo 'fn main() { panic!("stub"); }' |
|
echo 'fn main() { panic!("stub"); }' |
|
||||||
tee crates/bonfire/src/main.rs |
|
tee crates/bonfire/src/main.rs |
|
||||||
tee crates/delta/src/main.rs |
|
tee crates/delta/src/main.rs |
|
||||||
tee crates/services/autumn/src/main.rs
|
tee crates/services/autumn/src/main.rs |
|
||||||
|
tee crates/services/january/src/main.rs
|
||||||
echo '' |
|
echo '' |
|
||||||
tee crates/bindings/node/src/lib.rs |
|
tee crates/bindings/node/src/lib.rs |
|
||||||
tee crates/core/config/src/lib.rs |
|
tee crates/core/config/src/lib.rs |
|
||||||
|
|||||||
Reference in New Issue
Block a user