From 5f883a51f1cc427407beb75c5354080e6738745f Mon Sep 17 00:00:00 2001 From: Miroslav Pejic Date: Thu, 19 Mar 2026 09:09:23 +0100 Subject: [PATCH] [mirotalk] - #331: fix peer count inflation when room password is set --- .env.template | 2 +- app/src/api.js | 6 ++++-- app/src/config.template.js | 2 +- app/src/server.js | 32 ++++++++++++++------------------ package-lock.json | 4 ++-- package.json | 2 +- public/js/brand.js | 2 +- public/js/client.js | 4 ++-- 8 files changed, 26 insertions(+), 28 deletions(-) diff --git a/.env.template b/.env.template index 43c808d6..538af7f3 100644 --- a/.env.template +++ b/.env.template @@ -1,5 +1,5 @@ # ==================================================== -# MiroTalk P2P v.1.7.55 - Environment Configuration +# MiroTalk P2P v.1.7.56 - Environment Configuration # ==================================================== # App environment diff --git a/app/src/api.js b/app/src/api.js index a76f7275..0f3e4b4f 100644 --- a/app/src/api.js +++ b/app/src/api.js @@ -21,12 +21,13 @@ module.exports = class ServerApi { } getStats(peers, timestamp = new Date().toISOString()) { + const metaKeys = new Set(['lock', 'password']); let totalRooms = 0; let totalPeers = 0; for (const room_id in peers) { totalRooms++; // Increment room count - totalPeers += Object.keys(peers[room_id]).length; // Count the number of peers in the room + totalPeers += Object.keys(peers[room_id]).filter((k) => !metaKeys.has(k)).length; } return { @@ -37,9 +38,10 @@ module.exports = class ServerApi { } getActiveRooms(roomList) { + const metaKeys = new Set(['lock', 'password']); return Object.entries(roomList).map(([roomId, room]) => ({ id: roomId, - peers: room && typeof room === 'object' ? Object.keys(room).length : 0, + peers: room && typeof room === 'object' ? Object.keys(room).filter((k) => !metaKeys.has(k)).length : 0, join: this.getProtocol() + this._host + '/' + roomId, })); } diff --git a/app/src/config.template.js b/app/src/config.template.js index 7e7fdd3d..007ba5b4 100644 --- a/app/src/config.template.js +++ b/app/src/config.template.js @@ -2,7 +2,7 @@ /** * ============================================== - * MiroTalk P2P v.1.7.55 - Configuration File + * MiroTalk P2P v.1.7.56 - Configuration File * ============================================== * * This file is the central configuration source. diff --git a/app/src/server.js b/app/src/server.js index b6bd7bca..b31a9737 100755 --- a/app/src/server.js +++ b/app/src/server.js @@ -45,7 +45,7 @@ dependencies: { * @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.7.55 + * @version 1.7.56 * */ @@ -379,6 +379,13 @@ const sockets = {}; // collect sockets const peers = {}; // collect peers info grp by channels const presenters = {}; // collect presenters grp by channels +const roomMetaKeys = new Set(['lock', 'password']); + +function getPeerCount(roomId) { + if (!peers[roomId]) return 0; + return Object.keys(peers[roomId]).filter((k) => !roomMetaKeys.has(k)).length; +} + app.set('trust proxy', trustProxy); // Enables trust for proxy headers (e.g., X-Forwarded-For) based on the trustProxy setting app.use(helmet.noSniff()); // Enable content type sniffing prevention @@ -1442,7 +1449,7 @@ io.sockets.on('connect', async (socket) => { channels[channel][socket.id] = socket; socket.channels[channel] = channel; - const peerCounts = Object.keys(peers[channel]).length; + const peerCounts = getPeerCount(channel); // Send some server info to joined peer await sendToPeer(socket.id, sockets, 'serverInfo', { @@ -1996,21 +2003,10 @@ io.sockets.on('connect', async (socket) => { delete channels[channel][socket.id]; delete peers[channel][socket.id]; // delete peer data from the room - switch (Object.keys(peers[channel]).length) { - case 0: // last peer disconnected from the room without room lock & password set - delete peers[channel]; - delete presenters[channel]; - delete channels[channel]; // Clean up channels to prevent memory leak - break; - case 2: // last peer disconnected from the room having room lock & password set - if (peers[channel]['lock'] && peers[channel]['password']) { - delete peers[channel]; // clean lock and password value from the room - delete presenters[channel]; // clean the presenter from the channel - delete channels[channel]; // Clean up channels to prevent memory leak - } - break; - default: - break; + if (getPeerCount(channel) === 0) { + delete peers[channel]; + delete presenters[channel]; + delete channels[channel]; // Clean up channels to prevent memory leak } } catch (err) { log.error('Remove Peer', toJson(err)); @@ -2245,7 +2241,7 @@ function getActiveRooms() { for (const roomId in peers) { if (peers.hasOwnProperty(roomId)) { // Get the count of peers in the current room - const peersCount = Object.keys(peers[roomId]).length; + const peersCount = getPeerCount(roomId); roomPeersArray.push({ roomId: roomId, peersCount: peersCount, diff --git a/package-lock.json b/package-lock.json index 714ae145..e6ac555b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mirotalk", - "version": "1.7.55", + "version": "1.7.56", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mirotalk", - "version": "1.7.55", + "version": "1.7.56", "license": "AGPL-3.0", "dependencies": { "@mattermost/client": "11.4.0", diff --git a/package.json b/package.json index af0af004..b62bbcea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalk", - "version": "1.7.55", + "version": "1.7.56", "description": "A free WebRTC browser-based video call", "main": "server.js", "scripts": { diff --git a/public/js/brand.js b/public/js/brand.js index f0026f70..7e94193c 100644 --- a/public/js/brand.js +++ b/public/js/brand.js @@ -107,7 +107,7 @@ let brand = { }, about: { imageUrl: '../images/mirotalk-logo.gif', - title: 'WebRTC P2P v1.7.55', + title: 'WebRTC P2P v1.7.56', html: `