chore: refactor generic web server code into quark
26
Cargo.lock
generated
@@ -684,16 +684,6 @@ dependencies = [
|
|||||||
"cipher",
|
"cipher",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ctrlc"
|
|
||||||
version = "3.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865"
|
|
||||||
dependencies = [
|
|
||||||
"nix",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.13.4"
|
version = "0.13.4"
|
||||||
@@ -1914,17 +1904,6 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nix"
|
|
||||||
version = "0.24.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "7.1.1"
|
version = "7.1.1"
|
||||||
@@ -2757,7 +2736,6 @@ dependencies = [
|
|||||||
"async-std",
|
"async-std",
|
||||||
"bitfield",
|
"bitfield",
|
||||||
"chrono",
|
"chrono",
|
||||||
"ctrlc",
|
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
@@ -2778,7 +2756,6 @@ dependencies = [
|
|||||||
"reqwest",
|
"reqwest",
|
||||||
"revolt-quark",
|
"revolt-quark",
|
||||||
"rocket",
|
"rocket",
|
||||||
"rocket_cors",
|
|
||||||
"rocket_empty",
|
"rocket_empty",
|
||||||
"rocket_okapi",
|
"rocket_okapi",
|
||||||
"rocket_rauth",
|
"rocket_rauth",
|
||||||
@@ -2801,6 +2778,7 @@ dependencies = [
|
|||||||
"bincode",
|
"bincode",
|
||||||
"bitfield",
|
"bitfield",
|
||||||
"bson",
|
"bson",
|
||||||
|
"dashmap",
|
||||||
"deadqueue",
|
"deadqueue",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -2809,6 +2787,7 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
"linkify 0.8.1",
|
"linkify 0.8.1",
|
||||||
"log",
|
"log",
|
||||||
|
"lru",
|
||||||
"mongodb",
|
"mongodb",
|
||||||
"nanoid",
|
"nanoid",
|
||||||
"num_enum",
|
"num_enum",
|
||||||
@@ -2820,6 +2799,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rocket",
|
"rocket",
|
||||||
|
"rocket_cors",
|
||||||
"rocket_empty",
|
"rocket_empty",
|
||||||
"rocket_http",
|
"rocket_http",
|
||||||
"rocket_okapi",
|
"rocket_okapi",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ mod websocket;
|
|||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
// Configure requirements for Bonfire.
|
// Configure requirements for Bonfire.
|
||||||
let _guard = revolt_quark::setup_logging();
|
revolt_quark::configure!();
|
||||||
database::connect().await;
|
database::connect().await;
|
||||||
|
|
||||||
// Clean up the current region information.
|
// Clean up the current region information.
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ linkify = "0.6.0"
|
|||||||
once_cell = "1.4.1"
|
once_cell = "1.4.1"
|
||||||
env_logger = "0.7.1"
|
env_logger = "0.7.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
ctrlc = { version = "3.0", features = ["termination"] }
|
|
||||||
|
|
||||||
# Lang. Utilities
|
# Lang. Utilities
|
||||||
regex = "1"
|
regex = "1"
|
||||||
@@ -54,7 +53,6 @@ mobc-redis = { version = "0.7.0", default-features = false, features = ["async-s
|
|||||||
rocket = { version = "0.5.0-rc.2", default-features = false, features = ["json"] }
|
rocket = { version = "0.5.0-rc.2", default-features = false, features = ["json"] }
|
||||||
rocket_empty = { git = "https://github.com/insertish/rocket_empty", branch = "master" }
|
rocket_empty = { git = "https://github.com/insertish/rocket_empty", branch = "master" }
|
||||||
rocket_rauth = { git = "https://github.com/insertish/rauth", rev = "a82cb5d23da4787e75d6f3c795189ce31e1590c4" }
|
rocket_rauth = { git = "https://github.com/insertish/rauth", rev = "a82cb5d23da4787e75d6f3c795189ce31e1590c4" }
|
||||||
rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "5843861a88958c16bfaa0b40f0d8910772bcd2f6" }
|
|
||||||
|
|
||||||
# spec generation
|
# spec generation
|
||||||
schemars = "0.8.8"
|
schemars = "0.8.8"
|
||||||
|
|||||||
@@ -6,101 +6,21 @@ extern crate rocket_okapi;
|
|||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
extern crate ctrlc;
|
|
||||||
|
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod version;
|
|
||||||
|
|
||||||
use log::info;
|
|
||||||
use revolt_quark::rauth::config::{
|
|
||||||
Captcha, Config, EmailVerificationConfig, SMTPSettings, Template, Templates,
|
|
||||||
};
|
|
||||||
use revolt_quark::rauth::RAuth;
|
use revolt_quark::rauth::RAuth;
|
||||||
use revolt_quark::variables::delta::{
|
|
||||||
APP_URL, HCAPTCHA_KEY, INVITE_ONLY, SMTP_FROM, SMTP_HOST, SMTP_PASSWORD, SMTP_USERNAME,
|
|
||||||
USE_EMAIL, USE_HCAPTCHA,
|
|
||||||
};
|
|
||||||
use revolt_quark::DatabaseInfo;
|
use revolt_quark::DatabaseInfo;
|
||||||
use rocket_cors::AllowedOrigins;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
async fn rocket() -> _ {
|
async fn rocket() -> _ {
|
||||||
let _guard = revolt_quark::setup_logging();
|
// Configure logging and environment
|
||||||
|
revolt_quark::configure!();
|
||||||
info!(
|
|
||||||
"Starting Revolt server [version {}].",
|
|
||||||
crate::version::VERSION
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Ensure environment variables are present
|
||||||
revolt_quark::variables::delta::preflight_checks();
|
revolt_quark::variables::delta::preflight_checks();
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
ctrlc::set_handler(move || {
|
|
||||||
// Force ungraceful exit to avoid hang.
|
|
||||||
std::process::exit(0);
|
|
||||||
})
|
|
||||||
.expect("Error setting Ctrl-C handler");
|
|
||||||
|
|
||||||
let cors = rocket_cors::CorsOptions {
|
|
||||||
allowed_origins: AllowedOrigins::All,
|
|
||||||
allowed_methods: [
|
|
||||||
"Get", "Put", "Post", "Delete", "Options", "Head", "Trace", "Connect", "Patch",
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
.map(|s| FromStr::from_str(s).unwrap())
|
|
||||||
.collect(),
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
.to_cors()
|
|
||||||
.expect("Failed to create CORS.");
|
|
||||||
|
|
||||||
let mut config = Config {
|
|
||||||
email_verification: if *USE_EMAIL {
|
|
||||||
EmailVerificationConfig::Enabled {
|
|
||||||
smtp: SMTPSettings {
|
|
||||||
from: (*SMTP_FROM).to_string(),
|
|
||||||
host: (*SMTP_HOST).to_string(),
|
|
||||||
username: (*SMTP_USERNAME).to_string(),
|
|
||||||
password: (*SMTP_PASSWORD).to_string(),
|
|
||||||
reply_to: Some("support@revolt.chat".into()),
|
|
||||||
port: None,
|
|
||||||
use_tls: None,
|
|
||||||
},
|
|
||||||
expiry: Default::default(),
|
|
||||||
templates: Templates {
|
|
||||||
verify: Template {
|
|
||||||
title: "Verify your Revolt account.".into(),
|
|
||||||
text: include_str!(crate::asset!("templates/verify.txt")).into(),
|
|
||||||
url: format!("{}/login/verify/", *APP_URL),
|
|
||||||
html: None,
|
|
||||||
},
|
|
||||||
reset: Template {
|
|
||||||
title: "Reset your Revolt password.".into(),
|
|
||||||
text: include_str!(crate::asset!("templates/reset.txt")).into(),
|
|
||||||
url: format!("{}/login/reset/", *APP_URL),
|
|
||||||
html: None,
|
|
||||||
},
|
|
||||||
welcome: None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
EmailVerificationConfig::Disabled
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
if *INVITE_ONLY {
|
|
||||||
config.invite_only = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if *USE_HCAPTCHA {
|
|
||||||
config.captcha = Captcha::HCaptcha {
|
|
||||||
secret: HCAPTCHA_KEY.clone(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup database
|
// Setup database
|
||||||
let db = DatabaseInfo::Auto.connect().await.unwrap();
|
let db = DatabaseInfo::Auto.connect().await.unwrap();
|
||||||
db.migrate_database().await.unwrap();
|
db.migrate_database().await.unwrap();
|
||||||
@@ -108,7 +28,7 @@ async fn rocket() -> _ {
|
|||||||
// Setup rAuth
|
// Setup rAuth
|
||||||
let rauth = RAuth {
|
let rauth = RAuth {
|
||||||
database: db.clone().into(),
|
database: db.clone().into(),
|
||||||
config,
|
config: revolt_quark::util::rauth::config(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Launch background task workers.
|
// Launch background task workers.
|
||||||
@@ -117,27 +37,11 @@ async fn rocket() -> _ {
|
|||||||
// Configure Rocket
|
// Configure Rocket
|
||||||
let rocket = rocket::build();
|
let rocket = rocket::build();
|
||||||
routes::mount(rocket)
|
routes::mount(rocket)
|
||||||
.mount("/", rocket_cors::catch_all_options_routes())
|
.mount("/", revolt_quark::web::cors::catch_all_options_routes())
|
||||||
.mount("/", util::ratelimiter::routes())
|
.mount("/", revolt_quark::web::ratelimiter::routes())
|
||||||
.mount(
|
.mount("/swagger/", revolt_quark::web::swagger::routes())
|
||||||
"/swagger/",
|
|
||||||
rocket_okapi::swagger_ui::make_swagger_ui(&rocket_okapi::swagger_ui::SwaggerUIConfig {
|
|
||||||
url: "../openapi.json".to_owned(),
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.manage(rauth)
|
.manage(rauth)
|
||||||
.manage(db)
|
.manage(db)
|
||||||
.manage(cors.clone())
|
.attach(revolt_quark::web::ratelimiter::RatelimitFairing)
|
||||||
.attach(util::ratelimiter::RatelimitFairing)
|
.attach(revolt_quark::web::cors::fairing())
|
||||||
.attach(cors)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve asset
|
|
||||||
macro_rules! asset {
|
|
||||||
($path:literal) => {
|
|
||||||
concat!(env!("CARGO_MANIFEST_DIR"), "/assets/", $path)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) use asset;
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ use revolt_quark::{
|
|||||||
message::{Masquerade, Reply, SendableEmbed},
|
message::{Masquerade, Reply, SendableEmbed},
|
||||||
Message, User,
|
Message, User,
|
||||||
},
|
},
|
||||||
perms, Db, Error, Permission, Ref, Result,
|
perms,
|
||||||
|
web::idempotency::IdempotencyKey,
|
||||||
|
Db, Error, Permission, Ref, Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
@@ -14,8 +16,6 @@ use serde::{Deserialize, Serialize};
|
|||||||
use ulid::Ulid;
|
use ulid::Ulid;
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
use crate::util::idempotency::IdempotencyKey;
|
|
||||||
|
|
||||||
#[derive(Validate, Serialize, Deserialize, JsonSchema)]
|
#[derive(Validate, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct DataMessageSend {
|
pub struct DataMessageSend {
|
||||||
/// Unique token to prevent duplicate message sending
|
/// Unique token to prevent duplicate message sending
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ pub struct RevoltConfig {
|
|||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub async fn root() -> Result<Json<RevoltConfig>> {
|
pub async fn root() -> Result<Json<RevoltConfig>> {
|
||||||
Ok(Json(RevoltConfig {
|
Ok(Json(RevoltConfig {
|
||||||
revolt: crate::version::VERSION.to_string(),
|
revolt: env!("CARGO_PKG_VERSION").to_string(),
|
||||||
features: RevoltFeatures {
|
features: RevoltFeatures {
|
||||||
captcha: CaptchaFeature {
|
captcha: CaptchaFeature {
|
||||||
enabled: *USE_HCAPTCHA,
|
enabled: *USE_HCAPTCHA,
|
||||||
|
|||||||
@@ -59,18 +59,6 @@ impl rocket_okapi::response::OpenApiResponderInner for CachedFile {
|
|||||||
pub async fn req(target: String) -> CachedFile {
|
pub async fn req(target: String) -> CachedFile {
|
||||||
CachedFile((
|
CachedFile((
|
||||||
ContentType::PNG,
|
ContentType::PNG,
|
||||||
match target.chars().last().unwrap() {
|
revolt_quark::util::pfp::avatar(target.chars().last().unwrap()),
|
||||||
// 0123456789ABCDEFGHJKMNPQRSTVWXYZ
|
|
||||||
'0' | '1' | '2' | '3' | 'S' | 'Z' => {
|
|
||||||
include_bytes!(crate::asset!("user/2.png")).to_vec()
|
|
||||||
}
|
|
||||||
'4' | '5' | '6' | '7' | 'T' => include_bytes!(crate::asset!("user/3.png")).to_vec(),
|
|
||||||
'8' | '9' | 'A' | 'B' => include_bytes!(crate::asset!("user/4.png")).to_vec(),
|
|
||||||
'C' | 'D' | 'E' | 'F' | 'V' => include_bytes!(crate::asset!("user/5.png")).to_vec(),
|
|
||||||
'G' | 'H' | 'J' | 'K' | 'W' => include_bytes!(crate::asset!("user/6.png")).to_vec(),
|
|
||||||
'M' | 'N' | 'P' | 'Q' | 'X' => include_bytes!(crate::asset!("user/7.png")).to_vec(),
|
|
||||||
/*'0' | '1' | '2' | '3' | 'R' | 'Y'*/
|
|
||||||
_ => include_bytes!(crate::asset!("user/1.png")).to_vec(),
|
|
||||||
},
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1 @@
|
|||||||
pub mod idempotency;
|
|
||||||
pub mod ratelimiter;
|
|
||||||
pub mod regex;
|
pub mod regex;
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
pub const VERSION: &str = "0.5.3-5-patch.2";
|
|
||||||
@@ -8,7 +8,18 @@ edition = "2021"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
mongo = [ "mongodb" ]
|
mongo = [ "mongodb" ]
|
||||||
rocket_impl = [ "rocket", "rocket_empty", "rauth/database-mongodb", "rauth/rocket_impl", "rauth/okapi_impl" ]
|
rocket_impl = [
|
||||||
|
"rocket",
|
||||||
|
"rocket_empty",
|
||||||
|
"rocket_cors",
|
||||||
|
|
||||||
|
"lru",
|
||||||
|
"dashmap",
|
||||||
|
|
||||||
|
"rauth/database-mongodb",
|
||||||
|
"rauth/rocket_impl",
|
||||||
|
"rauth/okapi_impl"
|
||||||
|
]
|
||||||
|
|
||||||
test = [ "async-std", "mongo", "mongodb/async-std-runtime", "rocket_impl" ]
|
test = [ "async-std", "mongo", "mongodb/async-std-runtime", "rocket_impl" ]
|
||||||
default = [ "test" ]
|
default = [ "test" ]
|
||||||
@@ -59,6 +70,9 @@ reqwest = "0.11.10"
|
|||||||
bitfield = "0.13.2"
|
bitfield = "0.13.2"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
||||||
|
lru = { version = "0.7.6", optional = true }
|
||||||
|
dashmap = { version = "5.2.0", optional = true }
|
||||||
|
|
||||||
# Web Push
|
# Web Push
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
web-push = "0.7.2"
|
web-push = "0.7.2"
|
||||||
@@ -67,6 +81,7 @@ web-push = "0.7.2"
|
|||||||
rocket_http = { optional = true, version = "0.5.0-rc.2" }
|
rocket_http = { optional = true, version = "0.5.0-rc.2" }
|
||||||
rocket = { optional = true, version = "0.5.0-rc.2", default-features = false, features = ["json"] }
|
rocket = { optional = true, version = "0.5.0-rc.2", default-features = false, features = ["json"] }
|
||||||
rocket_empty = { optional = true, git = "https://github.com/insertish/rocket_empty", branch = "master" }
|
rocket_empty = { optional = true, git = "https://github.com/insertish/rocket_empty", branch = "master" }
|
||||||
|
rocket_cors = { optional = true, git = "https://github.com/lawliet89/rocket_cors", rev = "5843861a88958c16bfaa0b40f0d8910772bcd2f6" }
|
||||||
|
|
||||||
# rAuth
|
# rAuth
|
||||||
rauth = { git = "https://github.com/insertish/rauth", rev = "a82cb5d23da4787e75d6f3c795189ce31e1590c4", features = [ "async-std-runtime" ] }
|
rauth = { git = "https://github.com/insertish/rauth", rev = "a82cb5d23da4787e75d6f3c795189ce31e1590c4", features = [ "async-std-runtime" ] }
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
@@ -2,7 +2,6 @@ use crate::r#impl::mongo::MongoDb;
|
|||||||
|
|
||||||
use super::scripts::LATEST_REVISION;
|
use super::scripts::LATEST_REVISION;
|
||||||
|
|
||||||
use log::info;
|
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
use mongodb::options::CreateCollectionOptions;
|
use mongodb::options::CreateCollectionOptions;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use bson::Bson;
|
use bson::Bson;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use log::info;
|
|
||||||
use mongodb::{
|
use mongodb::{
|
||||||
bson::{doc, from_bson, from_document, to_document, Document},
|
bson::{doc, from_bson, from_document, to_document, Document},
|
||||||
options::FindOptions,
|
options::FindOptions,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ extern crate lazy_static;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitfield;
|
extern crate bitfield;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub extern crate bson;
|
extern crate bson;
|
||||||
|
|
||||||
pub use iso8601_timestamp::Timestamp;
|
pub use iso8601_timestamp::Timestamp;
|
||||||
pub use rauth;
|
pub use rauth;
|
||||||
@@ -27,6 +27,7 @@ pub mod models;
|
|||||||
pub mod presence;
|
pub mod presence;
|
||||||
pub mod tasks;
|
pub mod tasks;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
pub mod util;
|
||||||
|
|
||||||
#[cfg(feature = "rocket_impl")]
|
#[cfg(feature = "rocket_impl")]
|
||||||
pub mod web;
|
pub mod web;
|
||||||
@@ -34,7 +35,6 @@ pub mod web;
|
|||||||
mod database;
|
mod database;
|
||||||
mod permissions;
|
mod permissions;
|
||||||
mod traits;
|
mod traits;
|
||||||
mod util;
|
|
||||||
|
|
||||||
pub use database::*;
|
pub use database::*;
|
||||||
pub use traits::*;
|
pub use traits::*;
|
||||||
@@ -43,10 +43,19 @@ pub use permissions::defn::*;
|
|||||||
pub use permissions::{get_relationship, perms};
|
pub use permissions::{get_relationship, perms};
|
||||||
|
|
||||||
pub use util::{
|
pub use util::{
|
||||||
log::setup_logging,
|
|
||||||
r#ref::Ref,
|
r#ref::Ref,
|
||||||
result::{Error, Result},
|
result::{Error, Result},
|
||||||
variables,
|
variables,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "rocket_impl")]
|
||||||
pub use web::{Db, EmptyResponse};
|
pub use web::{Db, EmptyResponse};
|
||||||
|
|
||||||
|
/// Resolve asset
|
||||||
|
macro_rules! asset {
|
||||||
|
($path:literal) => {
|
||||||
|
concat!(env!("CARGO_MANIFEST_DIR"), "/assets/", $path)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use asset;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
use crate::{models::channel::PartialChannel, Database};
|
use crate::{models::channel::PartialChannel, Database};
|
||||||
|
|
||||||
use deadqueue::limited::Queue;
|
use deadqueue::limited::Queue;
|
||||||
use log::info;
|
|
||||||
use mongodb::bson::doc;
|
use mongodb::bson::doc;
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use deadqueue::limited::Queue;
|
use deadqueue::limited::Queue;
|
||||||
use log::error;
|
|
||||||
|
|
||||||
/// Task information
|
/// Task information
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/// Configure logging and common Rust variables
|
/// Configure logging and common Rust variables
|
||||||
pub fn setup_logging() -> sentry::ClientInitGuard {
|
pub fn setup_logging(release: &'static str) -> sentry::ClientInitGuard {
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
|
|
||||||
if std::env::var("RUST_LOG").is_err() {
|
if std::env::var("RUST_LOG").is_err() {
|
||||||
@@ -11,12 +11,24 @@ pub fn setup_logging() -> sentry::ClientInitGuard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
|
info!("Starting {release}");
|
||||||
|
|
||||||
sentry::init((
|
sentry::init((
|
||||||
"https://62fd0e02c5354905b4e286757f4beb16@sentry.insert.moe/4",
|
"https://62fd0e02c5354905b4e286757f4beb16@sentry.insert.moe/4",
|
||||||
sentry::ClientOptions {
|
sentry::ClientOptions {
|
||||||
release: sentry::release_name!(),
|
release: Some(release.into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! configure {
|
||||||
|
() => {
|
||||||
|
let _sentry = revolt_quark::util::log::setup_logging(concat!(
|
||||||
|
env!("CARGO_PKG_NAME"),
|
||||||
|
"@",
|
||||||
|
env!("CARGO_PKG_VERSION")
|
||||||
|
));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
pub mod log;
|
pub mod log;
|
||||||
pub mod manipulation;
|
pub mod manipulation;
|
||||||
|
pub mod pfp;
|
||||||
|
pub mod rauth;
|
||||||
pub mod r#ref;
|
pub mod r#ref;
|
||||||
pub mod result;
|
pub mod result;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|||||||
13
crates/quark/src/util/pfp.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
pub fn avatar(v: char) -> Vec<u8> {
|
||||||
|
match v {
|
||||||
|
// 0123456789ABCDEFGHJKMNPQRSTVWXYZ
|
||||||
|
'0' | '1' | '2' | '3' | 'S' | 'Z' => include_bytes!(crate::asset!("user/2.png")).to_vec(),
|
||||||
|
'4' | '5' | '6' | '7' | 'T' => include_bytes!(crate::asset!("user/3.png")).to_vec(),
|
||||||
|
'8' | '9' | 'A' | 'B' => include_bytes!(crate::asset!("user/4.png")).to_vec(),
|
||||||
|
'C' | 'D' | 'E' | 'F' | 'V' => include_bytes!(crate::asset!("user/5.png")).to_vec(),
|
||||||
|
'G' | 'H' | 'J' | 'K' | 'W' => include_bytes!(crate::asset!("user/6.png")).to_vec(),
|
||||||
|
'M' | 'N' | 'P' | 'Q' | 'X' => include_bytes!(crate::asset!("user/7.png")).to_vec(),
|
||||||
|
/*'0' | '1' | '2' | '3' | 'R' | 'Y'*/
|
||||||
|
_ => include_bytes!(crate::asset!("user/1.png")).to_vec(),
|
||||||
|
}
|
||||||
|
}
|
||||||
57
crates/quark/src/util/rauth.rs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
use super::variables::delta::{
|
||||||
|
APP_URL, HCAPTCHA_KEY, INVITE_ONLY, SMTP_FROM, SMTP_HOST, SMTP_PASSWORD, SMTP_USERNAME,
|
||||||
|
USE_EMAIL, USE_HCAPTCHA,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::rauth::config::{
|
||||||
|
Captcha, Config, EmailVerificationConfig, SMTPSettings, Template, Templates,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn config() -> Config {
|
||||||
|
let mut config = Config {
|
||||||
|
email_verification: if *USE_EMAIL {
|
||||||
|
EmailVerificationConfig::Enabled {
|
||||||
|
smtp: SMTPSettings {
|
||||||
|
from: (*SMTP_FROM).to_string(),
|
||||||
|
host: (*SMTP_HOST).to_string(),
|
||||||
|
username: (*SMTP_USERNAME).to_string(),
|
||||||
|
password: (*SMTP_PASSWORD).to_string(),
|
||||||
|
reply_to: Some("support@revolt.chat".into()),
|
||||||
|
port: None,
|
||||||
|
use_tls: None,
|
||||||
|
},
|
||||||
|
expiry: Default::default(),
|
||||||
|
templates: Templates {
|
||||||
|
verify: Template {
|
||||||
|
title: "Verify your Revolt account.".into(),
|
||||||
|
text: include_str!(crate::asset!("templates/verify.txt")).into(),
|
||||||
|
url: format!("{}/login/verify/", *APP_URL),
|
||||||
|
html: None,
|
||||||
|
},
|
||||||
|
reset: Template {
|
||||||
|
title: "Reset your Revolt password.".into(),
|
||||||
|
text: include_str!(crate::asset!("templates/reset.txt")).into(),
|
||||||
|
url: format!("{}/login/reset/", *APP_URL),
|
||||||
|
html: None,
|
||||||
|
},
|
||||||
|
welcome: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
EmailVerificationConfig::Disabled
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
if *INVITE_ONLY {
|
||||||
|
config.invite_only = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if *USE_HCAPTCHA {
|
||||||
|
config.captcha = Captcha::HCaptcha {
|
||||||
|
secret: HCAPTCHA_KEY.clone(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
config
|
||||||
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use log::warn;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
// Application Settings
|
// Application Settings
|
||||||
pub static ref PUBLIC_URL: String =
|
pub static ref PUBLIC_URL: String =
|
||||||
|
|||||||
19
crates/quark/src/web/cors.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
pub use rocket_cors::catch_all_options_routes;
|
||||||
|
use rocket_cors::{AllowedOrigins, Cors};
|
||||||
|
|
||||||
|
pub fn fairing() -> Cors {
|
||||||
|
rocket_cors::CorsOptions {
|
||||||
|
allowed_origins: AllowedOrigins::All,
|
||||||
|
allowed_methods: [
|
||||||
|
"Get", "Put", "Post", "Delete", "Options", "Head", "Trace", "Connect", "Patch",
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.map(|s| FromStr::from_str(s).unwrap())
|
||||||
|
.collect(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
.to_cors()
|
||||||
|
.expect("Failed to create CORS.")
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
|
use crate::{Error, Result};
|
||||||
|
|
||||||
use async_std::sync::Mutex;
|
use async_std::sync::Mutex;
|
||||||
use revolt_quark::{Error, Result};
|
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::request::{FromRequest, Outcome};
|
use rocket::request::{FromRequest, Outcome};
|
||||||
use rocket_okapi::gen::OpenApiGenerator;
|
use rocket_okapi::gen::OpenApiGenerator;
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
use crate::Database;
|
use crate::Database;
|
||||||
use rocket::State;
|
use rocket::State;
|
||||||
|
|
||||||
|
pub mod cors;
|
||||||
|
pub mod idempotency;
|
||||||
|
pub mod ratelimiter;
|
||||||
|
pub mod swagger;
|
||||||
|
|
||||||
pub use rocket_empty::EmptyResponse;
|
pub use rocket_empty::EmptyResponse;
|
||||||
pub type Db = State<Database>;
|
pub type Db = State<Database>;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::hash::Hasher;
|
|||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use revolt_quark::rauth::models::Session;
|
use crate::rauth::models::Session;
|
||||||
use rocket::fairing::{Fairing, Info, Kind};
|
use rocket::fairing::{Fairing, Info, Kind};
|
||||||
use rocket::http::uri::Origin;
|
use rocket::http::uri::Origin;
|
||||||
use rocket::http::{Method, Status};
|
use rocket::http::{Method, Status};
|
||||||
@@ -23,8 +23,6 @@ use serde::Serialize;
|
|||||||
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
|
||||||
use log::info;
|
|
||||||
|
|
||||||
/// Ratelimit Bucket
|
/// Ratelimit Bucket
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Entry {
|
struct Entry {
|
||||||
@@ -304,11 +302,11 @@ impl<'r> FromRequest<'r> for RatelimitInformation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/ratelimit")]
|
#[rocket::get("/ratelimit")]
|
||||||
fn ratelimit_info(info: RatelimitInformation) -> Json<RatelimitInformation> {
|
fn ratelimit_info(info: RatelimitInformation) -> Json<RatelimitInformation> {
|
||||||
Json(info)
|
Json(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn routes() -> Vec<rocket::Route> {
|
pub fn routes() -> Vec<rocket::Route> {
|
||||||
routes![ratelimit_info]
|
rocket::routes![ratelimit_info]
|
||||||
}
|
}
|
||||||
9
crates/quark/src/web/swagger.rs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
use rocket::Route;
|
||||||
|
|
||||||
|
pub fn routes() -> Vec<Route> {
|
||||||
|
rocket_okapi::swagger_ui::make_swagger_ui(&rocket_okapi::swagger_ui::SwaggerUIConfig {
|
||||||
|
url: "../openapi.json".to_owned(),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||