diff --git a/src/database/entities/autumn.rs b/src/database/entities/autumn.rs
index a0ae82f9ed58f24515afe5a193d443c7cf4a940a..10eb7c10a4bb47f16a7ce9a135183f6f9aca2034 100644
--- a/src/database/entities/autumn.rs
+++ b/src/database/entities/autumn.rs
@@ -19,6 +19,9 @@ pub struct File {
     metadata: Metadata,
     content_type: String,
     size: isize,
+    
+    #[serde(skip_serializing_if = "Option::is_none")]
+    deleted: Option<bool>,
 
     #[serde(skip_serializing_if = "Option::is_none")]
     message_id: Option<String>,
diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs
index 13346164c2e152618c0b831906e607276a977bfc..dce0672d0f44b6012d833a75904db0aabba11745 100644
--- a/src/database/entities/channel.rs
+++ b/src/database/entities/channel.rs
@@ -1,9 +1,10 @@
 use crate::database::*;
 use crate::notifications::events::ClientboundNotification;
 use crate::util::result::{Error, Result};
-use mongodb::bson::{doc, from_document, to_document};
+use mongodb::{bson::{Document, doc, from_document, to_document}, options::FindOptions};
 use rocket_contrib::json::JsonValue;
 use serde::{Deserialize, Serialize};
+use futures::StreamExt;
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
 pub struct LastMessage {
@@ -107,7 +108,56 @@ impl Channel {
 
     pub async fn delete(&self) -> Result<()> {
         let id = self.id();
-        get_collection("messages")
+        let messages = get_collection("messages");
+
+        // Check if there are any attachments we need to delete.
+        let message_ids = messages
+            .find(
+                doc! {
+                    "channel": id,
+                    "attachment": {
+                        "$exists": 1
+                    }
+                },
+                FindOptions::builder().projection(doc! { "_id": 1 }).build(),
+            )
+            .await
+            .map_err(|_| Error::DatabaseError {
+                operation: "fetch_many",
+                with: "messages",
+            })?
+            .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>>();
+        
+        // If we found any, mark them as deleted.
+        if message_ids.len() > 0 {
+            get_collection("attachments")
+                .update_many(
+                    doc! {
+                        "message_id": {
+                            "$in": message_ids
+                        }
+                    },
+                    doc! {
+                        "$set": {
+                            "deleted": true
+                        }
+                    },
+                    None
+                )
+                .await
+                .map_err(|_| Error::DatabaseError {
+                    operation: "update_many",
+                    with: "attachments",
+                })?;
+        }
+
+        // And then delete said messages.
+        messages
             .delete_many(
                 doc! {
                     "channel": id
diff --git a/src/database/entities/message.rs b/src/database/entities/message.rs
index b506ccc3f0b2e2742adb92068c1567fe6c0d512a..0ef9f01fb9d97225599c777410288376483113a1 100644
--- a/src/database/entities/message.rs
+++ b/src/database/entities/message.rs
@@ -276,6 +276,26 @@ impl Message {
         .await
         .ok();
 
+        if let Some(attachment) = &self.attachment {
+            get_collection("attachments")
+                .update_one(
+                    doc! {
+                        "_id": &attachment.id
+                    },
+                    doc! {
+                        "$set": {
+                            "deleted": true
+                        }
+                    },
+                    None
+                )
+                .await
+                .map_err(|_| Error::DatabaseError {
+                    operation: "update_one",
+                    with: "attachment",
+                })?;
+        }
+
         Ok(())
     }
 }
diff --git a/src/routes/users/edit_user.rs b/src/routes/users/edit_user.rs
index b1c1ef98e5c96637bc9677c89c464fbb9cd6ee0b..ab5e1f6e71c8f1c40eedecde2a521f013c1c6df4 100644
--- a/src/routes/users/edit_user.rs
+++ b/src/routes/users/edit_user.rs
@@ -10,8 +10,10 @@ use validator::Validate;
 #[derive(Validate, Serialize, Deserialize)]
 pub struct Data {
     #[serde(skip_serializing_if = "Option::is_none")]
+    #[validate]
     status: Option<UserStatus>,
     #[serde(skip_serializing_if = "Option::is_none")]
+    #[validate]
     profile: Option<UserProfile>,
 }
 
@@ -29,13 +31,15 @@ pub async fn req(user: User, data: Json<Data>, _ignore_id: String) -> Result<()>
     .await
     .map_err(|_| Error::DatabaseError { operation: "update_one", with: "user" })?;
 
-    ClientboundNotification::UserUpdate {
-        id: user.id.clone(),
-        data: json!(data.0),
+    if let Some(status) = data.0.status {
+        ClientboundNotification::UserUpdate {
+            id: user.id.clone(),
+            data: json!({ "status": status }),
+        }
+        .publish(user.id.clone())
+        .await
+        .ok();
     }
-    .publish(user.id.clone())
-    .await
-    .ok();
 
     Ok(())
 }