diff --git a/.docker/Dockerfile.rhel b/.docker/Dockerfile.rhel index 993ac5499afaf..201fbbe5c398d 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.10.3 +ENV RC_VERSION 3.10.4 MAINTAINER buildmaster@rocket.chat diff --git a/.github/history.json b/.github/history.json index 3cecdc3b52df2..a1bca12ba1e2e 100644 --- a/.github/history.json +++ b/.github/history.json @@ -53923,6 +53923,37 @@ ] } ] + }, + "3.10.4": { + "node_version": "12.18.4", + "npm_version": "6.14.8", + "apps_engine_version": "1.21.0-alpha.4235", + "mongo_versions": [ + "3.4", + "3.6", + "4.0" + ], + "pull_requests": [ + { + "pr": "20200", + "title": "Chore: Change console.warning() to console.warn()", + "userLogin": "lucassartor", + "milestone": "3.10.4", + "contributors": [ + "lucassartor" + ] + }, + { + "pr": "20176", + "title": "[FIX] Room's list showing all rooms with same name", + "userLogin": "sampaiodiego", + "description": "Add a migration to fix the room's list for those who ran version 3.10.1 and got it scrambled when a new user was registered.", + "milestone": "3.10.4", + "contributors": [ + "sampaiodiego" + ] + } + ] } } } \ No newline at end of file diff --git a/.snapcraft/resources/prepareRocketChat b/.snapcraft/resources/prepareRocketChat index 4be1d8d0837cb..b0b2c9852d4c3 100755 --- a/.snapcraft/resources/prepareRocketChat +++ b/.snapcraft/resources/prepareRocketChat @@ -1,6 +1,6 @@ #!/bin/bash -curl -SLf "https://releases.rocket.chat/3.10.3/download/" -o rocket.chat.tgz +curl -SLf "https://releases.rocket.chat/3.10.4/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 eba4d603428f0..d4115985fe60f 100644 --- a/.snapcraft/snap/snapcraft.yaml +++ b/.snapcraft/snap/snapcraft.yaml @@ -7,7 +7,7 @@ # 5. `snapcraft snap` name: rocketchat-server -version: 3.10.3 +version: 3.10.4 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 367a50951d98c..84b3b049cb00f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,33 @@ +# 3.10.4 +`2021-01-14 ยท 1 ๐Ÿ› ยท 1 ๐Ÿ” ยท 2 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` + +### Engine versions +- Node: `12.18.4` +- NPM: `6.14.8` +- MongoDB: `3.4, 3.6, 4.0` +- Apps-Engine: `1.21.0-alpha.4235` + +### ๐Ÿ› Bug fixes + + +- Room's list showing all rooms with same name ([#20176](https://github.com/RocketChat/Rocket.Chat/pull/20176)) + + Add a migration to fix the room's list for those who ran version 3.10.1 and got it scrambled when a new user was registered. + +
+๐Ÿ” Minor changes + + +- Chore: Change console.warning() to console.warn() ([#20200](https://github.com/RocketChat/Rocket.Chat/pull/20200)) + +
+ +### ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป Core Team ๐Ÿค“ + +- [@lucassartor](https://github.com/lucassartor) +- [@sampaiodiego](https://github.com/sampaiodiego) + # 3.10.3 `2021-01-09 ยท 1 ๐Ÿ› ยท 1 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` @@ -160,8 +189,8 @@ - Hightlights validation on Account Preferences page ([#19902](https://github.com/RocketChat/Rocket.Chat/pull/19902) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) - This PR fixes two issues in the account settings "preferences" panel. - Once set, the "Highlighted Words" setting cannot be reset to an empty string. This was fixed by changing the string validation from checking the length to checking the type of variable. + This PR fixes two issues in the account settings "preferences" panel. + Once set, the "Highlighted Words" setting cannot be reset to an empty string. This was fixed by changing the string validation from checking the length to checking the type of variable. Secondly, it tracks the changes to correctly identify if changes after the last "save changes" action have been made, using an "updates" state variable, instead of just comparing against the initialValue that does not change on clicking "save changes". - Image preview for image URLs on messages ([#19734](https://github.com/RocketChat/Rocket.Chat/pull/19734)) @@ -220,10 +249,14 @@ - Chore: Update Pull Request template ([#19768](https://github.com/RocketChat/Rocket.Chat/pull/19768)) - Improve the template of Pull Requests in order to make it clear reducing duplicated information and removing the visible checklists that were generating noise and misunderstanding with the PR progress. - - Moved the checklists to inside comments - - Merge the changelog and proposed changes sections to have a single source of description that goes to the changelog - - Remove the screenshot section, they can be added inside the description + Improve the template of Pull Requests in order to make it clear reducing duplicated information and removing the visible checklists that were generating noise and misunderstanding with the PR progress. + + - Moved the checklists to inside comments + + - Merge the changelog and proposed changes sections to have a single source of description that goes to the changelog + + - Remove the screenshot section, they can be added inside the description + - Changed the proposed changes title to incentivizing the usage of images and videos - Frontend folder structure ([#19631](https://github.com/RocketChat/Rocket.Chat/pull/19631)) @@ -258,11 +291,11 @@ - Regression: Double Scrollbars on tables ([#19980](https://github.com/RocketChat/Rocket.Chat/pull/19980)) - Before: - ![image](https://user-images.githubusercontent.com/40830821/103242719-0ec84680-4936-11eb-87a7-68b6eea8de7b.png) - - - After: + Before: + ![image](https://user-images.githubusercontent.com/40830821/103242719-0ec84680-4936-11eb-87a7-68b6eea8de7b.png) + + + After: ![image](https://user-images.githubusercontent.com/40830821/103242680-ee988780-4935-11eb-99e2-a95de99f78f1.png) - Regression: Failed autolinker and markdown rendering ([#19831](https://github.com/RocketChat/Rocket.Chat/pull/19831)) @@ -281,7 +314,7 @@ - Regression: Omnichannel Custom Fields Form no longer working after refactoring ([#19948](https://github.com/RocketChat/Rocket.Chat/pull/19948)) - The Omnichannel `Custom Fields` form is not working anymore after some refactorings on client-side. + The Omnichannel `Custom Fields` form is not working anymore after some refactorings on client-side. When the user clicks on `Custom Field` in the Omnichannel menu, a blank page appears. - Regression: polishing licenses endpoints ([#19981](https://github.com/RocketChat/Rocket.Chat/pull/19981)) @@ -474,8 +507,8 @@ - Bundle Size Client ([#19533](https://github.com/RocketChat/Rocket.Chat/pull/19533)) - temporarily removes some codeblock languages - Moved some libraries to dynamic imports + temporarily removes some codeblock languages + Moved some libraries to dynamic imports Removed some shared code not used on the client side - Forward Omnichannel room to agent in another department ([#19576](https://github.com/RocketChat/Rocket.Chat/pull/19576) by [@mrfigueiredo](https://github.com/mrfigueiredo)) @@ -1553,8 +1586,10 @@ - **2FA:** Password enforcement setting and 2FA protection when saving settings or resetting E2E encryption ([#18640](https://github.com/RocketChat/Rocket.Chat/pull/18640)) - - Increase the 2FA remembering time from 5min to 30min - - Add new setting to enforce 2FA password fallback (enabled only for new installations) + - Increase the 2FA remembering time from 5min to 30min + + - Add new setting to enforce 2FA password fallback (enabled only for new installations) + - Require 2FA to save settings and reset E2E Encryption keys - **Omnichannel:** Allow set other agent status via method `livechat:changeLivechatStatus ` ([#18571](https://github.com/RocketChat/Rocket.Chat/pull/18571)) @@ -1572,7 +1607,7 @@ - 2FA by Email setting showing for the user even when disabled by the admin ([#18473](https://github.com/RocketChat/Rocket.Chat/pull/18473)) - The option to disable/enable the **Two-factor authentication via Email** at `Account > Security > Two Factor Authentication + The option to disable/enable the **Two-factor authentication via Email** at `Account > Security > Two Factor Authentication ` was visible even when the setting **Enable Two Factor Authentication via Email** at `Admin > Accounts > Two Factor Authentication` was disabled leading to misbehavior since the functionality was disabled. - Agents enabledDepartment attribute not set on collection ([#18614](https://github.com/RocketChat/Rocket.Chat/pull/18614) by [@paulobernardoaf](https://github.com/paulobernardoaf)) @@ -1922,13 +1957,16 @@ - Mention autocomplete UI and performance improvements ([#18309](https://github.com/RocketChat/Rocket.Chat/pull/18309)) - * New setting to configure the number of suggestions `Admin > Layout > User Interface > Number of users' autocomplete suggestions` (default 5) - * The UI shows whenever the user is not a member of the room - * The UI shows when the suggestion came from the last messages for quick selection/reply - * The suggestions follow this order: - * The user with the exact username and member of the room - * The user with the exact username but not a member of the room (if allowed to list non-members) - * The users containing the text in username, name or nickname and member of the room + * New setting to configure the number of suggestions `Admin > Layout > User Interface > Number of users' autocomplete suggestions` (default 5) + + * The UI shows whenever the user is not a member of the room + + * The UI shows when the suggestion came from the last messages for quick selection/reply + + * The suggestions follow this order: + * The user with the exact username and member of the room + * The user with the exact username but not a member of the room (if allowed to list non-members) + * The users containing the text in username, name or nickname and member of the room * The users containing the text in username, name or nickname and not a member of the room (if allowed to list non-members) - Message action styles ([#18190](https://github.com/RocketChat/Rocket.Chat/pull/18190)) @@ -2270,10 +2308,10 @@ - Split NOTIFICATIONS_SCHEDULE_DELAY into three separate variables ([#17669](https://github.com/RocketChat/Rocket.Chat/pull/17669) by [@jazztickets](https://github.com/jazztickets)) - Email notification delay can now be customized with the following environment variables: - NOTIFICATIONS_SCHEDULE_DELAY_ONLINE - NOTIFICATIONS_SCHEDULE_DELAY_AWAY - NOTIFICATIONS_SCHEDULE_DELAY_OFFLINE + Email notification delay can now be customized with the following environment variables: + NOTIFICATIONS_SCHEDULE_DELAY_ONLINE + NOTIFICATIONS_SCHEDULE_DELAY_AWAY + NOTIFICATIONS_SCHEDULE_DELAY_OFFLINE Setting the value to -1 disable notifications for that type. - Threads ([#17416](https://github.com/RocketChat/Rocket.Chat/pull/17416)) @@ -2673,11 +2711,11 @@ - **ENTERPRISE:** Omnichannel Last-Chatted Agent Preferred option ([#17666](https://github.com/RocketChat/Rocket.Chat/pull/17666)) - If activated, this feature will store the last agent that assisted each Omnichannel visitor when a conversation is taken. So, when a visitor returns(it works with any entry point, Livechat, Facebook, REST API, and so on) and starts a new chat, the routing system checks: - - 1 - The visitor object for any stored agent that the visitor has previously talked to; - 2 - If a previous agent is not found, the system will try to find a previous conversation of the same visitor. If a room is found, the system will get the previous agent from the room; - + If activated, this feature will store the last agent that assisted each Omnichannel visitor when a conversation is taken. So, when a visitor returns(it works with any entry point, Livechat, Facebook, REST API, and so on) and starts a new chat, the routing system checks: + + 1 - The visitor object for any stored agent that the visitor has previously talked to; + 2 - If a previous agent is not found, the system will try to find a previous conversation of the same visitor. If a room is found, the system will get the previous agent from the room; + After this process, if an agent has been found, the system will check the agent's availability to assist the new chat. If it's not available, then the routing system will get the next available agent in the queue. - **ENTERPRISE:** Support for custom Livechat registration form fields ([#17581](https://github.com/RocketChat/Rocket.Chat/pull/17581)) @@ -2782,9 +2820,12 @@ - Notification sounds ([#17616](https://github.com/RocketChat/Rocket.Chat/pull/17616)) - * Global CDN config was ignored when loading the sound files - * Upload of custom sounds wasn't getting the file extension correctly - * Some translations were missing + * Global CDN config was ignored when loading the sound files + + * Upload of custom sounds wasn't getting the file extension correctly + + * Some translations were missing + * Edit and delete of custom sounds were not working correctly - Omnichannel departments are not saved when the offline channel name is not defined ([#17553](https://github.com/RocketChat/Rocket.Chat/pull/17553)) @@ -3072,14 +3113,19 @@ - Better Push and Email Notification logic ([#17357](https://github.com/RocketChat/Rocket.Chat/pull/17357)) - We are still using the same logic to define which notifications every new message will generate, it takes some servers' settings, users's preferences and subscriptions' settings in consideration to determine who will receive each notification type (desktop, audio, email and mobile push), but now it doesn't check the user's status (online, away, offline) for email and mobile push notifications but send those notifications to a new queue with the following rules: - - - When the user is online the notification is scheduled to be sent in 120 seconds - - When the user is away the notification is scheduled to be sent in 120 seconds minus the amount of time he is away - - When the user is offline the notification is scheduled to be sent right away - - When the user reads a channel all the notifications for that user are removed (clear queue) - - When a notification is processed to be sent to a user and there are other scheduled notifications: - - All the scheduled notifications for that user are rescheduled to now + We are still using the same logic to define which notifications every new message will generate, it takes some servers' settings, users's preferences and subscriptions' settings in consideration to determine who will receive each notification type (desktop, audio, email and mobile push), but now it doesn't check the user's status (online, away, offline) for email and mobile push notifications but send those notifications to a new queue with the following rules: + + + - When the user is online the notification is scheduled to be sent in 120 seconds + + - When the user is away the notification is scheduled to be sent in 120 seconds minus the amount of time he is away + + - When the user is offline the notification is scheduled to be sent right away + + - When the user reads a channel all the notifications for that user are removed (clear queue) + + - When a notification is processed to be sent to a user and there are other scheduled notifications: + - All the scheduled notifications for that user are rescheduled to now - The current notification goes back to the queue to be processed ordered by creation date - Buttons to check/uncheck all users and channels on import ([#17207](https://github.com/RocketChat/Rocket.Chat/pull/17207)) @@ -3442,7 +3488,7 @@ - Translation via MS translate ([#16363](https://github.com/RocketChat/Rocket.Chat/pull/16363) by [@mrsimpson](https://github.com/mrsimpson)) - Adds Microsoft's translation service (https://translator.microsoft.com/) as a provider for translation of messages. + Adds Microsoft's translation service (https://translator.microsoft.com/) as a provider for translation of messages. In addition to implementing the interface (similar to google and DeepL), a small change has been done in order to display the translation provider on the UI. - Two Factor authentication via email ([#15949](https://github.com/RocketChat/Rocket.Chat/pull/15949)) @@ -14981,4 +15027,4 @@ - [@graywolf336](https://github.com/graywolf336) - [@marceloschmidt](https://github.com/marceloschmidt) - [@rodrigok](https://github.com/rodrigok) -- [@sampaiodiego](https://github.com/sampaiodiego) \ No newline at end of file +- [@sampaiodiego](https://github.com/sampaiodiego) diff --git a/app/utils/rocketchat.info b/app/utils/rocketchat.info index 2a0ac456ddb0e..eb00952d9a0db 100644 --- a/app/utils/rocketchat.info +++ b/app/utils/rocketchat.info @@ -1,3 +1,3 @@ { - "version": "3.10.3" + "version": "3.10.4" } diff --git a/ee/app/auditing/server/methods.js b/ee/app/auditing/server/methods.js index fb781ce340f89..4055bca3cb141 100644 --- a/ee/app/auditing/server/methods.js +++ b/ee/app/auditing/server/methods.js @@ -26,7 +26,7 @@ const getRoomInfoByAuditParams = ({ type, roomId, users, visitor, agent }) => { } if (type === 'l') { - console.warning('Deprecation Warning! This method will be removed in the next version (4.0.0)'); + console.warn('Deprecation Warning! This method will be removed in the next version (4.0.0)'); const rooms = LivechatRooms.findByVisitorIdAndAgentId(visitor, agent, { fields: { _id: 1 } }).fetch(); return rooms && rooms.length && { rids: rooms.map(({ _id }) => _id), name: TAPi18n.__('Omnichannel') }; } diff --git a/package-lock.json b/package-lock.json index 819759e9ee95b..d00f03e02d5b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "Rocket.Chat", - "version": "3.10.3", + "version": "3.10.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 14c1a594170fe..bc7c704e3fcbb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Rocket.Chat", "description": "The Ultimate Open Source WebChat Platform", - "version": "3.10.3", + "version": "3.10.4", "author": { "name": "Rocket.Chat", "url": "https://rocket.chat/" diff --git a/server/startup/migrations/index.js b/server/startup/migrations/index.js index 9e53f75c3b96f..307fd414164c5 100644 --- a/server/startup/migrations/index.js +++ b/server/startup/migrations/index.js @@ -209,4 +209,5 @@ import './v209'; import './v210'; import './v211'; import './v212'; +import './v213'; import './xrun'; diff --git a/server/startup/migrations/v213.js b/server/startup/migrations/v213.js new file mode 100644 index 0000000000000..7752f0d047cd0 --- /dev/null +++ b/server/startup/migrations/v213.js @@ -0,0 +1,89 @@ +import { Migrations } from '../../../app/migrations'; +import { Subscriptions, Rooms } from '../../../app/models/server/raw'; + +const updateSubscriptions = async () => { + const cursor = Subscriptions.find({ t: 'd' }, { projection: { rid: 1, u: 1 } }); + + let actions = []; + for await (const sub of cursor) { + const room = await Rooms.findOne({ _id: sub.rid }, { projection: { usernames: 1 } }); + if (!room) { + console.log(`[migration] room record not found: ${ sub.rid }`); + continue; + } + + if (!room.usernames || room.usernames.length === 0) { + console.log(`[migration] room without usernames: ${ sub.rid }`); + continue; + } + + const name = room.usernames + .filter((u) => u !== sub.u.username) + .sort() + .join(', ') || sub.u.username; + if (!name) { + console.log(`[migration] subscription without name ${ sub._id }`); + continue; + } + + actions.push({ + updateMany: { + filter: { _id: sub._id }, + update: { $set: { name, _updatedAt: new Date() } }, + }, + }); + if (actions.length === 1000) { + await Subscriptions.col.bulkWrite(actions, { ordered: false }); + actions = []; + } + } + if (actions.length) { + await Subscriptions.col.bulkWrite(actions, { ordered: false }); + } +}; + +Migrations.add({ + version: 213, + up() { + Promise.await((async () => { + const options = { + projection: { rid: 1, u: 1, name: 1 }, + }; + const cursor = Subscriptions.find({ t: 'd' }, options).sort({ _updatedAt: 1 }).limit(100); + const total = await cursor.count(); + + // if number of subscription is low, we can go ahead and fix them all + if (total < 1000) { + return updateSubscriptions(); + } + + // otherwise we'll first see if they're broken + const subs = await cursor.toArray(); + const subsTotal = subs.length; + + const subsWithRoom = await Promise.all(subs.map(async (sub) => ({ + sub, + room: await Rooms.findOne({ _id: sub.rid }, { projection: { usernames: 1 } }), + }))); + + const wrongSubs = subsWithRoom + .filter(({ room }) => room && room.usernames && room.usernames.length > 0) + .filter(({ room, sub }) => { + const name = room.usernames + .filter((u) => u !== sub.u.username) + .sort() + .join(', ') || sub.u.username; + + return name !== sub.name; + }).length; + + + // if less then 5% of subscriptions are wrong, we're fine, doesn't need to do anything + if (wrongSubs / subsTotal < 0.05) { + return; + } + + return updateSubscriptions(); + })()); + }, +});