diff --git a/.docker/Dockerfile.rhel b/.docker/Dockerfile.rhel index 73acb90606ec8..3f0e7a809ebe3 100644 --- a/.docker/Dockerfile.rhel +++ b/.docker/Dockerfile.rhel @@ -1,6 +1,6 @@ FROM registry.access.redhat.com/ubi8/nodejs-12 -ENV RC_VERSION 3.14.4 +ENV RC_VERSION 3.14.5 MAINTAINER buildmaster@rocket.chat diff --git a/.github/history.json b/.github/history.json index d2fcacc1491ce..7c65cd1dde9cf 100644 --- a/.github/history.json +++ b/.github/history.json @@ -59696,6 +59696,80 @@ ] } ] + }, + "3.12.7": { + "node_version": "12.18.4", + "npm_version": "6.14.8", + "apps_engine_version": "1.23.0", + "mongo_versions": [ + "3.4", + "3.6", + "4.0" + ], + "pull_requests": [ + { + "pr": "22172", + "title": "[FIX] Discussion names showing a random value", + "userLogin": "sampaiodiego", + "milestone": "3.14.4", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "3.13.5": { + "node_version": "12.21.0", + "npm_version": "6.14.8", + "apps_engine_version": "1.24.1", + "mongo_versions": [ + "3.4", + "3.6", + "4.0" + ], + "pull_requests": [ + { + "pr": "22172", + "title": "[FIX] Discussion names showing a random value", + "userLogin": "sampaiodiego", + "milestone": "3.14.4", + "contributors": [ + "sampaiodiego" + ] + } + ] + }, + "3.14.5": { + "node_version": "12.22.1", + "npm_version": "6.14.1", + "apps_engine_version": "1.25.0", + "mongo_versions": [ + "3.4", + "3.6", + "4.0" + ], + "pull_requests": [ + { + "pr": "22258", + "title": "[IMPROVE] Send only relevant data via WebSocket", + "userLogin": "sampaiodiego", + "description": "Previously when any data changed on subscriptions or rooms we were getting fresh data from database, to also remove undesired fields, but sometimes the data that changed was not relevant so we were sending the whole object everytime **without** the fields that actually changed. This change aims to reduce this overhead and also send less data to clients.", + "milestone": "3.14.5", + "contributors": [ + "sampaiodiego", + "web-flow" + ] + }, + { + "pr": "22257", + "title": "[FIX] Support DISABLE_PRESENCE_MONITOR env var in new DB watchers", + "userLogin": "sampaiodiego", + "milestone": "3.14.5", + "contributors": [ + "sampaiodiego" + ] + } + ] } } } \ No newline at end of file diff --git a/.snapcraft/resources/prepareRocketChat b/.snapcraft/resources/prepareRocketChat index 9364c21fec675..e264230b5c161 100755 --- a/.snapcraft/resources/prepareRocketChat +++ b/.snapcraft/resources/prepareRocketChat @@ -1,6 +1,6 @@ #!/bin/bash -curl -SLf "https://releases.rocket.chat/3.14.4/download/" -o rocket.chat.tgz +curl -SLf "https://releases.rocket.chat/3.14.5/download/" -o rocket.chat.tgz tar xf rocket.chat.tgz --strip 1 diff --git a/.snapcraft/snap/snapcraft.yaml b/.snapcraft/snap/snapcraft.yaml index 9062d5259740f..5437ff59d8e76 100644 --- a/.snapcraft/snap/snapcraft.yaml +++ b/.snapcraft/snap/snapcraft.yaml @@ -7,7 +7,7 @@ # 5. `snapcraft snap` name: rocketchat-server -version: 3.14.4 +version: 3.14.5 summary: Rocket.Chat server description: Have your own Slack like online chat, built with Meteor. https://rocket.chat/ confinement: strict diff --git a/HISTORY.md b/HISTORY.md index 44ca58f5a5fa6..765c7c913ff70 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,31 @@ +# 3.14.5 +`2021-06-06 ยท 1 ๐Ÿš€ ยท 1 ๐Ÿ› ยท 1 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` + +### Engine versions +- Node: `12.22.1` +- NPM: `6.14.1` +- MongoDB: `3.4, 3.6, 4.0` +- Apps-Engine: `1.25.0` + +### ๐Ÿš€ Improvements + + +- Send only relevant data via WebSocket ([#22258](https://github.com/RocketChat/Rocket.Chat/pull/22258)) + + Previously when any data changed on subscriptions or rooms we were getting fresh data from database, to also remove undesired fields, but sometimes the data that changed was not relevant so we were sending the whole object everytime **without** the fields that actually changed. This change aims to reduce this overhead and also send less data to clients. + +### ๐Ÿ› Bug fixes + + +- Support DISABLE_PRESENCE_MONITOR env var in new DB watchers ([#22257](https://github.com/RocketChat/Rocket.Chat/pull/22257)) + +### ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป Core Team ๐Ÿค“ + +- [@sampaiodiego](https://github.com/sampaiodiego) + # 3.14.4 -`2021-05-27 ยท 2 ๐Ÿ› ยท 2 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` +`2021-05-28 ยท 2 ๐Ÿ› ยท 2 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` ### Engine versions - Node: `12.22.1` @@ -589,6 +614,24 @@ - [@thassiov](https://github.com/thassiov) - [@tiagoevanp](https://github.com/tiagoevanp) +# 3.13.5 +`2021-05-27 ยท 1 ๐Ÿ› ยท 1 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` + +### Engine versions +- Node: `12.21.0` +- NPM: `6.14.8` +- MongoDB: `3.4, 3.6, 4.0` +- Apps-Engine: `1.24.1` + +### ๐Ÿ› Bug fixes + + +- Discussion names showing a random value ([#22172](https://github.com/RocketChat/Rocket.Chat/pull/22172)) + +### ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป Core Team ๐Ÿค“ + +- [@sampaiodiego](https://github.com/sampaiodiego) + # 3.13.3 `2021-04-20 ยท 2 ๐Ÿ› ยท 3 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` @@ -1279,6 +1322,24 @@ - [@tassoevan](https://github.com/tassoevan) - [@tiagoevanp](https://github.com/tiagoevanp) +# 3.12.7 +`2021-05-27 ยท 1 ๐Ÿ› ยท 1 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` + +### Engine versions +- Node: `12.18.4` +- NPM: `6.14.8` +- MongoDB: `3.4, 3.6, 4.0` +- Apps-Engine: `1.23.0` + +### ๐Ÿ› Bug fixes + + +- Discussion names showing a random value ([#22172](https://github.com/RocketChat/Rocket.Chat/pull/22172)) + +### ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป Core Team ๐Ÿค“ + +- [@sampaiodiego](https://github.com/sampaiodiego) + # 3.12.5 `2021-04-20 ยท 1 ๐Ÿ› ยท 1 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` diff --git a/app/models/server/models/LivechatVisitors.js b/app/models/server/models/LivechatVisitors.js index 3c1848020f474..8ff645f15ec82 100644 --- a/app/models/server/models/LivechatVisitors.js +++ b/app/models/server/models/LivechatVisitors.js @@ -6,6 +6,9 @@ import { Base } from './_Base'; import Settings from './Settings'; import { escapeRegExp } from '../../../../lib/escapeRegExp'; +const settingsRaw = Settings.model.rawCollection(); +const findAndModify = Meteor.wrapAsync(settingsRaw.findAndModify, settingsRaw); + export class LivechatVisitors extends Base { constructor() { super('livechat_visitor'); @@ -124,9 +127,6 @@ export class LivechatVisitors extends Base { * @return {string} The next visitor name */ getNextVisitorUsername() { - const settingsRaw = Settings.model.rawCollection(); - const findAndModify = Meteor.wrapAsync(settingsRaw.findAndModify, settingsRaw); - const query = { _id: 'Livechat_guest_count', }; diff --git a/app/utils/rocketchat.info b/app/utils/rocketchat.info index 386c2c6f8c548..4c2155cafe6ec 100644 --- a/app/utils/rocketchat.info +++ b/app/utils/rocketchat.info @@ -1,3 +1,3 @@ { - "version": "3.14.4" + "version": "3.14.5" } diff --git a/client/views/room/Header/Omnichannel/QuickActions/QuickActions.tsx b/client/views/room/Header/Omnichannel/QuickActions/QuickActions.tsx index a083cb96bebb9..06b3013f00fc3 100644 --- a/client/views/room/Header/Omnichannel/QuickActions/QuickActions.tsx +++ b/client/views/room/Header/Omnichannel/QuickActions/QuickActions.tsx @@ -69,7 +69,7 @@ const QuickActions: FC = ({ room, className }) => { useEffect(() => { getVisitorEmail(); - }, [room, getVisitorEmail]); + }, [visitorRoomId, getVisitorEmail]); const closeModal = useCallback(() => setModal(null), [setModal]); diff --git a/package-lock.json b/package-lock.json index 11a214d163b9c..16a0b157d829d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "Rocket.Chat", - "version": "3.14.4", + "version": "3.14.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 58dfd53d0934e..5b4039e21f9df 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Rocket.Chat", "description": "The Ultimate Open Source WebChat Platform", - "version": "3.14.4", + "version": "3.14.5", "author": { "name": "Rocket.Chat", "url": "https://rocket.chat/" diff --git a/server/modules/watchers/watchers.module.ts b/server/modules/watchers/watchers.module.ts index a6f856a4413d0..0a5c9fbb7aff5 100644 --- a/server/modules/watchers/watchers.module.ts +++ b/server/modules/watchers/watchers.module.ts @@ -66,6 +66,24 @@ type Watcher = (model: IBaseRaw, fn: (event: IChange) type BroadcastCallback = (event: T, ...args: Parameters) => Promise; +const hasKeys = (requiredKeys: string[]): (data?: Record) => boolean => + (data?: Record): boolean => { + if (!data) { + return false; + } + + return Object.keys(data) + .filter((key) => key !== '_id') + .map((key) => key.split('.')[0]) + .some((key) => requiredKeys.includes(key)); + }; + +const hasRoomFields = hasKeys(Object.keys(roomFields)); +const hasSubscriptionFields = hasKeys(Object.keys(subscriptionFields)); + +const startMonitor = typeof process.env.DISABLE_PRESENCE_MONITOR === 'undefined' + || !['true', 'yes'].includes(String(process.env.DISABLE_PRESENCE_MONITOR).toLowerCase()); + export function initWatchers(models: IModelsParam, broadcast: BroadcastCallback, watch: Watcher): void { const { Messages, @@ -122,10 +140,14 @@ export function initWatchers(models: IModelsParam, broadcast: BroadcastCallback, } }); - watch(Subscriptions, async ({ clientAction, id }) => { + watch(Subscriptions, async ({ clientAction, id, data, diff }) => { switch (clientAction) { case 'inserted': case 'updated': { + if (!hasSubscriptionFields(data || diff)) { + return; + } + // Override data cuz we do not publish all fields const subscription = await Subscriptions.findOneById(id, { projection: subscriptionFields }); if (!subscription) { @@ -164,22 +186,24 @@ export function initWatchers(models: IModelsParam, broadcast: BroadcastCallback, }); }); - watch(UsersSessions, async ({ clientAction, id, data }) => { - switch (clientAction) { - case 'inserted': - case 'updated': - data = data ?? await UsersSessions.findOneById(id); - if (!data) { - return; - } + if (startMonitor) { + watch(UsersSessions, async ({ clientAction, id, data }) => { + switch (clientAction) { + case 'inserted': + case 'updated': + data = data ?? await UsersSessions.findOneById(id); + if (!data) { + return; + } - broadcast('watch.userSessions', { clientAction, userSession: data }); - break; - case 'removed': - broadcast('watch.userSessions', { clientAction, userSession: { _id: id } }); - break; - } - }); + broadcast('watch.userSessions', { clientAction, userSession: data }); + break; + case 'removed': + broadcast('watch.userSessions', { clientAction, userSession: { _id: id } }); + break; + } + }); + } watch(LivechatInquiry, async ({ clientAction, id, data, diff }) => { switch (clientAction) { @@ -278,12 +302,16 @@ export function initWatchers(models: IModelsParam, broadcast: BroadcastCallback, broadcast('watch.settings', { clientAction, setting }); }); - watch(Rooms, async ({ clientAction, id, data }) => { + watch(Rooms, async ({ clientAction, id, data, diff }) => { if (clientAction === 'removed') { broadcast('watch.rooms', { clientAction, room: { _id: id } }); return; } + if (!hasRoomFields(data || diff)) { + return; + } + const room = data ?? await Rooms.findOneById(id, { projection: roomFields }); if (!room) { return;