From d107f777146903d88c44722319bf80e97a1b3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ram=C3=B3n=20Souza?= <contato@ramonsouza.com>
Date: Fri, 9 Apr 2021 11:16:49 -0300
Subject: [PATCH] Prevent users from sending private messages to offline user
 (#11906)

* lock offline user private messages

* removing reassignment of props
---
 .../imports/ui/components/chat/component.jsx  |  8 ++++-
 .../imports/ui/components/chat/container.jsx  | 31 +++++++++++++++++--
 .../chat/message-form/component.jsx           |  5 +--
 .../chat/time-window-list/component.jsx       |  4 +--
 4 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/bigbluebutton-html5/imports/ui/components/chat/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/component.jsx
index 4746fc9481..cde4f0d48f 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/component.jsx
@@ -50,6 +50,7 @@ const Chat = (props) => {
     syncedPercent,
     lastTimeWindowValuesBuild,
   } = props;
+
   const HIDE_CHAT_AK = shortcuts.hidePrivateChat;
   const CLOSE_CHAT_AK = shortcuts.closePrivateChat;
   ChatLogger.debug('ChatComponent::render', props);
@@ -96,7 +97,12 @@ const Chat = (props) => {
                 accessKey={CLOSE_CHAT_AK}
               />
             )
-            : <ChatDropdownContainer {...{ meetingIsBreakout, isMeteorConnected, amIModerator, timeWindowsValues }} />
+            : (
+              <ChatDropdownContainer {...{
+                meetingIsBreakout, isMeteorConnected, amIModerator, timeWindowsValues,
+              }}
+              />
+            )
         }
       </header>
       <TimeWindowList
diff --git a/bigbluebutton-html5/imports/ui/components/chat/container.jsx b/bigbluebutton-html5/imports/ui/components/chat/container.jsx
index 3b743fe052..5fcad9215a 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/container.jsx
@@ -53,6 +53,7 @@ const intlMessages = defineMessages({
 
 let previousChatId = null;
 let prevSync = false;
+let prevPartnerIsLoggedOut = false;
 
 let globalAppplyStateToProps = () => { }
 
@@ -124,6 +125,13 @@ const ChatContainer = (props) => {
   const chatName = participants?.filter((user) => user.id !== Auth.userID)[0]?.name;
   const title = chatName ? intl.formatMessage(intlMessages.titlePrivate, { 0: chatName}) : intl.formatMessage(intlMessages.titlePublic);
 
+  let partnerIsLoggedOut = false;
+
+  if(!isPublicChat){
+    const idUser = participants?.filter((user) => user.id !== Auth.userID)[0]?.id;
+    partnerIsLoggedOut = (users[idUser]?.loggedOut || users[idUser]?.ejected) ? true : false;
+  }
+
   if (unmounting === true) {
     return null;
   }
@@ -140,8 +148,11 @@ const ChatContainer = (props) => {
       (lastMsg?.lastTimestamp !== stateLastMsg?.lastTimestamp)
       || (previousChatId !== chatID)
       || (prevSync !== contextChat?.syncing)
+      || (prevPartnerIsLoggedOut !== partnerIsLoggedOut)
       ) {
       prevSync = contextChat?.syncing;
+      prevPartnerIsLoggedOut = partnerIsLoggedOut;
+
       const timeWindowsValues = isPublicChat
         ? [
           ...(
@@ -166,6 +177,23 @@ const ChatContainer = (props) => {
         previousChatId = chatID;
       }
 
+      if (partnerIsLoggedOut) {
+        const time = Date.now();
+        const id = `partner-disconnected-${time}`;
+        const messagePartnerLoggedOut = {
+          id,
+          content: [{
+            id,
+            text: intl.formatMessage(intlMessages.partnerDisconnected, { 0: chatName}),
+            time,
+          }],
+          time,
+          sender: null,
+        };
+
+        timeWindowsValues.push(messagePartnerLoggedOut);
+      }
+
       setLastMsg(lastMsg ? { ...lastMsg } : lastMsg);
       setTimeWindows(timeWindowsValues);
       setLastTimeWindowValuesBuild(Date.now());
@@ -192,6 +220,7 @@ const ChatContainer = (props) => {
       syncedPercent: contextChat?.syncedPercent,
       chatName,
       lastTimeWindowValuesBuild,
+      partnerIsLoggedOut
     }}>
       {children}
     </Chat>
@@ -201,7 +230,6 @@ const ChatContainer = (props) => {
 export default lockContextContainer(injectIntl(withTracker(({ intl, userLocks }) => {
   const chatID = Session.get('idChatOpen');
   const isChatLocked = userLocks.userPrivateChat || userLocks.userPublicChat;
-  let partnerIsLoggedOut = false;
 
   if (!chatID) {
     // No chatID is set so the panel is closed, about to close, or wasn't opened correctly
@@ -215,7 +243,6 @@ export default lockContextContainer(injectIntl(withTracker(({ intl, userLocks })
   return {
     chatID,
     intl,
-    partnerIsLoggedOut,
     isChatLocked,
     isMeteorConnected,
     meetingIsBreakout: meetingIsBreakout(),
diff --git a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
index 165e167490..61825a3d77 100755
--- a/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/message-form/component.jsx
@@ -267,6 +267,7 @@ class MessageForm extends PureComponent {
       title,
       disabled,
       className,
+      partnerIsLoggedOut,
     } = this.props;
 
     const { hasErrors, error, message } = this.state;
@@ -288,7 +289,7 @@ class MessageForm extends PureComponent {
             autoCorrect="off"
             autoComplete="off"
             spellCheck="true"
-            disabled={disabled}
+            disabled={disabled || partnerIsLoggedOut}
             value={message}
             onChange={this.handleMessageChange}
             onKeyDown={this.handleMessageKeyDown}
@@ -300,7 +301,7 @@ class MessageForm extends PureComponent {
             className={styles.sendButton}
             aria-label={intl.formatMessage(messages.submitLabel)}
             type="submit"
-            disabled={disabled}
+            disabled={disabled || partnerIsLoggedOut}
             label={intl.formatMessage(messages.submitLabel)}
             color="primary"
             icon="send"
diff --git a/bigbluebutton-html5/imports/ui/components/chat/time-window-list/component.jsx b/bigbluebutton-html5/imports/ui/components/chat/time-window-list/component.jsx
index 623f320a27..1be88312a7 100644
--- a/bigbluebutton-html5/imports/ui/components/chat/time-window-list/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/chat/time-window-list/component.jsx
@@ -49,8 +49,8 @@ class TimeWindowList extends PureComponent {
         const { timeWindowsValues } = this.props;
         const timewindow = timeWindowsValues[rowIndex];
 
-        const key = timewindow.key;
-        const contentCount = timewindow.content.length;
+        const key = timewindow?.key;
+        const contentCount = timewindow?.content?.length;
         return `${key}-${contentCount}`;
       },
     });
-- 
GitLab