From c4728c696d1fd2ea39c41961db751ea9360ed4f9 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 30 May 2025 13:12:57 +0100 Subject: [PATCH] feat: policy changes API chore: bump version to 0.8.7 --- Cargo.lock | 28 +++++------ crates/bonfire/Cargo.toml | 4 +- crates/bonfire/src/events/impl.rs | 15 ++++++ crates/core/config/Cargo.toml | 4 +- crates/core/database/Cargo.toml | 14 +++--- crates/core/database/src/drivers/reference.rs | 5 +- crates/core/database/src/events/client.rs | 4 +- .../admin_migrations/ops/mongodb/init.rs | 4 ++ .../admin_migrations/ops/mongodb/scripts.rs | 32 +++++++++++-- crates/core/database/src/models/mod.rs | 3 ++ .../database/src/models/policy_changes/mod.rs | 5 ++ .../src/models/policy_changes/model.rs | 20 ++++++++ .../database/src/models/policy_changes/ops.rs | 15 ++++++ .../src/models/policy_changes/ops/mongodb.rs | 46 +++++++++++++++++++ .../models/policy_changes/ops/reference.rs | 31 +++++++++++++ .../core/database/src/models/users/model.rs | 4 ++ crates/core/database/src/util/bridge/v0.rs | 13 ++++++ crates/core/files/Cargo.toml | 6 +-- crates/core/models/Cargo.toml | 6 +-- crates/core/models/src/v0/mod.rs | 2 + crates/core/models/src/v0/policy_changes.rs | 16 +++++++ crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +- crates/core/presence/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 ++-- crates/daemons/pushd/Cargo.toml | 12 ++--- crates/delta/Cargo.toml | 2 +- crates/delta/src/routes/mod.rs | 3 ++ .../policy/acknowledge_policy_changes.rs | 17 +++++++ crates/delta/src/routes/policy/mod.rs | 11 +++++ crates/services/autumn/Cargo.toml | 10 ++-- crates/services/january/Cargo.toml | 10 ++-- 33 files changed, 298 insertions(+), 64 deletions(-) create mode 100644 crates/core/database/src/models/policy_changes/mod.rs create mode 100644 crates/core/database/src/models/policy_changes/model.rs create mode 100644 crates/core/database/src/models/policy_changes/ops.rs create mode 100644 crates/core/database/src/models/policy_changes/ops/mongodb.rs create mode 100644 crates/core/database/src/models/policy_changes/ops/reference.rs create mode 100644 crates/core/models/src/v0/policy_changes.rs create mode 100644 crates/delta/src/routes/policy/acknowledge_policy_changes.rs create mode 100644 crates/delta/src/routes/policy/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 712754c9..f932a03c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5954,7 +5954,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.6" +version = "0.8.7" dependencies = [ "axum", "axum-macros", @@ -5991,7 +5991,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-channel 2.3.1", "async-std", @@ -6021,7 +6021,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-std", "cached", @@ -6038,7 +6038,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.8.6" +version = "0.8.7" dependencies = [ "log", "revolt-config", @@ -6050,7 +6050,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.6" +version = "0.8.7" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6100,7 +6100,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.6" +version = "0.8.7" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6147,7 +6147,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.6" +version = "0.8.7" dependencies = [ "aes-gcm", "aws-config", @@ -6170,7 +6170,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-recursion", "axum", @@ -6198,7 +6198,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.6" +version = "0.8.7" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6217,14 +6217,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.8.6" +version = "0.8.7" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-std", "async-trait", @@ -6239,7 +6239,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-std", "log", @@ -6250,7 +6250,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.6" +version = "0.8.7" dependencies = [ "amqprs", "anyhow", @@ -6278,7 +6278,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.6" +version = "0.8.7" dependencies = [ "axum", "revolt_okapi", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 5a55f1aa..1f38becf 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.6" +version = "0.8.7" 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.6", path = "../core/permissions" } +revolt-permissions = { version = "0.8.7", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 62da6108..160e7c6c 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -100,6 +100,18 @@ impl State { let user = self.clone_user(); self.cache.is_bot = user.bot.is_some(); + // Fetch pending policy changes. + let policy_changes = if user.bot.is_some() { + vec![] + } else { + db.fetch_policy_changes() + .await? + .into_iter() + .filter(|policy| policy.created_time > user.last_acknowledged_policy_change) + .map(Into::into) + .collect() + }; + // Find all relationships to the user. let mut user_ids: HashSet = user .relations @@ -227,6 +239,7 @@ impl State { for channel in &channels { self.insert_subscription(channel.id().to_string()).await; } + Ok(EventV1::Ready { users: if fields.contains(&ReadyPayloadFields::Users) { Some(users) @@ -252,6 +265,8 @@ impl State { user_settings, channel_unreads: channel_unreads.map(|vec| vec.into_iter().map(Into::into).collect()), + + policy_changes, }) } diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 02595ac9..7254866f 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -36,4 +36,4 @@ sentry = "0.31.5" sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.8.6", path = "../result", optional = true } +revolt-result = { version = "0.8.7", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 81b0224e..976d1384 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -24,19 +24,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.6", path = "../config", features = [ +revolt-config = { version = "0.8.7", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.6", path = "../result" } -revolt-models = { version = "0.8.6", path = "../models", features = [ +revolt-result = { version = "0.8.7", path = "../result" } +revolt-models = { version = "0.8.7", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.6", path = "../presence" } -revolt-permissions = { version = "0.8.6", path = "../permissions", features = [ +revolt-presence = { version = "0.8.7", path = "../presence" } +revolt-permissions = { version = "0.8.7", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.8.6", path = "../parser" } +revolt-parser = { version = "0.8.7", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/database/src/drivers/reference.rs b/crates/core/database/src/drivers/reference.rs index 9c51d422..ff18f253 100644 --- a/crates/core/database/src/drivers/reference.rs +++ b/crates/core/database/src/drivers/reference.rs @@ -4,8 +4,8 @@ use futures::lock::Mutex; use crate::{ Bot, Channel, ChannelCompositeKey, ChannelUnread, Emoji, File, FileHash, Invite, Member, - MemberCompositeKey, Message, RatelimitEvent, Report, Server, ServerBan, Snapshot, User, - UserSettings, Webhook, + MemberCompositeKey, Message, PolicyChange, RatelimitEvent, Report, Server, ServerBan, Snapshot, + User, UserSettings, Webhook, }; database_derived!( @@ -21,6 +21,7 @@ database_derived!( pub file_hashes: Arc>>, pub files: Arc>>, pub messages: Arc>>, + pub policy_changes: Arc>>, pub ratelimit_events: Arc>>, pub user_settings: Arc>>, pub users: Arc>>, diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index b35007cc..af480d5a 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -6,7 +6,7 @@ use revolt_models::v0::{ AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, - PartialWebhook, RemovalIntention, Report, Server, User, UserSettings, Webhook, + PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, Webhook, }; use crate::Database; @@ -62,6 +62,8 @@ pub enum EventV1 { user_settings: Option, #[serde(skip_serializing_if = "Option::is_none")] channel_unreads: Option>, + + policy_changes: Vec, }, /// Ping response diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs index 00fe26b8..4a422cbb 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs @@ -64,6 +64,10 @@ pub async fn create_database(db: &MongoDb) { .await .expect("Failed to create user_settings collection."); + db.create_collection("policy_changes") + .await + .expect("Failed to create policy_changes collection."); + db.create_collection("safety_reports") .await .expect("Failed to create safety_reports collection."); diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index aafee066..0f58082a 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -5,10 +5,11 @@ use crate::{ bson::{doc, from_bson, from_document, to_document, Bson, DateTime, Document}, options::FindOptions, }, - AbstractChannels, AbstractServers, Channel, Invite, MongoDb, DISCRIMINATOR_SEARCH_SPACE, + AbstractChannels, AbstractServers, Channel, Invite, MongoDb, User, DISCRIMINATOR_SEARCH_SPACE, }; -use bson::oid::ObjectId; +use bson::{oid::ObjectId, to_bson}; use futures::StreamExt; +use iso8601_timestamp::Timestamp; use rand::seq::SliceRandom; use revolt_permissions::DEFAULT_WEBHOOK_PERMISSIONS; use revolt_result::{Error, ErrorType}; @@ -21,7 +22,7 @@ struct MigrationInfo { revision: i32, } -pub const LATEST_REVISION: i32 = 33; // MUST BE +1 to last migration +pub const LATEST_REVISION: i32 = 41; // MUST BE +1 to last migration pub async fn migrate_database(db: &MongoDb) { let migrations = db.col::("migrations"); @@ -1139,6 +1140,31 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .unwrap(); } + if revision <= 40 { + info!( + "Running migration [revision |> 40 / 30-05-2025]: Set last policy acknowlegement date to now and create policy changes collection." + ); + + db.db() + .create_collection("policy_changes") + .await + .expect("Failed to create policy_changes collection."); + + db.db() + .collection::("users") + .update_many( + doc! {}, + doc! { + "$set": { + "last_acknowledged_policy_change": to_bson(&Timestamp::now_utc()) + .expect("failed to serialise timestamp") + } + }, + ) + .await + .expect("failed to update users"); + } + // Reminder to update LATEST_REVISION when adding new migrations. LATEST_REVISION.max(revision) } diff --git a/crates/core/database/src/models/mod.rs b/crates/core/database/src/models/mod.rs index 671c7abb..181a30c0 100644 --- a/crates/core/database/src/models/mod.rs +++ b/crates/core/database/src/models/mod.rs @@ -8,6 +8,7 @@ mod emojis; mod file_hashes; mod files; mod messages; +mod policy_changes; mod ratelimit_events; mod safety_reports; mod safety_snapshots; @@ -27,6 +28,7 @@ pub use emojis::*; pub use file_hashes::*; pub use files::*; pub use messages::*; +pub use policy_changes::*; pub use ratelimit_events::*; pub use safety_reports::*; pub use safety_snapshots::*; @@ -51,6 +53,7 @@ pub trait AbstractDatabase: + file_hashes::AbstractAttachmentHashes + files::AbstractAttachments + messages::AbstractMessages + + policy_changes::AbstractPolicyChange + ratelimit_events::AbstractRatelimitEvents + safety_reports::AbstractReport + safety_snapshots::AbstractSnapshot diff --git a/crates/core/database/src/models/policy_changes/mod.rs b/crates/core/database/src/models/policy_changes/mod.rs new file mode 100644 index 00000000..4d801b73 --- /dev/null +++ b/crates/core/database/src/models/policy_changes/mod.rs @@ -0,0 +1,5 @@ +mod model; +mod ops; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/policy_changes/model.rs b/crates/core/database/src/models/policy_changes/model.rs new file mode 100644 index 00000000..54109505 --- /dev/null +++ b/crates/core/database/src/models/policy_changes/model.rs @@ -0,0 +1,20 @@ +use iso8601_timestamp::Timestamp; + +auto_derived!( + /// Platform policy change + pub struct PolicyChange { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + + /// Time at which this policy was created + pub created_time: Timestamp, + /// Time at which this policy is effective + pub effective_time: Timestamp, + + /// Message shown to users + pub description: String, + /// URL with details about changes + pub url: String, + } +); diff --git a/crates/core/database/src/models/policy_changes/ops.rs b/crates/core/database/src/models/policy_changes/ops.rs new file mode 100644 index 00000000..2692a81f --- /dev/null +++ b/crates/core/database/src/models/policy_changes/ops.rs @@ -0,0 +1,15 @@ +use revolt_result::Result; + +use crate::PolicyChange; + +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractPolicyChange: Sync + Send { + /// Fetch all policy changes + async fn fetch_policy_changes(&self) -> Result>; + + /// Acknowledge policy changes + async fn acknowledge_policy_changes(&self, user_id: &str) -> Result<()>; +} diff --git a/crates/core/database/src/models/policy_changes/ops/mongodb.rs b/crates/core/database/src/models/policy_changes/ops/mongodb.rs new file mode 100644 index 00000000..fb70646f --- /dev/null +++ b/crates/core/database/src/models/policy_changes/ops/mongodb.rs @@ -0,0 +1,46 @@ +use bson::to_bson; +use iso8601_timestamp::Timestamp; +use revolt_result::Result; + +use crate::MongoDb; +use crate::PolicyChange; +use crate::User; + +use super::AbstractPolicyChange; + +static COL: &str = "policy_changes"; + +#[async_trait] +impl AbstractPolicyChange for MongoDb { + /// Fetch all policy changes + async fn fetch_policy_changes(&self) -> Result> { + query!(self, find, COL, doc! {}) + } + + /// Acknowledge policy changes + async fn acknowledge_policy_changes(&self, user_id: &str) -> Result<()> { + let latest_policy = self + .fetch_policy_changes() + .await? + .into_iter() + .map(|policy| policy.created_time) + .max() + .unwrap_or(Timestamp::UNIX_EPOCH); + + self.col::("users") + .update_one( + doc! { + "_id": user_id + }, + doc! { + "$set": { + "last_acknowledged_policy_change": to_bson(&latest_policy) + .map_err(|_| create_database_error!("to_bson", "timestamp"))? + } + }, + ) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("update_one", COL)) + } +} diff --git a/crates/core/database/src/models/policy_changes/ops/reference.rs b/crates/core/database/src/models/policy_changes/ops/reference.rs new file mode 100644 index 00000000..e9745e44 --- /dev/null +++ b/crates/core/database/src/models/policy_changes/ops/reference.rs @@ -0,0 +1,31 @@ +use iso8601_timestamp::Timestamp; +use revolt_result::Result; + +use crate::PolicyChange; +use crate::ReferenceDb; + +use super::AbstractPolicyChange; + +#[async_trait] +impl AbstractPolicyChange for ReferenceDb { + /// Fetch all policy changes + async fn fetch_policy_changes(&self) -> Result> { + let policy_changes = self.policy_changes.lock().await; + Ok(policy_changes.values().cloned().collect()) + } + + /// Acknowledge policy changes + async fn acknowledge_policy_changes(&self, user_id: &str) -> Result<()> { + let mut users = self.users.lock().await; + let user = users.get_mut(user_id).expect("user doesn't exist"); + user.last_acknowledged_policy_change = self + .fetch_policy_changes() + .await? + .into_iter() + .map(|policy| policy.created_time) + .max() + .unwrap_or(Timestamp::UNIX_EPOCH); + + Ok(()) + } +} diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index fc2866cf..0c2b6cee 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -57,6 +57,8 @@ auto_derived_partial!( /// Time until user is unsuspended #[serde(skip_serializing_if = "Option::is_none")] pub suspended_until: Option, + /// Last acknowledged policy change + pub last_acknowledged_policy_change: Timestamp, }, "PartialUser" ); @@ -178,6 +180,7 @@ impl Default for User { privileged: Default::default(), bot: Default::default(), suspended_until: Default::default(), + last_acknowledged_policy_change: Timestamp::UNIX_EPOCH, } } } @@ -200,6 +203,7 @@ impl User { id: account_id.into().unwrap_or_else(|| Ulid::new().to_string()), discriminator: User::find_discriminator(db, &username, None).await?, username, + last_acknowledged_policy_change: Timestamp::now_utc(), ..Default::default() }; diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 12f7c8fc..f741144b 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -1,3 +1,4 @@ +use iso8601_timestamp::Timestamp; use revolt_models::v0::*; use revolt_permissions::{calculate_user_permissions, UserPermission}; @@ -597,6 +598,17 @@ impl From for crate::Masquerade { } } +impl From for PolicyChange { + fn from(value: crate::PolicyChange) -> Self { + PolicyChange { + created_time: value.created_time, + effective_time: value.effective_time, + description: value.description, + url: value.url, + } + } +} + impl From for Report { fn from(value: crate::Report) -> Self { Report { @@ -1188,6 +1200,7 @@ impl From for crate::User { privileged: value.privileged, bot: value.bot.map(Into::into), suspended_until: None, + last_acknowledged_policy_change: Timestamp::UNIX_EPOCH, } } } diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 29cf897d..4dfadeed 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.6" +version = "0.8.7" 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.6", path = "../config", features = [ +revolt-config = { version = "0.8.7", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.6", path = "../result" } +revolt-result = { version = "0.8.7", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 691d37a5..6c9dcf80 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.6", path = "../config" } -revolt-permissions = { version = "0.8.6", path = "../permissions" } +revolt-config = { version = "0.8.7", path = "../config" } +revolt-permissions = { version = "0.8.7", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/models/src/v0/mod.rs b/crates/core/models/src/v0/mod.rs index 78540e32..0468493b 100644 --- a/crates/core/models/src/v0/mod.rs +++ b/crates/core/models/src/v0/mod.rs @@ -7,6 +7,7 @@ mod embeds; mod emojis; mod files; mod messages; +mod policy_changes; mod safety_reports; mod server_bans; mod server_members; @@ -23,6 +24,7 @@ pub use embeds::*; pub use emojis::*; pub use files::*; pub use messages::*; +pub use policy_changes::*; pub use safety_reports::*; pub use server_bans::*; pub use server_members::*; diff --git a/crates/core/models/src/v0/policy_changes.rs b/crates/core/models/src/v0/policy_changes.rs new file mode 100644 index 00000000..267618de --- /dev/null +++ b/crates/core/models/src/v0/policy_changes.rs @@ -0,0 +1,16 @@ +use iso8601_timestamp::Timestamp; + +auto_derived!( + /// Platform policy change + pub struct PolicyChange { + /// Time at which this policy was created + pub created_time: Timestamp, + /// Time at which this policy is effective + pub effective_time: Timestamp, + + /// Message shown to users + pub description: String, + /// URL with details about changes + pub url: String, + } +); diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 558997bf..3c0a15b5 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" description = "Revolt Backend: Message Parser" diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 886ed973..c4eb7262 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.6" +version = "0.8.7" 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.6", path = "../result" } +revolt-result = { version = "0.8.7", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 5e101db0..7ecb776a 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.6" +version = "0.8.7" 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 cd314fb5..a0de339d 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 4c89f8bf..413a810e 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.8.6" +version = "0.8.7" 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.8.6", path = "../../core/database" } -revolt-result = { version = "0.8.6", path = "../../core/result" } -revolt-config = { version = "0.8.6", path = "../../core/config" } -revolt-files = { version = "0.8.6", path = "../../core/files" } +revolt-database = { version = "0.8.7", path = "../../core/database" } +revolt-result = { version = "0.8.7", path = "../../core/result" } +revolt-config = { version = "0.8.7", path = "../../core/config" } +revolt-files = { version = "0.8.7", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 6696b213..7800c4fd 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,19 +1,19 @@ [package] name = "revolt-pushd" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-result = { version = "0.8.6", path = "../../core/result" } -revolt-config = { version = "0.8.6", path = "../../core/config", features = [ +revolt-result = { version = "0.8.7", path = "../../core/result" } +revolt-config = { version = "0.8.7", path = "../../core/config", features = [ "report-macros", ] } -revolt-database = { version = "0.8.6", path = "../../core/database" } -revolt-models = { version = "0.8.6", path = "../../core/models", features = [ +revolt-database = { version = "0.8.7", path = "../../core/database" } +revolt-models = { version = "0.8.7", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.8.6", path = "../../core/presence", features = [ +revolt-presence = { version = "0.8.7", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 4b79c107..5401223f 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.6" +version = "0.8.7" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 25ed460d..9643a365 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -9,6 +9,7 @@ mod channels; mod customisation; mod invites; mod onboard; +mod policy; mod push; mod root; mod safety; @@ -36,6 +37,7 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { "/auth/session" => rocket_authifier::routes::session::routes(), "/auth/mfa" => rocket_authifier::routes::mfa::routes(), "/onboard" => onboard::routes(), + "/policy" => policy::routes(), "/push" => push::routes(), "/sync" => sync::routes(), "/webhooks" => webhooks::routes() @@ -56,6 +58,7 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { "/auth/session" => rocket_authifier::routes::session::routes(), "/auth/mfa" => rocket_authifier::routes::mfa::routes(), "/onboard" => onboard::routes(), + "/policy" => policy::routes(), "/push" => push::routes(), "/sync" => sync::routes() }; diff --git a/crates/delta/src/routes/policy/acknowledge_policy_changes.rs b/crates/delta/src/routes/policy/acknowledge_policy_changes.rs new file mode 100644 index 00000000..062dc32c --- /dev/null +++ b/crates/delta/src/routes/policy/acknowledge_policy_changes.rs @@ -0,0 +1,17 @@ +use revolt_database::{events::client::EventV1, Database, Report, Snapshot, SnapshotContent, User}; +use revolt_models::v0::{ReportStatus, ReportedContent}; +use revolt_result::{create_error, Result}; +use serde::Deserialize; +use ulid::Ulid; +use validator::Validate; + +use rocket::{serde::json::Json, State}; + +/// # Acknowledge Policy Changes +/// +/// Accept/acknowledge changes to platform policy. +#[openapi(tag = "Policy")] +#[post("/acknowledge")] +pub async fn acknowledge_policy_changes(db: &State, user: User) -> Result<()> { + db.acknowledge_policy_changes(&user.id).await +} diff --git a/crates/delta/src/routes/policy/mod.rs b/crates/delta/src/routes/policy/mod.rs new file mode 100644 index 00000000..77831b1f --- /dev/null +++ b/crates/delta/src/routes/policy/mod.rs @@ -0,0 +1,11 @@ +use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi; +use rocket::Route; + +mod acknowledge_policy_changes; + +pub fn routes() -> (Vec, OpenApi) { + openapi_get_routes_spec![ + // Policy + acknowledge_policy_changes::acknowledge_policy_changes, + ] +} diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index eea5a707..36446c01 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,12 +43,12 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.6", path = "../../core/files" } -revolt-config = { version = "0.8.6", path = "../../core/config" } -revolt-database = { version = "0.8.6", path = "../../core/database", features = [ +revolt-files = { version = "0.8.7", path = "../../core/files" } +revolt-config = { version = "0.8.7", path = "../../core/config" } +revolt-database = { version = "0.8.7", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.6", path = "../../core/result", features = [ +revolt-result = { version = "0.8.7", path = "../../core/result", features = [ "utoipa", "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index fedfae97..3566d2a0 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.6", path = "../../core/config" } -revolt-models = { version = "0.8.6", path = "../../core/models" } -revolt-result = { version = "0.8.6", path = "../../core/result", features = [ +revolt-config = { version = "0.8.7", path = "../../core/config" } +revolt-models = { version = "0.8.7", path = "../../core/models" } +revolt-result = { version = "0.8.7", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.6", path = "../../core/files" } +revolt-files = { version = "0.8.7", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" }