From acc4317246ad0410f1f7e3b274d5e1549d940ff8 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Wed, 27 Nov 2024 16:56:30 +0000 Subject: [PATCH 01/35] feat: init crond crate --- Cargo.lock | 8 ++++++++ Cargo.toml | 1 + crates/core/database/src/models/users/model.rs | 11 +++++++++-- crates/daemons/crond/Cargo.toml | 14 ++++++++++++++ crates/daemons/crond/src/main.rs | 3 +++ 5 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 crates/daemons/crond/Cargo.toml create mode 100644 crates/daemons/crond/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 4b464193..1d9cd243 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1573,6 +1573,14 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crond" +version = "0.7.19" +dependencies = [ + "revolt-database", + "revolt-files", +] + [[package]] name = "crossbeam-channel" version = "0.5.13" diff --git a/Cargo.toml b/Cargo.toml index 61f6fa51..b0e93186 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "crates/core/*", "crates/services/*", "crates/bindings/*", + "crates/daemons/*", ] [patch.crates-io] diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index 9a250ad6..20286b16 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -152,7 +152,7 @@ pub static DISCRIMINATOR_SEARCH_SPACE: Lazy> = Lazy::new(|| { .collect::>(); for discrim in [ - 123, 1234, 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, + 123, 1234, 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888, 9999, 1488, ] { set.remove(&format!("{:0>4}", discrim)); } @@ -293,7 +293,14 @@ impl User { } // Ensure none of the following substrings show up in the username - const BLOCKED_SUBSTRINGS: &[&str] = &["```"]; + const BLOCKED_SUBSTRINGS: &[&str] = &[ + "```", + "discord.gg", + "rvlt.gg", + "guilded.gg", + "https://", + "http://", + ]; for substr in BLOCKED_SUBSTRINGS { if username_lowercase.contains(substr) { diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml new file mode 100644 index 00000000..85ec4349 --- /dev/null +++ b/crates/daemons/crond/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "crond" +version = "0.7.19" +license = "AGPL-3.0-or-later" +authors = ["Paul Makles "] +edition = "2021" +description = "Revolt Daemon Service: Timed data clean up tasks" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# Core +revolt-database = { version = "0.7.19", path = "../../core/database" } +revolt-files = { version = "0.7.19", path = "../../core/files" } diff --git a/crates/daemons/crond/src/main.rs b/crates/daemons/crond/src/main.rs new file mode 100644 index 00000000..e7a11a96 --- /dev/null +++ b/crates/daemons/crond/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From 249749e14dbd2b565fbc728aa5131cd6a923be99 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Wed, 27 Nov 2024 21:54:39 +0000 Subject: [PATCH 02/35] feat: file deletion implementation --- Cargo.lock | 28 +++++----- crates/core/config/Revolt.toml | 1 + crates/core/config/src/lib.rs | 1 + .../database/src/models/file_hashes/ops.rs | 3 ++ .../src/models/file_hashes/ops/mongodb.rs | 5 ++ .../src/models/file_hashes/ops/reference.rs | 12 ++++- crates/core/database/src/models/files/ops.rs | 12 +++++ .../database/src/models/files/ops/mongodb.rs | 54 ++++++++++++++++++- .../src/models/files/ops/reference.rs | 45 ++++++++++++++++ crates/core/files/src/lib.rs | 17 ++++++ crates/daemons/crond/Cargo.toml | 10 +++- crates/daemons/crond/src/main.rs | 20 ++++++- .../daemons/crond/src/tasks/file_deletion.rs | 39 ++++++++++++++ crates/daemons/crond/src/tasks/mod.rs | 2 + .../crond/src/tasks/prune_dangling_files.rs | 36 +++++++++++++ 15 files changed, 267 insertions(+), 18 deletions(-) create mode 100644 crates/daemons/crond/src/tasks/file_deletion.rs create mode 100644 crates/daemons/crond/src/tasks/mod.rs create mode 100644 crates/daemons/crond/src/tasks/prune_dangling_files.rs diff --git a/Cargo.lock b/Cargo.lock index 1d9cd243..45f665cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1573,14 +1573,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crond" -version = "0.7.19" -dependencies = [ - "revolt-database", - "revolt-files", -] - [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -2459,9 +2451,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -2490,9 +2482,9 @@ checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -5670,6 +5662,18 @@ dependencies = [ "serde", ] +[[package]] +name = "revolt-crond" +version = "0.7.19" +dependencies = [ + "log", + "revolt-config", + "revolt-database", + "revolt-files", + "revolt-result", + "tokio 1.35.1", +] + [[package]] name = "revolt-database" version = "0.7.19" diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 359c0e99..1028a7e8 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -234,3 +234,4 @@ api = "" events = "" files = "" proxy = "" +crond = "" diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index e0f57d17..2f55441e 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -245,6 +245,7 @@ pub struct Sentry { pub events: String, pub files: String, pub proxy: String, + pub crond: String, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/core/database/src/models/file_hashes/ops.rs b/crates/core/database/src/models/file_hashes/ops.rs index e7f62658..648a1a2f 100644 --- a/crates/core/database/src/models/file_hashes/ops.rs +++ b/crates/core/database/src/models/file_hashes/ops.rs @@ -15,4 +15,7 @@ pub trait AbstractAttachmentHashes: Sync + Send { /// Update an attachment hash nonce value. async fn set_attachment_hash_nonce(&self, hash: &str, nonce: &str) -> Result<()>; + + /// Delete attachment hash by id. + async fn delete_attachment_hash(&self, id: &str) -> Result<()>; } diff --git a/crates/core/database/src/models/file_hashes/ops/mongodb.rs b/crates/core/database/src/models/file_hashes/ops/mongodb.rs index c55a0610..153cb72f 100644 --- a/crates/core/database/src/models/file_hashes/ops/mongodb.rs +++ b/crates/core/database/src/models/file_hashes/ops/mongodb.rs @@ -48,4 +48,9 @@ impl AbstractAttachmentHashes for MongoDb { .map(|_| ()) .map_err(|_| create_database_error!("update_one", COL)) } + + /// Delete attachment hash by id. + async fn delete_attachment_hash(&self, id: &str) -> Result<()> { + query!(self, delete_one_by_id, COL, id).map(|_| ()) + } } diff --git a/crates/core/database/src/models/file_hashes/ops/reference.rs b/crates/core/database/src/models/file_hashes/ops/reference.rs index 86bbeee8..7733523e 100644 --- a/crates/core/database/src/models/file_hashes/ops/reference.rs +++ b/crates/core/database/src/models/file_hashes/ops/reference.rs @@ -23,8 +23,8 @@ impl AbstractAttachmentHashes for ReferenceDb { let hashes = self.file_hashes.lock().await; hashes .values() + .find(|&hash| hash.id == hash_value || hash.processed_hash == hash_value) .cloned() - .find(|hash| hash.id == hash_value || hash.processed_hash == hash_value) .ok_or(create_error!(NotFound)) } @@ -38,4 +38,14 @@ impl AbstractAttachmentHashes for ReferenceDb { Err(create_error!(NotFound)) } } + + /// Delete attachment hash by id. + async fn delete_attachment_hash(&self, id: &str) -> Result<()> { + let mut file_hashes = self.file_hashes.lock().await; + if file_hashes.remove(id).is_some() { + Ok(()) + } else { + Err(create_error!(NotFound)) + } + } } diff --git a/crates/core/database/src/models/files/ops.rs b/crates/core/database/src/models/files/ops.rs index 58d599d3..b30d3acc 100644 --- a/crates/core/database/src/models/files/ops.rs +++ b/crates/core/database/src/models/files/ops.rs @@ -15,6 +15,15 @@ pub trait AbstractAttachments: Sync + Send { /// Fetch an attachment by its id. async fn fetch_attachment(&self, tag: &str, file_id: &str) -> Result; + /// Fetch all deleted attachments. + async fn fetch_deleted_attachments(&self) -> Result>; + + /// Fetch all dangling attachments. + async fn fetch_dangling_files(&self) -> Result>; + + /// Count references to a given hash. + async fn count_file_hash_references(&self, hash: &str) -> Result; + /// Find an attachment by its details and mark it as used by a given parent. async fn find_and_use_attachment( &self, @@ -32,4 +41,7 @@ pub trait AbstractAttachments: Sync + Send { /// Mark multiple attachments as having been deleted. async fn mark_attachments_as_deleted(&self, ids: &[String]) -> Result<()>; + + /// Delete the attachment entry. + async fn delete_attachment(&self, id: &str) -> Result<()>; } diff --git a/crates/core/database/src/models/files/ops/mongodb.rs b/crates/core/database/src/models/files/ops/mongodb.rs index c2295cf3..43e8e946 100644 --- a/crates/core/database/src/models/files/ops/mongodb.rs +++ b/crates/core/database/src/models/files/ops/mongodb.rs @@ -32,6 +32,51 @@ impl AbstractAttachments for MongoDb { .ok_or_else(|| create_error!(NotFound)) } + /// Fetch all deleted attachments. + async fn fetch_deleted_attachments(&self) -> Result> { + query!( + self, + find, + COL, + doc! { + "deleted": true, + "reported": { + "$ne": true + } + } + ) + } + + /// Fetch all dangling attachments. + async fn fetch_dangling_files(&self) -> Result> { + query!( + self, + find, + COL, + doc! { + "used_for.type": { + "$exists": 0 + }, + "deleted": { + "$ne": true + } + } + ) + } + + /// Count references to a given hash. + async fn count_file_hash_references(&self, hash: &str) -> Result { + query!( + self, + count_documents, + COL, + doc! { + "hash": hash + } + ) + .map(|count| count as usize) + } + /// Find an attachment by its details and mark it as used by a given parent. async fn find_and_use_attachment( &self, @@ -114,7 +159,7 @@ impl AbstractAttachments for MongoDb { /// Mark multiple attachments as having been deleted. async fn mark_attachments_as_deleted(&self, ids: &[String]) -> Result<()> { self.col::(COL) - .update_one( + .update_many( doc! { "_id": { "$in": ids @@ -129,7 +174,12 @@ impl AbstractAttachments for MongoDb { ) .await .map(|_| ()) - .map_err(|_| create_database_error!("update_one", COL)) + .map_err(|_| create_database_error!("update_many", COL)) + } + + /// Delete the attachment entry. + async fn delete_attachment(&self, id: &str) -> Result<()> { + query!(self, delete_one_by_id, COL, id).map(|_| ()) } } diff --git a/crates/core/database/src/models/files/ops/reference.rs b/crates/core/database/src/models/files/ops/reference.rs index e1879427..208b0b0a 100644 --- a/crates/core/database/src/models/files/ops/reference.rs +++ b/crates/core/database/src/models/files/ops/reference.rs @@ -33,6 +33,41 @@ impl AbstractAttachments for ReferenceDb { } } + /// Fetch all deleted attachments. + async fn fetch_deleted_attachments(&self) -> Result> { + let files = self.files.lock().await; + Ok(files + .values() + .filter(|file| { + // file has been marked as deleted + file.deleted.is_some_and(|v| v) + // and it has not been reported + && !file.reported.is_some_and(|v| v) + }) + .cloned() + .collect()) + } + + /// Fetch all dangling attachments. + async fn fetch_dangling_files(&self) -> Result> { + let files = self.files.lock().await; + Ok(files + .values() + .filter(|file| file.used_for.is_none() && !file.deleted.is_some_and(|v| v)) + .cloned() + .collect()) + } + + /// Count references to a given hash. + async fn count_file_hash_references(&self, hash: &str) -> Result { + let files = self.files.lock().await; + Ok(files + .values() + .filter(|file| file.hash.as_ref().is_some_and(|h| h == hash)) + .cloned() + .count()) + } + /// Find an attachment by its details and mark it as used by a given parent. async fn find_and_use_attachment( &self, @@ -96,4 +131,14 @@ impl AbstractAttachments for ReferenceDb { Ok(()) } + + /// Delete the attachment entry. + async fn delete_attachment(&self, id: &str) -> Result<()> { + let mut files = self.files.lock().await; + if files.remove(id).is_some() { + Ok(()) + } else { + Err(create_error!(NotFound)) + } + } } diff --git a/crates/core/files/src/lib.rs b/crates/core/files/src/lib.rs index c09853dd..dacc988e 100644 --- a/crates/core/files/src/lib.rs +++ b/crates/core/files/src/lib.rs @@ -113,6 +113,23 @@ pub async fn upload_to_s3(bucket_id: &str, path: &str, buf: &[u8]) -> Result Result<()> { + let config = config().await; + let client = create_client(config.files.s3); + + report_internal_error!( + client + .delete_object() + .bucket(bucket_id) + .key(path) + .send() + .await + )?; + + Ok(()) +} + /// Determine size of image at temp file pub fn image_size(f: &NamedTempFile) -> Option<(usize, usize)> { if let Ok(size) = imagesize::size(f.path()) diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 85ec4349..f2c4b94f 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "crond" +name = "revolt-crond" version = "0.7.19" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -9,6 +9,14 @@ description = "Revolt Daemon Service: Timed data clean up tasks" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +# Utility +log = "0.4" + +# Async +tokio = { version = "1" } + # Core revolt-database = { version = "0.7.19", path = "../../core/database" } +revolt-result = { version = "0.7.19", path = "../../core/result" } +revolt-config = { version = "0.7.19", path = "../../core/config" } revolt-files = { version = "0.7.19", path = "../../core/files" } diff --git a/crates/daemons/crond/src/main.rs b/crates/daemons/crond/src/main.rs index e7a11a96..40af6a2b 100644 --- a/crates/daemons/crond/src/main.rs +++ b/crates/daemons/crond/src/main.rs @@ -1,3 +1,19 @@ -fn main() { - println!("Hello, world!"); +use revolt_config::configure; +use revolt_database::DatabaseInfo; +use revolt_result::Result; +use tasks::{file_deletion, prune_dangling_files}; +use tokio::try_join; + +pub mod tasks; + +#[tokio::main] +async fn main() -> Result<()> { + configure!(crond); + + let db = DatabaseInfo::Auto.connect().await.expect("database"); + try_join!( + file_deletion::task(db.clone()), + prune_dangling_files::task(db) + ) + .map(|_| ()) } diff --git a/crates/daemons/crond/src/tasks/file_deletion.rs b/crates/daemons/crond/src/tasks/file_deletion.rs new file mode 100644 index 00000000..912173b3 --- /dev/null +++ b/crates/daemons/crond/src/tasks/file_deletion.rs @@ -0,0 +1,39 @@ +use std::time::Duration; + +use log::info; +use revolt_database::Database; +use revolt_files::delete_from_s3; +use revolt_result::Result; +use tokio::time::sleep; + +pub async fn task(db: Database) -> Result<()> { + loop { + let files = db.fetch_deleted_attachments().await?; + + for file in files { + let count = db + .count_file_hash_references(file.hash.as_ref().expect("no `hash` present")) + .await?; + + // No other files reference this file on disk anymore + if count <= 1 { + let file_hash = db + .fetch_attachment_hash(file.hash.as_ref().expect("no `hash` present")) + .await?; + + // Delete from S3 + delete_from_s3(&file_hash.bucket_id, &file_hash.path).await?; + + // Delete the hash + db.delete_attachment_hash(&file_hash.id).await?; + info!("Deleted file hash {}", file_hash.id); + } + + // Delete the file + db.delete_attachment(&file.id).await?; + info!("Deleted file {}", file.id); + } + + sleep(Duration::from_secs(60)).await; + } +} diff --git a/crates/daemons/crond/src/tasks/mod.rs b/crates/daemons/crond/src/tasks/mod.rs new file mode 100644 index 00000000..2a668f14 --- /dev/null +++ b/crates/daemons/crond/src/tasks/mod.rs @@ -0,0 +1,2 @@ +pub mod file_deletion; +pub mod prune_dangling_files; diff --git a/crates/daemons/crond/src/tasks/prune_dangling_files.rs b/crates/daemons/crond/src/tasks/prune_dangling_files.rs new file mode 100644 index 00000000..be1eb6d6 --- /dev/null +++ b/crates/daemons/crond/src/tasks/prune_dangling_files.rs @@ -0,0 +1,36 @@ +use std::time::Duration; + +use revolt_database::{iso8601_timestamp::Timestamp, Database}; +use revolt_result::Result; +use tokio::time::sleep; + +use log::info; + +pub async fn task(db: Database) -> Result<()> { + loop { + // This could just be a single database query + // ... but timestamps are inconsistently serialised + // ... sometimes they are dates/numbers, hard to query + // ... in the future, we could use Postgres instead! :D + // ... + // ... on the plus side, it's still only 2 queries + + let files = db.fetch_dangling_files().await?; + let file_ids: Vec = files + .into_iter() + .filter(|file| { + file.uploaded_at.is_some_and(|uploaded_at| { + Timestamp::now_utc().duration_since(uploaded_at) > Duration::from_secs(60 * 60) + }) + }) + .map(|file| file.id) + .collect(); + + if !file_ids.is_empty() { + db.mark_attachments_as_deleted(&file_ids).await?; + info!("Marked {} dangling files for deletion", file_ids.len()); + } + + sleep(Duration::from_secs(60)).await; + } +} From fa55e88dd9a09013d74ef008cc90197530526314 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 17:19:54 +0000 Subject: [PATCH 03/35] chore: add pushd to debug image script --- scripts/publish-debug-image.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/publish-debug-image.sh b/scripts/publish-debug-image.sh index 1f0eb2e4..247338ab 100755 --- a/scripts/publish-debug-image.sh +++ b/scripts/publish-debug-image.sh @@ -25,6 +25,7 @@ docker build -t ghcr.io/revoltchat/server:$TAG - < crates/delta/Dockerfile docker build -t ghcr.io/revoltchat/bonfire:$TAG - < crates/bonfire/Dockerfile docker build -t ghcr.io/revoltchat/autumn:$TAG - < crates/services/autumn/Dockerfile docker build -t ghcr.io/revoltchat/january:$TAG - < crates/services/january/Dockerfile +docker build -t ghcr.io/revoltchat/pushd:$TAG - < crates/daemons/pushd/Dockerfile if [ "$DEBUG" = "true" ]; then git restore Cargo.toml @@ -34,3 +35,4 @@ docker push ghcr.io/revoltchat/server:$TAG docker push ghcr.io/revoltchat/bonfire:$TAG docker push ghcr.io/revoltchat/autumn:$TAG docker push ghcr.io/revoltchat/january:$TAG +docker push ghcr.io/revoltchat/pushd:$TAG From 439bacf067fd886b4cba2be96a4db8d3510b4dd3 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 17:20:29 +0000 Subject: [PATCH 04/35] refactor: add error messages for Rabbit issues --- crates/delta/src/main.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index c25cf7fa..0561a9da 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -89,8 +89,12 @@ pub async fn web() -> Rocket { &config.rabbit.password, )) .await - .unwrap(); - let channel = connection.open_channel(None).await.unwrap(); + .expect("Failed to connect to RabbitMQ"); + + let channel = connection + .open_channel(None) + .await + .expect("Failed to open RabbitMQ channel"); channel .exchange_declare( From e957af4ca3f59bd6e9a3cb37d4b33898c3c2c2a6 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 17:21:23 +0000 Subject: [PATCH 05/35] docs: add some notes on overrides; fix defaults --- .gitignore | 1 + README.md | 34 +++++++++++++++++++++++++++++++++- Revolt.toml | 7 +++++-- default.nix | 20 ++------------------ 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index dc7d1372..b555a30c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ Rocket.toml Revolt.*.toml +compose.override.yml target .data diff --git a/README.md b/README.md index ea8cab84..c480340f 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ As a heads-up, the development environment uses the following ports: | MinIO | 14009 | | Maildev | 14025
14080 | | Revolt Web App | 14701 | -| RabbitMQ | 5672
15672 | +| RabbitMQ | 5672
15672 | | `crates/delta` | 14702 | | `crates/bonfire` | 14703 | | `crates/services/autumn` | 14704 | @@ -91,6 +91,38 @@ If you'd like to change anything, create a `Revolt.overrides.toml` file and spec > proxy = "https://abc@your.sentry/1" > ``` +> [!TIP] +> If you have port conflicts on common services, you can try the following: +> +> ```yaml +> # compose.override.yml +> services: +> redis: +> ports: !override +> - "14079:6379" +> +> database: +> ports: !override +> - "14017:27017" +> +> rabbit: +> ports: !override +> - "14072:5672" +> - "14672:15672" +> ``` +> +> And corresponding Revolt configuration: +> +> ```toml +> # Revolt.overrides.toml +> [database] +> mongodb = "mongodb://127.0.0.1:14017" +> redis = "redis://127.0.0.1:14079/" +> +> [rabbit] +> port = 14072 +> ``` + Then continue: ```bash diff --git a/Revolt.toml b/Revolt.toml index ff8827a8..47971a20 100644 --- a/Revolt.toml +++ b/Revolt.toml @@ -4,10 +4,13 @@ [database] # MongoDB connection URL # Defaults to the container name specified in self-hosted -mongodb = "mongodb://127.0.0.1:14017" +mongodb = "mongodb://127.0.0.1:27017" # Redis connection URL # Defaults to the container name specified in self-hosted -redis = "redis://127.0.0.1:14079/" +redis = "redis://127.0.0.1:6379/" + +[rabbit] +host = "127.0.0.1" [hosts] # Web locations of various services diff --git a/default.nix b/default.nix index 16096d50..f8736308 100644 --- a/default.nix +++ b/default.nix @@ -1,26 +1,10 @@ -let - # Pinned nixpkgs, deterministic. Last updated: 28-07-2024. - pkgs = import (fetchTarball("https://github.com/NixOS/nixpkgs/archive/9b34ca580417e1ebc56c4df57d8b387dad686665.tar.gz")) {}; - - # Rolling updates, not deterministic. - # pkgs = import (fetchTarball("channel:nixpkgs-unstable")) {}; -in pkgs.mkShell { - name = "revoltEnv"; - - # LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ - # pkgs.gcc-unwrapped - # pkgs.zlib - # pkgs.glib - # pkgs.libGL - # ]; +{ pkgs ? import {} }: +pkgs.mkShell rec { buildInputs = [ # Tools pkgs.git - # Database - # pkgs.mongodb - # Cargo pkgs.cargo pkgs.cargo-nextest From 5f84daa9dba34c103cd83a2ee1f5e5ba900bfe94 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 17:51:22 +0000 Subject: [PATCH 06/35] fix: ensure limit is always at least 1 when sent to database --- crates/core/database/src/models/messages/ops/mongodb.rs | 2 +- crates/core/models/src/v0/messages.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core/database/src/models/messages/ops/mongodb.rs b/crates/core/database/src/models/messages/ops/mongodb.rs index 18eeb379..721a3b7c 100644 --- a/crates/core/database/src/models/messages/ops/mongodb.rs +++ b/crates/core/database/src/models/messages/ops/mongodb.rs @@ -95,7 +95,7 @@ impl AbstractMessages for MongoDb { COL, older_message_filter, FindOptions::builder() - .limit(limit / 2) + .limit(limit / 2 + 1) .sort(doc! { "_id": -1_i32 }) diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index b8c53aee..1312f377 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -280,7 +280,7 @@ auto_derived!( pub struct OptionsQueryMessages { /// Maximum number of messages to fetch /// - /// For fetching nearby messages, this is \`(limit + 1)\`. + /// For fetching nearby messages, this is \`(limit + 2)\`. #[cfg_attr(feature = "validator", validate(range(min = 1, max = 100)))] pub limit: Option, /// Message id before which messages should be fetched From e3723d647effb81ea3d3919d848faf64dbe89829 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 18:04:46 +0000 Subject: [PATCH 07/35] fix: change permission check for fetching channel webhooks --- crates/delta/src/routes/channels/webhook_fetch_all.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/delta/src/routes/channels/webhook_fetch_all.rs b/crates/delta/src/routes/channels/webhook_fetch_all.rs index 06d94d80..6afc7ac8 100644 --- a/crates/delta/src/routes/channels/webhook_fetch_all.rs +++ b/crates/delta/src/routes/channels/webhook_fetch_all.rs @@ -22,7 +22,7 @@ pub async fn fetch_webhooks( let mut query = DatabasePermissionQuery::new(db, &user).channel(&channel); calculate_channel_permissions(&mut query) .await - .throw_if_lacking_channel_permission(ChannelPermission::ViewChannel)?; + .throw_if_lacking_channel_permission(ChannelPermission::ManageWebhooks)?; Ok(Json( db.fetch_webhooks_for_channel(channel.id()) From e525ffe5e40c3b265dc4a2b885e2c6eba42d59ae Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 18:19:34 +0000 Subject: [PATCH 08/35] chore: mount API at /0.8/ as well --- crates/delta/src/main.rs | 11 ++++++++- crates/delta/src/routes/mod.rs | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/crates/delta/src/main.rs b/crates/delta/src/main.rs index 0561a9da..9cce39ce 100644 --- a/crates/delta/src/main.rs +++ b/crates/delta/src/main.rs @@ -75,7 +75,15 @@ pub async fn web() -> Rocket { // Configure Swagger let swagger = revolt_rocket_okapi::swagger_ui::make_swagger_ui( &revolt_rocket_okapi::swagger_ui::SwaggerUIConfig { - url: "../openapi.json".to_owned(), + url: "/openapi.json".to_owned(), + ..Default::default() + }, + ) + .into(); + + let swagger_0_8 = revolt_rocket_okapi::swagger_ui::make_swagger_ui( + &revolt_rocket_okapi::swagger_ui::SwaggerUIConfig { + url: "/0.8/openapi.json".to_owned(), ..Default::default() }, ) @@ -120,6 +128,7 @@ pub async fn web() -> Rocket { .mount("/", rocket_cors::catch_all_options_routes()) .mount("/", util::ratelimiter::routes()) .mount("/swagger/", swagger) + .mount("/0.8/swagger/", swagger_0_8) .manage(authifier) .manage(db) .manage(amqp) diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 516c2166..1f150e0b 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -61,6 +61,47 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { }; } + if config.features.webhooks_enabled { + mount_endpoints_and_merged_docs! { + rocket, "/0.8".to_owned(), settings, + "/" => (vec![], custom_openapi_spec()), + "" => openapi_get_routes_spec![root::root], + "/users" => users::routes(), + "/bots" => bots::routes(), + "/channels" => channels::routes(), + "/servers" => servers::routes(), + "/invites" => invites::routes(), + "/custom" => customisation::routes(), + "/safety" => safety::routes(), + "/auth/account" => rocket_authifier::routes::account::routes(), + "/auth/session" => rocket_authifier::routes::session::routes(), + "/auth/mfa" => rocket_authifier::routes::mfa::routes(), + "/onboard" => onboard::routes(), + "/push" => push::routes(), + "/sync" => sync::routes(), + "/webhooks" => webhooks::routes() + }; + } else { + mount_endpoints_and_merged_docs! { + rocket, "/0.8".to_owned(), settings, + "/" => (vec![], custom_openapi_spec()), + "" => openapi_get_routes_spec![root::root], + "/users" => users::routes(), + "/bots" => bots::routes(), + "/channels" => channels::routes(), + "/servers" => servers::routes(), + "/invites" => invites::routes(), + "/custom" => customisation::routes(), + "/safety" => safety::routes(), + "/auth/account" => rocket_authifier::routes::account::routes(), + "/auth/session" => rocket_authifier::routes::session::routes(), + "/auth/mfa" => rocket_authifier::routes::mfa::routes(), + "/onboard" => onboard::routes(), + "/push" => push::routes(), + "/sync" => sync::routes() + }; + } + rocket } From 5f39403ce78b90416305296ffa81e0137f0326db Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 18:34:37 +0000 Subject: [PATCH 09/35] fix: ensure ratelimiter adjusts for version prefix --- crates/delta/src/routes/mod.rs | 7 ++++++- crates/delta/src/util/ratelimiter.rs | 22 ++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 1f150e0b..5107e7c2 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -231,10 +231,15 @@ fn custom_openapi_spec() -> OpenApi { ..Default::default() }, Server { - url: "http://local.revolt.chat:8000".to_owned(), + url: "http://local.revolt.chat:14702".to_owned(), description: Some("Local Revolt Environment".to_owned()), ..Default::default() }, + Server { + url: "http://local.revolt.chat:14702/0.8".to_owned(), + description: Some("Local Revolt Environment (v0.8)".to_owned()), + ..Default::default() + }, ], external_docs: Some(ExternalDocs { url: "https://developers.revolt.chat".to_owned(), diff --git a/crates/delta/src/util/ratelimiter.rs b/crates/delta/src/util/ratelimiter.rs index c95f818d..95952918 100644 --- a/crates/delta/src/util/ratelimiter.rs +++ b/crates/delta/src/util/ratelimiter.rs @@ -94,14 +94,28 @@ pub struct Ratelimiter { /// /// Optionally, include a resource id to hash against. fn resolve_bucket<'r>(request: &'r rocket::Request<'_>) -> (&'r str, Option<&'r str>) { - if let Some(segment) = request.routed_segment(0) { - let resource = request.routed_segment(1); + let (segment, resource, extra) = if matches!(request.routed_segment(0), Some("0.8")) { + ( + request.routed_segment(1), + request.routed_segment(2), + request.routed_segment(3), + ) + } else { + ( + request.routed_segment(0), + request.routed_segment(1), + request.routed_segment(2), + ) + }; + + if let Some(segment) = segment { + let resource = resource; let method = request.method(); match (segment, resource, method) { ("users", target, Method::Patch) => ("user_edit", target), ("users", _, _) => { - if let Some("default_avatar") = request.routed_segment(2) { + if let Some("default_avatar") = extra { return ("default_avatar", None); } @@ -110,7 +124,7 @@ fn resolve_bucket<'r>(request: &'r rocket::Request<'_>) -> (&'r str, Option<&'r ("bots", _, _) => ("bots", None), ("channels", Some(id), _) => { if request.method() == Method::Post { - if let Some("messages") = request.routed_segment(2) { + if let Some("messages") = extra { return ("messaging", Some(id)); } } From a1e6a1921057906e3e4f56868aa15746d480713b Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 18:37:21 +0000 Subject: [PATCH 10/35] chore: bump version to 0.8.2 --- Cargo.lock | 26 +++++++++++++------------- crates/bindings/node/Cargo.toml | 8 ++++---- crates/bonfire/Cargo.toml | 4 ++-- crates/core/config/Cargo.toml | 4 ++-- crates/core/database/Cargo.toml | 12 ++++++------ crates/core/files/Cargo.toml | 6 +++--- crates/core/models/Cargo.toml | 6 +++--- crates/core/permissions/Cargo.toml | 4 ++-- crates/core/presence/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/pushd/Cargo.toml | 8 ++++---- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 10 +++++----- crates/services/january/Cargo.toml | 10 +++++----- 14 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a48bf1f9..5df45d5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5523,7 +5523,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.1" +version = "0.8.2" dependencies = [ "axum", "axum-macros", @@ -5560,7 +5560,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.1" +version = "0.8.2" dependencies = [ "async-channel 2.3.1", "async-std", @@ -5590,7 +5590,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.8.1" +version = "0.8.2" dependencies = [ "async-std", "cached", @@ -5606,7 +5606,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.1" +version = "0.8.2" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -5655,7 +5655,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.1" +version = "0.8.2" dependencies = [ "amqprs", "async-channel 1.6.1", @@ -5702,7 +5702,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.1" +version = "0.8.2" dependencies = [ "aes-gcm", "aws-config", @@ -5725,7 +5725,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.1" +version = "0.8.2" dependencies = [ "async-recursion", "axum", @@ -5753,7 +5753,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.1" +version = "0.8.2" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp 0.2.11", @@ -5771,7 +5771,7 @@ dependencies = [ [[package]] name = "revolt-nodejs-bindings" -version = "0.8.1" +version = "0.8.2" dependencies = [ "async-std", "neon", @@ -5784,7 +5784,7 @@ dependencies = [ [[package]] name = "revolt-permissions" -version = "0.8.1" +version = "0.8.2" dependencies = [ "async-std", "async-trait", @@ -5799,7 +5799,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.1" +version = "0.8.2" dependencies = [ "async-std", "log", @@ -5810,7 +5810,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.1" +version = "0.8.2" dependencies = [ "amqprs", "async-trait", @@ -5834,7 +5834,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.1" +version = "0.8.2" dependencies = [ "axum", "revolt_okapi", diff --git a/crates/bindings/node/Cargo.toml b/crates/bindings/node/Cargo.toml index 55ada675..43b9b856 100644 --- a/crates/bindings/node/Cargo.toml +++ b/crates/bindings/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-nodejs-bindings" -version = "0.8.1" +version = "0.8.2" description = "Node.js bindings for the Revolt software" authors = ["Paul Makles "] license = "MIT" @@ -20,6 +20,6 @@ serde = { version = "1", features = ["derive"] } async-std = "1.12.0" -revolt-config = { version = "0.8.1", path = "../../core/config" } -revolt-result = { version = "0.8.1", path = "../../core/result" } -revolt-database = { version = "0.8.1", path = "../../core/database" } +revolt-config = { version = "0.8.2", path = "../../core/config" } +revolt-result = { version = "0.8.2", path = "../../core/result" } +revolt-database = { version = "0.8.2", path = "../../core/database" } diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 86627e3c..ed13358b 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.1" +version = "0.8.2" license = "AGPL-3.0-or-later" edition = "2021" @@ -41,7 +41,7 @@ revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database" } -revolt-permissions = { version = "0.8.1", path = "../core/permissions" } +revolt-permissions = { version = "0.8.2", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 1e9c96d6..b23c10b9 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.1" +version = "0.8.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -34,4 +34,4 @@ pretty_env_logger = "0.4.0" sentry = "0.31.5" # Core -revolt-result = { version = "0.8.1", path = "../result", optional = true } +revolt-result = { version = "0.8.2", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index ba3de99a..d33dedd5 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.1" +version = "0.8.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -24,15 +24,15 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.1", path = "../config", features = [ +revolt-config = { version = "0.8.2", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.1", path = "../result" } -revolt-models = { version = "0.8.1", path = "../models", features = [ +revolt-result = { version = "0.8.2", path = "../result" } +revolt-models = { version = "0.8.2", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.1", path = "../presence" } -revolt-permissions = { version = "0.8.1", path = "../permissions", features = [ +revolt-presence = { version = "0.8.2", path = "../presence" } +revolt-permissions = { version = "0.8.2", path = "../permissions", features = [ "serde", "bson", ] } diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 59ce115a..de7d2d17 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.1" +version = "0.8.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.8.1", path = "../config", features = [ +revolt-config = { version = "0.8.2", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.1", path = "../result" } +revolt-result = { version = "0.8.2", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index b840d47f..4d0c7fa6 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.1" +version = "0.8.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.1", path = "../config" } -revolt-permissions = { version = "0.8.1", path = "../permissions" } +revolt-config = { version = "0.8.2", path = "../config" } +revolt-permissions = { version = "0.8.2", path = "../permissions" } # Utility regex = "1" diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index c30e9b74..daf61e8d 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.1" +version = "0.8.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.8.1", path = "../result" } +revolt-result = { version = "0.8.2", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 48ef797a..7df7c702 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.1" +version = "0.8.2" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 77ae3057..8b0b682f 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.1" +version = "0.8.2" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 231bba2f..a6f1c61f 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "revolt-pushd" -version = "0.8.1" +version = "0.8.2" edition = "2021" [dependencies] -revolt-config = { version = "0.8.1", path = "../../core/config" } -revolt-database = { version = "0.8.1", path = "../../core/database" } -revolt-models = { version = "0.8.1", path = "../../core/models", features = [ +revolt-config = { version = "0.8.2", path = "../../core/config" } +revolt-database = { version = "0.8.2", path = "../../core/database" } +revolt-models = { version = "0.8.2", path = "../../core/models", features = [ "validator", ] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 6df4a109..e048d7d3 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.1" +version = "0.8.2" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 580316c8..31356a89 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.1" +version = "0.8.2" edition = "2021" [dependencies] @@ -42,12 +42,12 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.1", path = "../../core/files" } -revolt-config = { version = "0.8.1", path = "../../core/config" } -revolt-database = { version = "0.8.1", path = "../../core/database", features = [ +revolt-files = { version = "0.8.2", path = "../../core/files" } +revolt-config = { version = "0.8.2", path = "../../core/config" } +revolt-database = { version = "0.8.2", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.1", path = "../../core/result", features = [ +revolt-result = { version = "0.8.2", path = "../../core/result", features = [ "utoipa", "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index b7ec1d1d..005ba406 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.1" +version = "0.8.2" edition = "2021" [dependencies] @@ -31,13 +31,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.1", path = "../../core/config" } -revolt-models = { version = "0.8.1", path = "../../core/models" } -revolt-result = { version = "0.8.1", path = "../../core/result", features = [ +revolt-config = { version = "0.8.2", path = "../../core/config" } +revolt-models = { version = "0.8.2", path = "../../core/models" } +revolt-result = { version = "0.8.2", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.1", path = "../../core/files" } +revolt-files = { version = "0.8.2", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } From 7216e9909b9e5687d3fb9cb0a429314abf8e21a2 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 18:50:19 +0000 Subject: [PATCH 11/35] chore: disable LTO because it likely overloads GitHub worker --- Cargo.toml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 98f61e66..903f3965 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,5 +16,9 @@ redis23 = { package = "redis", version = "0.23.1", git = "https://github.com/rev # authifier = { package = "authifier", version = "1.0.8", path = "../authifier/crates/authifier" } # rocket_authifier = { package = "rocket_authifier", version = "1.0.8", path = "../authifier/crates/rocket_authifier" } -[profile.release] -lto = true +# I'm 99% sure this is overloading the GitHub worker +# hence builds have been failing since, let's just +# disable it for now. In the future, we could use this +# if we were rolling our own CI. +# [profile.release] +# lto = true From add3f40b2308ef2858b5a4bc47d31dec90995abb Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 18:54:15 +0000 Subject: [PATCH 12/35] fix: don't allow users to time themselves out closes #376 --- crates/core/result/src/lib.rs | 1 + crates/delta/src/routes/servers/member_edit.rs | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index f3de55cd..4d5e1c65 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -116,6 +116,7 @@ pub enum ErrorType { max: usize, }, AlreadyInServer, + CannotTimeoutYourself, // ? Bot related errors ReachedMaximumBots, diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index b10a9a3e..005e65c7 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -15,12 +15,12 @@ use validator::Validate; /// /// Edit a member by their id. #[openapi(tag = "Server Members")] -#[patch("//members/", data = "")] +#[patch("//members/", data = "")] pub async fn edit( db: &State, user: User, server: Reference, - target: Reference, + member: Reference, data: Json, ) -> Result> { let data = data.into_inner(); @@ -30,9 +30,9 @@ pub async fn edit( }) })?; - // Fetch server and target member + // Fetch server and member let mut server = server.as_server(db).await?; - let mut member = target.as_member(db, &server.id).await?; + let mut member = member.as_member(db, &server.id).await?; // Fetch our currrent permissions let mut query = DatabasePermissionQuery::new(db, &user).server(&server); @@ -84,6 +84,10 @@ pub async fn edit( .map(|x| x.contains(&v0::FieldsMember::Timeout)) .unwrap_or_default() { + if data.timeout.is_some() && member.id.user == user.id { + return Err(create_error!(CannotTimeoutYourself)); + } + permissions.throw_if_lacking_channel_permission(ChannelPermission::TimeoutMembers)?; } From 7026961df4179e7281baa12e4efe8f98bb6961d0 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 19:03:48 +0000 Subject: [PATCH 13/35] chore: fix version references --- Cargo.lock | 4 ++-- crates/daemons/crond/Cargo.toml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09fed370..84c6965d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5606,14 +5606,14 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.7.19" +version = "0.8.2" dependencies = [ "log", "revolt-config", "revolt-database", "revolt-files", "revolt-result", - "tokio 1.35.1", + "tokio 1.40.0", ] [[package]] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index f2c4b94f..bd5d3f3b 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.7.19" +version = "0.8.2" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.7.19", path = "../../core/database" } -revolt-result = { version = "0.7.19", path = "../../core/result" } -revolt-config = { version = "0.7.19", path = "../../core/config" } -revolt-files = { version = "0.7.19", path = "../../core/files" } +revolt-database = { version = "0.8.2", path = "../../core/database" } +revolt-result = { version = "0.8.2", path = "../../core/result" } +revolt-config = { version = "0.8.2", path = "../../core/config" } +revolt-files = { version = "0.8.2", path = "../../core/files" } From defc9ec79bddf7f1a72e0a8eb5d7f6639acfef73 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 19:05:21 +0000 Subject: [PATCH 14/35] fix: match new error type for status code --- crates/core/result/src/axum.rs | 1 + crates/core/result/src/rocket.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index 80417d14..8c4c6491 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -42,6 +42,7 @@ impl IntoResponse for Error { ErrorType::InvalidRole => StatusCode::NOT_FOUND, ErrorType::Banned => StatusCode::FORBIDDEN, ErrorType::AlreadyInServer => StatusCode::CONFLICT, + ErrorType::CannotTimeoutYourself => StatusCode::BAD_REQUEST, ErrorType::TooManyServers { .. } => StatusCode::BAD_REQUEST, ErrorType::TooManyEmbeds { .. } => StatusCode::BAD_REQUEST, diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 4a39e2be..6b889c58 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -47,6 +47,7 @@ impl<'r> Responder<'r, 'static> for Error { ErrorType::InvalidRole => Status::NotFound, ErrorType::Banned => Status::Forbidden, ErrorType::AlreadyInServer => Status::Conflict, + ErrorType::CannotTimeoutYourself => Status::BadRequest, ErrorType::TooManyServers { .. } => Status::BadRequest, ErrorType::TooManyEmbeds { .. } => Status::BadRequest, From eb5f5f91cdd2eb37b4b99ed66b90887b8c6f4895 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 10 Feb 2025 20:28:48 +0000 Subject: [PATCH 15/35] feat: add crond container definitions --- .github/workflows/docker.yaml | 4 ++++ Dockerfile | 1 + Dockerfile.useCurrentArch | 1 + README.md | 1 + crates/daemons/crond/Dockerfile | 10 ++++++++++ scripts/build-image-layer.sh | 3 +++ scripts/publish-debug-image.sh | 2 ++ 7 files changed, 22 insertions(+) create mode 100644 crates/daemons/crond/Dockerfile diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 58e186d0..76107876 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -110,6 +110,10 @@ jobs: "pushd": { "path": "crates/daemons/pushd", "tag": "${{ github.repository_owner }}/pushd" + }, + "crond": { + "path": "crates/daemons/crond", + "tag": "${{ github.repository_owner }}/crond" } } export_to: output diff --git a/Dockerfile b/Dockerfile index 10112b66..c75748c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,7 @@ COPY crates/core/presence/Cargo.toml ./crates/core/presence/ COPY crates/core/result/Cargo.toml ./crates/core/result/ COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/ COPY crates/services/january/Cargo.toml ./crates/services/january/ +COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ COPY crates/daemons/pushd/Cargo.toml ./crates/daemons/pushd/ RUN sh /tmp/build-image-layer.sh deps diff --git a/Dockerfile.useCurrentArch b/Dockerfile.useCurrentArch index 34a69462..54b508ef 100644 --- a/Dockerfile.useCurrentArch +++ b/Dockerfile.useCurrentArch @@ -25,6 +25,7 @@ COPY crates/core/presence/Cargo.toml ./crates/core/presence/ COPY crates/core/result/Cargo.toml ./crates/core/result/ COPY crates/services/autumn/Cargo.toml ./crates/services/autumn/ COPY crates/services/january/Cargo.toml ./crates/services/january/ +COPY crates/daemons/crond/Cargo.toml ./crates/daemons/crond/ COPY crates/daemons/pushd/Cargo.toml ./crates/daemons/pushd/ RUN sh /tmp/build-image-layer.sh deps diff --git a/README.md b/README.md index c480340f..d0894dee 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ The services and libraries that power the Revolt service.
| `services/january` | [crates/services/january](crates/services/january) | Proxy server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `services/autumn` | [crates/services/autumn](crates/services/autumn) | File server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `bindings/node` | [crates/bindings/node](crates/bindings/node) | Node.js bindings for the Revolt software | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| `daemons/crond` | [crates/daemons/crond](crates/daemons/crond) | Timed data clean up daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | | `daemons/pushd` | [crates/daemons/pushd](crates/daemons/pushd) | Push notification daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | diff --git a/crates/daemons/crond/Dockerfile b/crates/daemons/crond/Dockerfile new file mode 100644 index 00000000..8a4c915a --- /dev/null +++ b/crates/daemons/crond/Dockerfile @@ -0,0 +1,10 @@ +# Build Stage +FROM ghcr.io/revoltchat/base:latest AS builder +FROM debian:12 AS debian + +# Bundle Stage +FROM gcr.io/distroless/cc-debian12:nonroot +COPY --from=builder /home/rust/src/target/release/revolt-crond ./ + +USER nonroot +CMD ["./revolt-crond"] \ No newline at end of file diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 4b2e18c4..064ee756 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -34,12 +34,14 @@ deps() { crates/core/result/src \ crates/services/autumn/src \ crates/services/january/src \ + crates/daemons/crond/src \ crates/daemons/pushd/src echo 'fn main() { panic!("stub"); }' | tee crates/bonfire/src/main.rs | tee crates/delta/src/main.rs | tee crates/services/autumn/src/main.rs | tee crates/services/january/src/main.rs | + tee crates/daemons/crond/src/main.rs | tee crates/daemons/pushd/src/main.rs echo '' | tee crates/bindings/node/src/lib.rs | @@ -62,6 +64,7 @@ apps() { touch -am \ crates/bonfire/src/main.rs \ crates/delta/src/main.rs \ + crates/daemons/crond/src/main.rs \ crates/daemons/pushd/src/main.rs \ crates/core/config/src/lib.rs \ crates/core/database/src/lib.rs \ diff --git a/scripts/publish-debug-image.sh b/scripts/publish-debug-image.sh index 247338ab..6686344c 100755 --- a/scripts/publish-debug-image.sh +++ b/scripts/publish-debug-image.sh @@ -25,6 +25,7 @@ docker build -t ghcr.io/revoltchat/server:$TAG - < crates/delta/Dockerfile docker build -t ghcr.io/revoltchat/bonfire:$TAG - < crates/bonfire/Dockerfile docker build -t ghcr.io/revoltchat/autumn:$TAG - < crates/services/autumn/Dockerfile docker build -t ghcr.io/revoltchat/january:$TAG - < crates/services/january/Dockerfile +docker build -t ghcr.io/revoltchat/crond:$TAG - < crates/daemons/crond/Dockerfile docker build -t ghcr.io/revoltchat/pushd:$TAG - < crates/daemons/pushd/Dockerfile if [ "$DEBUG" = "true" ]; then @@ -35,4 +36,5 @@ docker push ghcr.io/revoltchat/server:$TAG docker push ghcr.io/revoltchat/bonfire:$TAG docker push ghcr.io/revoltchat/autumn:$TAG docker push ghcr.io/revoltchat/january:$TAG +docker push ghcr.io/revoltchat/crond:$TAG docker push ghcr.io/revoltchat/pushd:$TAG From 3ceefb840bdfb5957431908499ac6fbe21717050 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Tue, 18 Feb 2025 11:53:21 +0000 Subject: [PATCH 16/35] chore: clarify cargo deny / tomls --- crates/daemons/pushd/Cargo.toml | 1 + crates/services/autumn/Cargo.toml | 1 + crates/services/january/Cargo.toml | 1 + deny.toml | 185 ++++++++++++++++++----------- 4 files changed, 116 insertions(+), 72 deletions(-) diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index a6f1c61f..be0e3cc5 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -2,6 +2,7 @@ name = "revolt-pushd" version = "0.8.2" edition = "2021" +license = "AGPL-3.0-or-later" [dependencies] revolt-config = { version = "0.8.2", path = "../../core/config" } diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 31356a89..4b944f55 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -2,6 +2,7 @@ name = "revolt-autumn" version = "0.8.2" edition = "2021" +license = "AGPL-3.0-or-later" [dependencies] # ID generation diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 005ba406..a053d11a 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -2,6 +2,7 @@ name = "revolt-january" version = "0.8.2" edition = "2021" +license = "AGPL-3.0-or-later" [dependencies] # Utility diff --git a/deny.toml b/deny.toml index 48dc5f08..d8f1bf67 100644 --- a/deny.toml +++ b/deny.toml @@ -9,6 +9,11 @@ # The values provided in this template are the default values that will be used # when any section or field is not specified in your own configuration +# Root options + +# The graph table configures how the dependency graph is constructed and thus +# which crates the checks are performed against +[graph] # If 1 or more target triples (and optionally, target_features) are specified, # only the specified targets will be checked when running `cargo deny check`. # This means, if a particular package is only ever used as a target specific @@ -20,85 +25,83 @@ targets = [ # The triple can be any string, but only the target triples built in to # rustc (as of 1.40) can be checked against actual config expressions - #{ triple = "x86_64-unknown-linux-musl" }, + #"x86_64-unknown-linux-musl", # You can also specify which target_features you promise are enabled for a # particular target. target_features are currently not validated against # the actual valid features supported by the target architecture. #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, ] +# When creating the dependency graph used as the source of truth when checks are +# executed, this field can be used to prune crates from the graph, removing them +# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate +# is pruned from the graph, all of its dependencies will also be pruned unless +# they are connected to another crate in the graph that hasn't been pruned, +# so it should be used with care. The identifiers are [Package ID Specifications] +# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) +#exclude = [] +# If true, metadata will be collected with `--all-features`. Note that this can't +# be toggled off if true, if you want to conditionally enable `--all-features` it +# is recommended to pass `--all-features` on the cmd line instead +all-features = false +# If true, metadata will be collected with `--no-default-features`. The same +# caveat with `all-features` applies +no-default-features = false +# If set, these feature will be enabled when collecting metadata. If `--features` +# is specified on the cmd line they will take precedence over this option. +#features = [] + +# The output table provides options for how/if diagnostics are outputted +[output] +# When outputting inclusion graphs in diagnostics that include features, this +# option can be used to specify the depth at which feature edges will be added. +# This option is included since the graphs can be quite large and the addition +# of features from the crate(s) to all of the graph roots can be far too verbose. +# This option can be overridden via `--feature-depth` on the cmd line +feature-depth = 1 # This section is considered when running `cargo deny check advisories` # More documentation for the advisories section can be found here: # https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html [advisories] -# The path where the advisory database is cloned/fetched into -db-path = "~/.cargo/advisory-db" +# The path where the advisory databases are cloned/fetched into +#db-path = "$CARGO_HOME/advisory-dbs" # The url(s) of the advisory databases to use -db-urls = ["https://github.com/rustsec/advisory-db"] -# The lint level for security vulnerabilities -vulnerability = "deny" -# The lint level for unmaintained crates -unmaintained = "warn" -# The lint level for crates that have been yanked from their source registry -yanked = "warn" -# The lint level for crates with security notices. Note that as of -# 2019-12-17 there are no security notice advisories in -# https://github.com/rustsec/advisory-db -notice = "warn" +#db-urls = ["https://github.com/rustsec/advisory-db"] # A list of advisory IDs to ignore. Note that ignored advisories will still # output a note when they are encountered. ignore = [ #"RUSTSEC-0000-0000", + #{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" }, + #"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish + #{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" }, ] -# Threshold for security vulnerabilities, any vulnerability with a CVSS score -# lower than the range specified will be ignored. Note that ignored advisories -# will still output a note when they are encountered. -# * None - CVSS Score 0.0 -# * Low - CVSS Score 0.1 - 3.9 -# * Medium - CVSS Score 4.0 - 6.9 -# * High - CVSS Score 7.0 - 8.9 -# * Critical - CVSS Score 9.0 - 10.0 -#severity-threshold = +# If this is true, then cargo deny will use the git executable to fetch advisory database. +# If this is false, then it uses a built-in git library. +# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. +# See Git Authentication for more information about setting up git authentication. +#git-fetch-with-cli = true # This section is considered when running `cargo deny check licenses` # More documentation for the licenses section can be found here: # https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html [licenses] -# The lint level for crates which do not have a detectable license -unlicensed = "warn" # List of explicitly allowed licenses # See https://spdx.org/licenses/ for list of possible licenses # [possible values: any SPDX 3.11 short identifier (+ optional exception)]. allow = [ + # any non-copyleft licenses are okay! "MIT", "ISC", "0BSD", + "Zlib", "CC0-1.0", + "MPL-2.0", "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", "BSD-2-Clause", "BSD-3-Clause", - #"Apache-2.0 WITH LLVM-exception", + "OpenSSL", ] -# List of explicitly disallowed licenses -# See https://spdx.org/licenses/ for list of possible licenses -# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. -deny = [ - #"Nokia", -] -# Lint level for licenses considered copyleft -copyleft = "warn" -# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses -# * both - The license will be approved if it is both OSI-approved *AND* FSF -# * either - The license will be approved if it is either OSI-approved *OR* FSF -# * osi-only - The license will be approved if is OSI-approved *AND NOT* FSF -# * fsf-only - The license will be approved if is FSF *AND NOT* OSI-approved -# * neither - This predicate is ignored and the default lint level is used -allow-osi-fsf-free = "neither" -# Lint level used when no other predicates are matched -# 1. License isn't in the allow or deny lists -# 2. License isn't copyleft -# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" -default = "deny" # The confidence threshold for detecting a license from license text. # The higher the value, the more closely the license text must be to the # canonical license text of a valid SPDX license file. @@ -108,29 +111,34 @@ confidence-threshold = 0.8 # aren't accepted for every possible crate as with the normal allow list exceptions = [ # Each entry is the crate and version constraint, and its specific allow - # list - #{ allow = ["Zlib"], name = "adler32", version = "*" }, + { allow = ["AGPL-3.0"], crate = "revolt-database" }, + { allow = ["AGPL-3.0"], crate = "revolt-presence" }, + { allow = ["AGPL-3.0"], crate = "revolt-files" }, + { allow = ["AGPL-3.0"], crate = "revolt-pushd" }, + { allow = ["AGPL-3.0"], crate = "revolt-crond" }, + { allow = ["AGPL-3.0"], crate = "revolt-delta" }, + { allow = ["AGPL-3.0"], crate = "revolt-bonfire" }, + { allow = ["AGPL-3.0"], crate = "revolt-autumn" }, + { allow = ["AGPL-3.0"], crate = "revolt-january" }, ] # Some crates don't have (easily) machine readable licensing information, # adding a clarification entry for it allows you to manually specify the # licensing information -#[[licenses.clarify]] -# The name of the crate the clarification applies to -#name = "ring" -# The optional version constraint for the crate -#version = "*" +[[licenses.clarify]] +# The package spec the clarification applies to +crate = "ring" # The SPDX expression for the license requirements of the crate -#expression = "MIT AND ISC AND OpenSSL" +expression = "MIT AND ISC AND OpenSSL" # One or more files in the crate's source used as the "source of truth" for # the license expression. If the contents match, the clarification will be used # when running the license check, otherwise the clarification will be ignored # and the crate will be checked normally, which may produce warnings or errors # depending on the rest of your configuration -#license-files = [ +license-files = [ # Each entry is a crate relative path, and the (opaque) hash of its contents - #{ path = "LICENSE", hash = 0xbd0eed23 } -#] + { path = "LICENSE", hash = 0xbd0eed23 }, +] [licenses.private] # If true, ignores workspace crates that aren't published, or are only @@ -159,30 +167,63 @@ wildcards = "allow" # * simplest-path - The path to the version with the fewest edges is highlighted # * all - Both lowest-version and simplest-path are used highlight = "all" +# The default lint level for `default` features for crates that are members of +# the workspace that is being checked. This can be overridden by allowing/denying +# `default` on a crate-by-crate basis if desired. +workspace-default-features = "allow" +# The default lint level for `default` features for external crates that are not +# members of the workspace. This can be overridden by allowing/denying `default` +# on a crate-by-crate basis if desired. +external-default-features = "allow" # List of crates that are allowed. Use with care! allow = [ - #{ name = "ansi_term", version = "=0.11.0" }, + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is allowed" }, ] # List of crates to deny deny = [ - # Each entry the name of a crate and a version range. If version is - # not specified, all versions will be matched. - #{ name = "ansi_term", version = "=0.11.0" }, - # + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is banned" }, # Wrapper crates can optionally be specified to allow the crate when it # is a direct dependency of the otherwise banned crate - #{ name = "ansi_term", version = "=0.11.0", wrappers = [] }, + #{ crate = "ansi_term@0.11.0", wrappers = ["this-crate-directly-depends-on-ansi_term"] }, ] + +# List of features to allow/deny +# Each entry the name of a crate and a version range. If version is +# not specified, all versions will be matched. +#[[bans.features]] +#crate = "reqwest" +# Features to not allow +#deny = ["json"] +# Features to allow +#allow = [ +# "rustls", +# "__rustls", +# "__tls", +# "hyper-rustls", +# "rustls", +# "rustls-pemfile", +# "rustls-tls-webpki-roots", +# "tokio-rustls", +# "webpki-roots", +#] +# If true, the allowed features must exactly match the enabled feature set. If +# this is set there is no point setting `deny` +#exact = true + # Certain crates/versions that will be skipped when doing duplicate detection. skip = [ - #{ name = "ansi_term", version = "=0.11.0" }, + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason why it can't be updated/removed" }, ] # Similarly to `skip` allows you to skip certain crates during duplicate # detection. Unlike skip, it also includes the entire tree of transitive # dependencies starting at the specified crate, up to a certain depth, which is -# by default infinite +# by default infinite. skip-tree = [ - #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, + #"ansi_term@0.11.0", # will be skipped along with _all_ of its direct and transitive dependencies + #{ crate = "ansi_term@0.11.0", depth = 20 }, ] # This section is considered when running `cargo deny check sources`. @@ -202,9 +243,9 @@ allow-registry = ["https://github.com/rust-lang/crates.io-index"] allow-git = [] [sources.allow-org] -# 1 or more github.com organizations to allow git sources for -github = ["insertish"] -# 1 or more gitlab.com organizations to allow git sources for -# gitlab = [] -# 1 or more bitbucket.org organizations to allow git sources for -# bitbucket = [""] +# github.com organizations to allow git sources for +github = [] +# gitlab.com organizations to allow git sources for +gitlab = [] +# bitbucket.org organizations to allow git sources for +bitbucket = [] From 01490f572358a9ea81e2cb3ff29bfa57f3321ee7 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Mon, 24 Feb 2025 22:17:48 +0000 Subject: [PATCH 17/35] feat: add company information to email footers --- crates/core/config/src/lib.rs | 10 +- crates/core/database/src/drivers/mod.rs | 64 +- crates/core/database/templates/deletion.html | 527 +++------------- .../database/templates/deletion.original.html | 8 + crates/core/database/templates/deletion.txt | 7 + .../templates/deletion.whitelabel.txt | 9 + .../templates/policy-change.original.html | 53 ++ crates/core/database/templates/reset.html | 524 +++------------- .../database/templates/reset.original.html | 8 + crates/core/database/templates/reset.txt | 7 + .../database/templates/reset.whitelabel.txt | 9 + .../core/database/templates/suspension.html | 587 +++--------------- .../templates/suspension.original.html | 8 + crates/core/database/templates/suspension.txt | 7 + .../templates/suspension.whitelabel.txt | 8 + crates/core/database/templates/verify.html | 524 +++------------- .../database/templates/verify.original.html | 8 + crates/core/database/templates/verify.txt | 7 + .../database/templates/verify.whitelabel.txt | 10 + 19 files changed, 502 insertions(+), 1883 deletions(-) create mode 100644 crates/core/database/templates/deletion.whitelabel.txt create mode 100644 crates/core/database/templates/policy-change.original.html create mode 100644 crates/core/database/templates/reset.whitelabel.txt create mode 100644 crates/core/database/templates/suspension.whitelabel.txt create mode 100644 crates/core/database/templates/verify.whitelabel.txt diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 9bffd526..c2e35bd7 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -337,6 +337,7 @@ pub struct Settings { pub files: Files, pub features: Features, pub sentry: Sentry, + pub production: bool, } impl Settings { @@ -364,7 +365,14 @@ pub async fn read() -> Config { #[cached(time = 30)] pub async fn config() -> Settings { - read().await.try_deserialize::().unwrap() + let mut config = read().await.try_deserialize::().unwrap(); + + // auto-detect production nodes + if config.hosts.api.contains("https") && config.hosts.api.contains("revolt.chat") { + config.production = true; + } + + config } /// Configure logging and common Rust variables diff --git a/crates/core/database/src/drivers/mod.rs b/crates/core/database/src/drivers/mod.rs index 7162777e..11fd5822 100644 --- a/crates/core/database/src/drivers/mod.rs +++ b/crates/core/database/src/drivers/mod.rs @@ -120,26 +120,50 @@ impl Database { use_tls: config.api.smtp.use_tls, }, expiry: Default::default(), - templates: Templates { - verify: Template { - title: "Verify your Revolt account.".into(), - text: include_str!("../../templates/verify.txt").into(), - url: format!("{}/login/verify/", config.hosts.app), - html: Some(include_str!("../../templates/verify.html").into()), - }, - reset: Template { - title: "Reset your Revolt password.".into(), - text: include_str!("../../templates/reset.txt").into(), - url: format!("{}/login/reset/", config.hosts.app), - html: Some(include_str!("../../templates/reset.html").into()), - }, - deletion: Template { - title: "Confirm account deletion.".into(), - text: include_str!("../../templates/deletion.txt").into(), - url: format!("{}/delete/", config.hosts.app), - html: Some(include_str!("../../templates/deletion.html").into()), - }, - welcome: None, + templates: if config.production { + Templates { + verify: Template { + title: "Verify your Revolt account.".into(), + text: include_str!("../../templates/verify.txt").into(), + url: format!("{}/login/verify/", config.hosts.app), + html: Some(include_str!("../../templates/verify.html").into()), + }, + reset: Template { + title: "Reset your Revolt password.".into(), + text: include_str!("../../templates/reset.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: Some(include_str!("../../templates/reset.html").into()), + }, + deletion: Template { + title: "Confirm account deletion.".into(), + text: include_str!("../../templates/deletion.txt").into(), + url: format!("{}/delete/", config.hosts.app), + html: Some(include_str!("../../templates/deletion.html").into()), + }, + welcome: None, + } + } else { + Templates { + verify: Template { + title: "Verify your account.".into(), + text: include_str!("../../templates/verify.whitelabel.txt").into(), + url: format!("{}/login/verify/", config.hosts.app), + html: None, + }, + reset: Template { + title: "Reset your password.".into(), + text: include_str!("../../templates/reset.whitelabel.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: None, + }, + deletion: Template { + title: "Confirm account deletion.".into(), + text: include_str!("../../templates/deletion.whitelabel.txt").into(), + url: format!("{}/delete/", config.hosts.app), + html: None, + }, + welcome: None, + } }, } } else { diff --git a/crates/core/database/templates/deletion.html b/crates/core/database/templates/deletion.html index ef19ee40..d2513883 100644 --- a/crates/core/database/templates/deletion.html +++ b/crates/core/database/templates/deletion.html @@ -1,464 +1,93 @@ - - - - - - + + + + + - - + + -