diff --git a/README.md b/README.md index d8e54334..8eb9ce18 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,12 @@ - Host protection to prevent unauthorized access. - User auth to prevent unauthorized access. - Room password protection. +- Room lobby, central gathering space. +- Room spam mitigations, focused on preventing spam. - Compatible with desktop and mobile devices. - Optimized mobile room URL sharing. - Webcam streaming with front and rear camera support for mobile devices. +- Broadcasting, distribution of audio or video content to a wide audience. - Crystal-clear audio streaming with speaking detection and volume indicators. - Screen sharing for presentations. - File sharing with drag-and-drop support. diff --git a/app/src/Server.js b/app/src/Server.js index 775a037e..f4fbe47b 100644 --- a/app/src/Server.js +++ b/app/src/Server.js @@ -40,7 +40,7 @@ dependencies: { * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.58 + * @version 1.3.59 * */ @@ -725,6 +725,10 @@ function startServer() { room.setHostOnlyRecording(false); room.broadCast(socket.id, 'roomAction', data.action); break; + case 'isBanned': + log.info('The user has been banned from the room due to spamming messages', data); + room.addBannedPeer(data.peer_uuid); + break; default: break; } diff --git a/package.json b/package.json index e321ff57..91944feb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalksfu", - "version": "1.3.58", + "version": "1.3.59", "description": "WebRTC SFU browser-based video calls", "main": "Server.js", "scripts": { diff --git a/public/js/Room.js b/public/js/Room.js index 657d5362..c1ade4c6 100644 --- a/public/js/Room.js +++ b/public/js/Room.js @@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.58 + * @version 1.3.59 * */ diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index 330adc54..523fb88d 100644 --- a/public/js/RoomClient.js +++ b/public/js/RoomClient.js @@ -9,7 +9,7 @@ * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.3.58 + * @version 1.3.59 * */ @@ -188,6 +188,14 @@ class RoomClient { chat_cant_chatgpt: false, }; + // Chat messages + this.chatMessageLength = 1000; // chars + this.chatMessageTimeLast = 0; + this.chatMessageTimeBetween = 1000; // ms + this.chatMessageNotifyDelay = 10000; // ms + this.chatMessageSpamCount = 0; + this.chatMessageSpamCountToBan = 1; + this.isAudioAllowed = isAudioAllowed; this.isVideoAllowed = isVideoAllowed; this.isScreenAllowed = isScreenAllowed; @@ -3362,6 +3370,41 @@ class RoomClient { isChatPasteTxt = false; return this.userLog('info', 'No participants in the room', 'top-end'); } + + // Prevent long messages + if (chatMessage.value.length > this.chatMessageLength) { + return this.userLog( + 'warning', + 'The message seems too long, with a maximum of 1000 characters allowed', + 'top-end', + ); + } + + // Spamming detected ban the user from the room + if (this.chatMessageSpamCount == this.chatMessageSpamCountToBan) { + return this.roomAction('isBanned', true); + } + + // Prevent Spam messages + const currentTime = Date.now(); + if (chatMessage.value && currentTime - this.chatMessageTimeLast <= this.chatMessageTimeBetween) { + this.cleanMessage(); + chatMessage.readOnly = true; + chatSendButton.disabled = true; + setTimeout(function () { + chatMessage.readOnly = false; + chatSendButton.disabled = false; + }, this.chatMessageNotifyDelay); + this.chatMessageSpamCount++; + return this.userLog( + 'warning', + `Kindly refrain from spamming. Please wait ${this.chatMessageNotifyDelay / 1000} seconds before sending another message`, + 'top-end', + this.chatMessageNotifyDelay, + ); + } + this.chatMessageTimeLast = currentTime; + chatMessage.value = filterXSS(chatMessage.value.trim()); const peer_msg = this.formatMsg(chatMessage.value); if (!peer_msg) { @@ -4809,6 +4852,10 @@ class RoomClient { this.socket.emit('roomAction', data); if (popup) this.roomStatus(action); break; + case 'isBanned': + this.socket.emit('roomAction', data); + this.isBanned(); + break; default: break; }