diff --git a/Cargo.lock b/Cargo.lock index 5a6fcf5686d33fa0c424f2a631b2f89845d348fe..f264925edd66bc75f88942a024458004baf74e6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2454,7 +2454,7 @@ dependencies = [ [[package]] name = "revolt" -version = "0.3.3-alpha.3" +version = "0.3.3-alpha.4" dependencies = [ "async-std", "async-tungstenite", diff --git a/Cargo.toml b/Cargo.toml index 25ced133f8b4797141d861ff9f6344afbf8eca3d..98bfdd263abb0545cc62937a80b9cb38b80e89b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt" -version = "0.3.3-alpha.3" +version = "0.3.3-alpha.4" authors = ["Paul Makles <paulmakles@gmail.com>"] edition = "2018" diff --git a/src/routes/channels/message_query_stale.rs b/src/routes/channels/message_query_stale.rs new file mode 100644 index 0000000000000000000000000000000000000000..d2ee19db597ff88333d37a1e31c74b4a7ae5d7b0 --- /dev/null +++ b/src/routes/channels/message_query_stale.rs @@ -0,0 +1,74 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use futures::StreamExt; +use mongodb::bson::{doc, from_document}; +use rocket_contrib::json::{Json, JsonValue}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct Options { + ids: Vec<String> +} + +#[post("/<target>/messages/stale", data = "<data>")] +pub async fn req(user: User, target: Ref, data: Json<Options>) -> Result<JsonValue> { + if data.ids.len() > 150 { + return Err(Error::LabelMe); + } + + let target = target.fetch_channel().await?; + + let perm = permissions::PermissionCalculator::new(&user) + .with_channel(&target) + .for_channel() + .await?; + if !perm.get_view() { + Err(Error::LabelMe)? + } + + let mut cursor = get_collection("messages") + .find( + doc! { + "_id": { + "$in": &data.ids + }, + "channel": target.id() + }, + None + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "find", + with: "messages", + })?; + + let mut updated = vec![]; + let mut found_ids = vec![]; + while let Some(result) = cursor.next().await { + if let Ok(doc) = result { + let msg = from_document::<Message>(doc) + .map_err(|_| Error::DatabaseError { + operation: "from_document", + with: "message", + })?; + + found_ids.push(msg.id.clone()); + if msg.edited.is_some() { + updated.push(msg); + } + } + } + + let mut deleted = vec![]; + for id in &data.ids { + if found_ids.iter().find(|x| *x == id).is_none() { + deleted.push(id); + } + } + + Ok(json!({ + "updated": updated, + "deleted": deleted + })) +} diff --git a/src/routes/channels/mod.rs b/src/routes/channels/mod.rs index ccc138988c4db8ca24426c6ea94532e2bd33d0ba..b8f37fe9f27140d71006abd8da7ba123aafe9ed1 100644 --- a/src/routes/channels/mod.rs +++ b/src/routes/channels/mod.rs @@ -9,6 +9,7 @@ mod message_delete; mod message_edit; mod message_fetch; mod message_query; +mod message_query_stale; mod message_send; pub fn routes() -> Vec<Route> { @@ -17,6 +18,7 @@ pub fn routes() -> Vec<Route> { delete_channel::req, message_send::req, message_query::req, + message_query_stale::req, message_fetch::req, message_edit::req, message_delete::req, diff --git a/src/routes/root.rs b/src/routes/root.rs index 126479aadad45399c6082d64fe72488f0e8494fa..70ff4a51909c0a923c975817a32f89b555a6b199 100644 --- a/src/routes/root.rs +++ b/src/routes/root.rs @@ -8,7 +8,7 @@ use rocket_contrib::json::JsonValue; #[get("/")] pub async fn root() -> JsonValue { json!({ - "revolt": "0.3.3-alpha.2", + "revolt": "0.3.3-alpha.4", "features": { "registration": !*DISABLE_REGISTRATION, "captcha": { diff --git a/src/routes/users/find_mutual.rs b/src/routes/users/find_mutual.rs new file mode 100644 index 0000000000000000000000000000000000000000..e75c07e917d7061ca166b7ece4664062ff69249a --- /dev/null +++ b/src/routes/users/find_mutual.rs @@ -0,0 +1,41 @@ +use crate::database::*; +use crate::util::result::{Error, Result}; + +use futures::StreamExt; +use mongodb::options::FindOptions; +use mongodb::bson::{Document, doc}; +use rocket_contrib::json::JsonValue; + +#[get("/<target>/mutual")] +pub async fn req(user: User, target: Ref) -> Result<JsonValue> { + let channels = get_collection("channels") + .find( + doc! { + "$or": [ + { "type": "Group" }, + ], + "$and": [ + { "recipients": &user.id }, + { "recipients": &target.id } + ] + }, + FindOptions::builder() + .projection(doc! { "_id": 1 }) + .build() + ) + .await + .map_err(|_| Error::DatabaseError { + operation: "find", + with: "channels", + })? + .filter_map(async move |s| s.ok()) + .collect::<Vec<Document>>() + .await + .into_iter() + .filter_map(|x| x.get_str("_id").ok().map(|x| x.to_string())) + .collect::<Vec<String>>(); + + Ok(json!({ + "channels": channels + })) +} diff --git a/src/routes/users/mod.rs b/src/routes/users/mod.rs index 2a0cd2f3c5362a3895546d4b9f7ad7a621dd8350..163978fdb0deba56f0cfa2fb552405501f88a61b 100644 --- a/src/routes/users/mod.rs +++ b/src/routes/users/mod.rs @@ -6,6 +6,7 @@ mod fetch_dms; mod fetch_relationship; mod fetch_relationships; mod fetch_user; +mod find_mutual; mod get_avatar; mod get_default_avatar; mod open_dm; @@ -22,6 +23,7 @@ pub fn routes() -> Vec<Route> { fetch_dms::req, open_dm::req, // Relationships + find_mutual::req, fetch_relationships::req, fetch_relationship::req, add_friend::req,