From 0f18a6781ded8559923b51b27c7dbbfb965718f6 Mon Sep 17 00:00:00 2001
From: Paul <paulmakles@gmail.com>
Date: Fri, 11 Jun 2021 16:22:35 +0100
Subject: [PATCH] Channels: Include last message id on text channels. API:
 Return members when fetching messages. Misc: Remove defunct
 DISABLE_REGISTRATION variable.

---
 src/database/entities/channel.rs     |  2 ++
 src/database/entities/message.rs     | 21 ++++++++++++++++++++-
 src/database/entities/server.rs      | 26 ++++++++++++++++++++++++--
 src/routes/channels/message_query.rs | 17 +++++++++++++----
 src/routes/root.rs                   |  3 +--
 src/routes/servers/channel_create.rs |  1 +
 src/routes/servers/server_create.rs  |  1 +
 src/util/variables.rs                |  1 -
 8 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs
index b0a6ced..6cef965 100644
--- a/src/database/entities/channel.rs
+++ b/src/database/entities/channel.rs
@@ -63,6 +63,8 @@ pub enum Channel {
         description: Option<String>,
         #[serde(skip_serializing_if = "Option::is_none")]
         icon: Option<File>,
+        #[serde(skip_serializing_if = "Option::is_none")]
+        last_message: Option<String>,
     },
 }
 
diff --git a/src/database/entities/message.rs b/src/database/entities/message.rs
index a5b6eb9..3609110 100644
--- a/src/database/entities/message.rs
+++ b/src/database/entities/message.rs
@@ -90,7 +90,7 @@ impl Message {
                 "last_message": {
                     "_id": self.id.clone(),
                     "author": self.author.clone(),
-                    "short": text.chars().take(24).collect::<String>()
+                    "short": text.chars().take(128).collect::<String>()
                 }
             }
         } else {
@@ -133,6 +133,25 @@ impl Message {
                         })?;
                 }
             }
+            Channel::TextChannel { id, .. } => {
+                if let Content::Text(_) = &self.content {
+                    channels
+                        .update_one(
+                            doc! { "_id": id },
+                            doc! {
+                                "$set": {
+                                    "last_message": &self.id
+                                }
+                            },
+                            None,
+                        )
+                        .await
+                        .map_err(|_| Error::DatabaseError {
+                            operation: "update_one",
+                            with: "channel",
+                        })?;
+                }
+            }
             _ => {}
         }
 
diff --git a/src/database/entities/server.rs b/src/database/entities/server.rs
index 13337ef..5f4eaf0 100644
--- a/src/database/entities/server.rs
+++ b/src/database/entities/server.rs
@@ -3,6 +3,7 @@ use crate::notifications::events::ClientboundNotification;
 use crate::util::result::{Error, Result};
 use futures::StreamExt;
 use mongodb::bson::doc;
+use mongodb::bson::from_document;
 use mongodb::bson::to_document;
 use mongodb::bson::Document;
 use mongodb::options::FindOptions;
@@ -148,7 +149,7 @@ impl Server {
             })?;
 
         // Delete all channels, members, bans and invites.
-        for with in ["channels", "invites"] {
+        for with in &["channels", "invites"] {
             get_collection(with)
                 .delete_many(
                     doc! {
@@ -163,7 +164,7 @@ impl Server {
                 })?;
         }
 
-        for with in ["server_members", "server_bans"] {
+        for with in &["server_members", "server_bans"] {
             get_collection(with)
                 .delete_many(
                     doc! {
@@ -207,6 +208,27 @@ impl Server {
         Ok(())
     }
 
+    pub async fn fetch_members(id: &str) -> Result<Vec<Member>> {
+        Ok(get_collection("server_members")
+            .find(
+                doc! {
+                    "_id.server": id
+                },
+                None,
+            )
+            .await
+            .map_err(|_| Error::DatabaseError {
+                operation: "find",
+                with: "server_members",
+            })?
+            .filter_map(async move |s| s.ok())
+            .collect::<Vec<Document>>()
+            .await
+            .into_iter()
+            .filter_map(|x| from_document(x).ok())
+            .collect::<Vec<Member>>())
+    }
+
     pub async fn fetch_member_ids(id: &str) -> Result<Vec<String>> {
         Ok(get_collection("server_members")
             .find(
diff --git a/src/routes/channels/message_query.rs b/src/routes/channels/message_query.rs
index b4bd407..e1d67b8 100644
--- a/src/routes/channels/message_query.rs
+++ b/src/routes/channels/message_query.rs
@@ -98,11 +98,20 @@ pub async fn req(user: User, target: Ref, options: Form<Options>) -> Result<Json
 
         ids.remove(&user.id);
         let user_ids = ids.into_iter().collect();
+        let users = user.fetch_multiple_users(user_ids).await?;
 
-        Ok(json!({
-            "messages": messages,
-            "users": user.fetch_multiple_users(user_ids).await?
-        }))
+        if let Channel::TextChannel { server, .. } = target {
+            Ok(json!({
+                "messages": messages,
+                "users": users,
+                "members": Server::fetch_members(&server).await?
+            }))
+        } else {
+            Ok(json!({
+                "messages": messages,
+                "users": users,
+            }))
+        }
     } else {
         Ok(json!(messages))
     }
diff --git a/src/routes/root.rs b/src/routes/root.rs
index c1f4008..8256477 100644
--- a/src/routes/root.rs
+++ b/src/routes/root.rs
@@ -1,5 +1,5 @@
 use crate::util::variables::{
-    APP_URL, AUTUMN_URL, DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, INVITE_ONLY,
+    APP_URL, AUTUMN_URL, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, INVITE_ONLY,
     JANUARY_URL, USE_AUTUMN, USE_EMAIL, USE_HCAPTCHA, USE_JANUARY, USE_VOSO, VAPID_PUBLIC_KEY,
     VOSO_URL, VOSO_WS_HOST,
 };
@@ -12,7 +12,6 @@ pub async fn root() -> JsonValue {
     json!({
         "revolt": crate::version::VERSION,
         "features": {
-            "registration": !*DISABLE_REGISTRATION,
             "captcha": {
                 "enabled": *USE_HCAPTCHA,
                 "key": HCAPTCHA_SITEKEY.to_string()
diff --git a/src/routes/servers/channel_create.rs b/src/routes/servers/channel_create.rs
index 28fb8e9..5990d15 100644
--- a/src/routes/servers/channel_create.rs
+++ b/src/routes/servers/channel_create.rs
@@ -60,6 +60,7 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<JsonValue>
         name: info.name,
         description: info.description,
         icon: None,
+        last_message: None
     };
 
     channel.clone().publish().await?;
diff --git a/src/routes/servers/server_create.rs b/src/routes/servers/server_create.rs
index 28d27c4..12cd741 100644
--- a/src/routes/servers/server_create.rs
+++ b/src/routes/servers/server_create.rs
@@ -64,6 +64,7 @@ pub async fn req(user: User, info: Json<Data>) -> Result<JsonValue> {
         name: "general".to_string(),
         description: None,
         icon: None,
+        last_message: None
     }
     .publish()
     .await?;
diff --git a/src/util/variables.rs b/src/util/variables.rs
index 9d4a136..77ac65a 100644
--- a/src/util/variables.rs
+++ b/src/util/variables.rs
@@ -37,7 +37,6 @@ lazy_static! {
         env::var("REVOLT_VAPID_PUBLIC_KEY").expect("Missing REVOLT_VAPID_PUBLIC_KEY environment variable.");
 
     // Application Flags
-    pub static ref DISABLE_REGISTRATION: bool = env::var("REVOLT_DISABLE_REGISTRATION").map_or(false, |v| v == "1");
     pub static ref INVITE_ONLY: bool = env::var("REVOLT_INVITE_ONLY").map_or(false, |v| v == "1");
     pub static ref USE_EMAIL: bool = env::var("REVOLT_USE_EMAIL_VERIFICATION").map_or(
         env::var("REVOLT_SMTP_HOST").is_ok()
-- 
GitLab