From b6b27b66c83c322a9887b7b207788f7e4b2c348f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20K=C3=B6sters?= <timo@koesters.xyz>
Date: Wed, 23 Mar 2022 11:05:41 +0100
Subject: [PATCH] fix: don't allow unjoined users to send typing notifications

---
 src/client_server/typing.rs | 11 +++++++++--
 src/server_server.rs        | 26 +++++++++++++++-----------
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/client_server/typing.rs b/src/client_server/typing.rs
index 60fc1cc4..413c5400 100644
--- a/src/client_server/typing.rs
+++ b/src/client_server/typing.rs
@@ -1,5 +1,5 @@
-use crate::{database::DatabaseGuard, utils, Result, Ruma};
-use ruma::api::client::typing::create_typing_event;
+use crate::{database::DatabaseGuard, Error, utils, Result, Ruma};
+use ruma::api::client::{typing::create_typing_event, error::ErrorKind};
 
 /// # `PUT /_matrix/client/r0/rooms/{roomId}/typing/{userId}`
 ///
@@ -12,6 +12,13 @@ pub async fn create_typing_event_route(
 
     let sender_user = body.sender_user.as_ref().expect("user is authenticated");
 
+    if !db.rooms.is_joined(sender_user, &body.room_id)? {
+        return Err(Error::BadRequest(
+            ErrorKind::Forbidden,
+            "You are not in this room.",
+        ));
+    }
+
     if let Typing::Yes(duration) = body.state {
         db.rooms.edus.typing_add(
             sender_user,
diff --git a/src/server_server.rs b/src/server_server.rs
index e95c4c0f..67ad3691 100644
--- a/src/server_server.rs
+++ b/src/server_server.rs
@@ -770,17 +770,21 @@ pub async fn send_transaction_message_route(
                 }
             }
             Edu::Typing(typing) => {
-                if typing.typing {
-                    db.rooms.edus.typing_add(
-                        &typing.user_id,
-                        &typing.room_id,
-                        3000 + utils::millis_since_unix_epoch(),
-                        &db.globals,
-                    )?;
-                } else {
-                    db.rooms
-                        .edus
-                        .typing_remove(&typing.user_id, &typing.room_id, &db.globals)?;
+                if db.rooms.is_joined(&typing.user_id, &typing.room_id)? {
+                    if typing.typing {
+                        db.rooms.edus.typing_add(
+                            &typing.user_id,
+                            &typing.room_id,
+                            3000 + utils::millis_since_unix_epoch(),
+                            &db.globals,
+                        )?;
+                    } else {
+                        db.rooms.edus.typing_remove(
+                            &typing.user_id,
+                            &typing.room_id,
+                            &db.globals,
+                        )?;
+                    }
                 }
             }
             Edu::DeviceListUpdate(DeviceListUpdateContent { user_id, .. }) => {