From 78fa896ad4d2dd095ef5cbcc98a93c1d2192e2b1 Mon Sep 17 00:00:00 2001 From: pierre-lehnen-rc <55164754+pierre-lehnen-rc@users.noreply.github.com> Date: Fri, 5 Nov 2021 11:07:57 -0300 Subject: [PATCH 01/14] [FIX] Advanced LDAP Sync Features (#23608) * [FIX] Advanced LDAP Sync Features * lint fixes * Update ee/server/settings/ldap.ts Co-authored-by: Diego Sampaio * Update ee/server/settings/ldap.ts Co-authored-by: Diego Sampaio * Removed unnecessary try..finally Co-authored-by: Diego Sampaio --- .../server/classes/ImportDataConverter.ts | 19 +++++-- ee/server/lib/ldap/Manager.ts | 53 ++++++++++++------- ee/server/settings/ldap.ts | 24 +++++++-- packages/rocketchat-i18n/i18n/en.i18n.json | 4 ++ server/lib/ldap/Connection.ts | 9 +++- 5 files changed, 82 insertions(+), 27 deletions(-) diff --git a/app/importer/server/classes/ImportDataConverter.ts b/app/importer/server/classes/ImportDataConverter.ts index 9f09a44d49bd..906ead79effc 100644 --- a/app/importer/server/classes/ImportDataConverter.ts +++ b/app/importer/server/classes/ImportDataConverter.ts @@ -219,11 +219,18 @@ export class ImportDataConverter { userData._id = _id; + if (!userData.roles && !existingUser.roles) { + userData.roles = ['user']; + } + if (!userData.type && !existingUser.type) { + userData.type = 'user'; + } + // #ToDo: #TODO: Move this to the model class const updateData: Record = { $set: { - roles: userData.roles || ['user'], - type: userData.type || 'user', + ...userData.roles && { roles: userData.roles }, + ...userData.type && { type: userData.type }, ...userData.statusText && { statusText: userData.statusText }, ...userData.bio && { bio: userData.bio }, ...userData.services?.ldap && { ldap: true }, @@ -235,7 +242,13 @@ export class ImportDataConverter { this.addUserServices(updateData, userData); this.addUserImportId(updateData, userData); this.addUserEmails(updateData, userData, existingUser.emails || []); - Users.update({ _id }, updateData); + + if (Object.keys(updateData.$set).length === 0) { + delete updateData.$set; + } + if (Object.keys(updateData).length > 0) { + Users.update({ _id }, updateData); + } if (userData.utcOffset) { Users.setUtcOffset(_id, userData.utcOffset); diff --git a/ee/server/lib/ldap/Manager.ts b/ee/server/lib/ldap/Manager.ts index 5e4c96fca602..d2f70921dd5b 100644 --- a/ee/server/lib/ldap/Manager.ts +++ b/ee/server/lib/ldap/Manager.ts @@ -36,17 +36,13 @@ export class LDAPEEManager extends LDAPManager { try { await ldap.connect(); - try { - const createNewUsers = settings.get('LDAP_Background_Sync_Import_New_Users') ?? true; - const updateExistingUsers = settings.get('LDAP_Background_Sync_Keep_Existant_Users_Updated') ?? true; + const createNewUsers = settings.get('LDAP_Background_Sync_Import_New_Users') ?? true; + const updateExistingUsers = settings.get('LDAP_Background_Sync_Keep_Existant_Users_Updated') ?? true; - if (createNewUsers) { - await this.importNewUsers(ldap, converter, updateExistingUsers); - } else if (updateExistingUsers) { - await this.updateExistingUsers(ldap, converter); - } - } finally { - ldap.disconnect(); + if (createNewUsers) { + await this.importNewUsers(ldap, converter, updateExistingUsers); + } else if (updateExistingUsers) { + await this.updateExistingUsers(ldap, converter); } converter.convertUsers({ @@ -55,6 +51,8 @@ export class LDAPEEManager extends LDAPManager { } catch (error) { logger.error(error); } + + ldap.disconnect(); } public static async syncAvatars(): Promise { @@ -116,12 +114,12 @@ export class LDAPEEManager extends LDAPManager { public static async advancedSyncForUser(ldap: LDAPConnection, user: IUser, isNewRecord: boolean, dn: string): Promise { await this.syncUserRoles(ldap, user, dn); await this.syncUserChannels(ldap, user, dn); - await this.syncUserTeams(ldap, user, isNewRecord); + await this.syncUserTeams(ldap, user, dn, isNewRecord); } private static async advancedSync(ldap: LDAPConnection, importUser: IImportUser, converter: LDAPDataConverter, isNewRecord: boolean): Promise { const user = converter.findExistingUser(importUser); - if (!user || user.username) { + if (!user?.username) { return; } @@ -140,6 +138,7 @@ export class LDAPEEManager extends LDAPManager { }; const result = await ldap.searchRaw(baseDN, searchOptions); + if (!Array.isArray(result) || result.length === 0) { logger.debug(`${ username } is not in ${ groupName } group!!!`); } else { @@ -314,7 +313,7 @@ export class LDAPEEManager extends LDAPManager { } } - private static async syncUserTeams(ldap: LDAPConnection, user: IUser, isNewRecord: boolean): Promise { + private static async syncUserTeams(ldap: LDAPConnection, user: IUser, dn: string, isNewRecord: boolean): Promise { if (!user.username) { return; } @@ -324,7 +323,7 @@ export class LDAPEEManager extends LDAPManager { return; } - const ldapUserTeams = await this.getLdapTeamsByUsername(ldap, user.username); + const ldapUserTeams = await this.getLdapTeamsByUsername(ldap, user.username, dn); const mapJson = settings.get('LDAP_Groups_To_Rocket_Chat_Teams'); if (!mapJson) { return; @@ -369,24 +368,42 @@ export class LDAPEEManager extends LDAPManager { return [...new Set(filteredTeams.map((ldapTeam) => mappedTeams[ldapTeam]).flat())]; } - private static async getLdapTeamsByUsername(ldap: LDAPConnection, username: string): Promise> { + private static async getLdapTeamsByUsername(ldap: LDAPConnection, username: string, dn: string): Promise> { + const baseDN = (settings.get('LDAP_Teams_BaseDN') ?? '').trim() || ldap.options.baseDN; const query = settings.get('LDAP_Query_To_Get_User_Teams'); if (!query) { return []; } const searchOptions = { - filter: query.replace(/#{username}/g, username), + filter: query.replace(/#{username}/g, username).replace(/#{userdn}/g, dn), scope: ldap.options.userSearchScope || 'sub', sizeLimit: ldap.options.searchSizeLimit, }; - const ldapUserGroups = await ldap.searchRaw(ldap.options.baseDN, searchOptions); + const attributeNames = (settings.get('LDAP_Teams_Name_Field') ?? '').split(',').map((attributeName) => attributeName.trim()); + if (!attributeNames.length) { + attributeNames.push('ou'); + } + + const ldapUserGroups = await ldap.searchRaw(baseDN, searchOptions); if (!Array.isArray(ldapUserGroups)) { return []; } - return ldapUserGroups.filter((entry) => entry?.raw?.ou).map((entry) => (ldap.extractLdapAttribute(entry.raw.ou) as string)).flat(); + return ldapUserGroups.map((entry) => { + if (!entry?.raw) { + return undefined; + } + + for (const attributeName of attributeNames) { + if (entry.raw[attributeName]) { + return ldap.extractLdapAttribute(entry.raw[attributeName]) as string; + } + } + + return undefined; + }).filter((entry): entry is string => Boolean(entry)).flat(); } private static isUserDeactivated(ldapUser: ILDAPEntry): boolean { diff --git a/ee/server/settings/ldap.ts b/ee/server/settings/ldap.ts index 18517bf6b620..48b11830fd69 100644 --- a/ee/server/settings/ldap.ts +++ b/ee/server/settings/ldap.ts @@ -200,20 +200,34 @@ export function addSettings(): void { enableQuery: { _id: 'LDAP_Enable', value: true }, invalidValue: false, }); + + const enableQueryTeams = { _id: 'LDAP_Enable_LDAP_Groups_To_RC_Teams', value: true }; + this.add('LDAP_Groups_To_Rocket_Chat_Teams', '{}', { type: 'code', - enableQuery: { _id: 'LDAP_Enable_LDAP_Groups_To_RC_Teams', value: true }, + enableQuery: enableQueryTeams, invalidValue: '{}', }); this.add('LDAP_Validate_Teams_For_Each_Login', false, { type: 'boolean', - enableQuery: { _id: 'LDAP_Enable_LDAP_Groups_To_RC_Teams', value: true }, + enableQuery: enableQueryTeams, invalidValue: false, }); - this.add('LDAP_Query_To_Get_User_Teams', '(&(ou=*)(uniqueMember=uid=#{username},dc=example,dc=com))', { + this.add('LDAP_Teams_BaseDN', '', { + type: 'string', + enableQuery: enableQueryTeams, + invalidValue: '', + }); + this.add('LDAP_Teams_Name_Field', 'ou,cn', { type: 'string', - enableQuery: { _id: 'LDAP_Enable_LDAP_Groups_To_RC_Teams', value: true }, - invalidValue: '(&(ou=*)(uniqueMember=uid=#{username},dc=example,dc=com))', + enableQuery: enableQueryTeams, + invalidValue: '', + }); + + this.add('LDAP_Query_To_Get_User_Teams', '(&(ou=*)(uniqueMember=#{userdn}))', { + type: 'string', + enableQuery: enableQueryTeams, + invalidValue: '', }); }); }); diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index c2e32ce53de4..8f16c2930cd6 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -2552,6 +2552,10 @@ "LDAP_Sync_User_Data_Roles_Filter_Description": "The LDAP search filter used to check if a user is in a group.", "LDAP_Sync_User_Data_RolesMap": "User Data Group Map", "LDAP_Sync_User_Data_RolesMap_Description": "Map LDAP groups to Rocket.Chat user roles
As an example, `{\"rocket-admin\":\"admin\", \"tech-support\":\"support\"}` will map the rocket-admin LDAP group to Rocket's \"admin\" role.", + "LDAP_Teams_BaseDN": "LDAP Teams BaseDN", + "LDAP_Teams_BaseDN_Description": "The LDAP BaseDN used to lookup user teams.", + "LDAP_Teams_Name_Field": "LDAP Team Name Attribute", + "LDAP_Teams_Name_Field_Description": "The LDAP attribute that Rocket.Chat should use to load the team's name. You can specify more than one possible attribute name if you separate them with a comma.", "LDAP_Timeout": "Timeout (ms)", "LDAP_Timeout_Description": "How many mileseconds wait for a search result before return an error", "LDAP_Unique_Identifier_Field": "Unique Identifier Field", diff --git a/server/lib/ldap/Connection.ts b/server/lib/ldap/Connection.ts index 1d4c9130fd22..c83b8d1393b2 100644 --- a/server/lib/ldap/Connection.ts +++ b/server/lib/ldap/Connection.ts @@ -278,7 +278,14 @@ export class LDAPConnection { Object.keys(values._raw).forEach((key) => { values[key] = this.extractLdapAttribute(values._raw[key]); - mapLogger.debug({ msg: 'Extracted Attribute', key, type: typeof values[key], value: values[key] }); + const dataType = typeof values[key]; + // eslint-disable-next-line no-control-regex + if (dataType === 'string' && values[key].length > 100 && /[\x00-\x1F]/.test(values[key])) { + mapLogger.debug({ msg: 'Extracted Attribute', key, type: dataType, length: values[key].length, value: `${ values[key].substr(0, 100) }...` }); + return; + } + + mapLogger.debug({ msg: 'Extracted Attribute', key, type: dataType, value: values[key] }); }); return values; From 65cb240247540daf8165f900a3bf38b43ae06e00 Mon Sep 17 00:00:00 2001 From: pierre-lehnen-rc <55164754+pierre-lehnen-rc@users.noreply.github.com> Date: Fri, 5 Nov 2021 11:07:37 -0300 Subject: [PATCH 02/14] [FIX] LDAP users not being re-activated on login (#23627) --- ee/server/lib/ldap/Manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/server/lib/ldap/Manager.ts b/ee/server/lib/ldap/Manager.ts index d2f70921dd5b..7230dbdb6c6d 100644 --- a/ee/server/lib/ldap/Manager.ts +++ b/ee/server/lib/ldap/Manager.ts @@ -456,7 +456,7 @@ export class LDAPEEManager extends LDAPManager { } const deleted = this.isUserDeactivated(ldapUser); - if (deleted === userData.deleted || (userData.deleted === undefined && !deleted)) { + if (deleted === userData.deleted) { return; } From 6dbd6aae66e59be476f875f1e92fc2e3d3ecad47 Mon Sep 17 00:00:00 2001 From: Duda Nogueira Date: Thu, 4 Nov 2021 09:00:47 -0300 Subject: [PATCH 03/14] [FIX] Cannot deactive a regular user if there's only one admin user admin check at setUserActiveStatus --- app/lib/server/functions/setUserActiveStatus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/server/functions/setUserActiveStatus.js b/app/lib/server/functions/setUserActiveStatus.js index 8f1207ad898c..8089fbf7d1cf 100644 --- a/app/lib/server/functions/setUserActiveStatus.js +++ b/app/lib/server/functions/setUserActiveStatus.js @@ -43,7 +43,7 @@ export function setUserActiveStatus(userId, active, confirmRelinquish = false) { // Users without username can't do anything, so there is no need to check for owned rooms if (user.username != null && !active) { - const userAdmin = Users.findOneAdmin(userId.count); + const userAdmin = Users.findOneAdmin(userId); const adminsCount = Users.findActiveUsersInRoles(['admin']).count(); if (userAdmin && adminsCount === 1) { throw new Meteor.Error('error-action-not-allowed', 'Leaving the app without an active admin is not allowed', { From 1131e0014c12a2f6a758ddc19a718f13e6ec9bbd Mon Sep 17 00:00:00 2001 From: Douglas Gubert Date: Wed, 3 Nov 2021 08:56:35 -0300 Subject: [PATCH 04/14] [FIX] App update flow failing in HA setups (#23607) * Update method call for Apps-Engine method * Update Apps-Engine --- app/apps/server/communication/websockets.js | 3 ++- package-lock.json | 6 +++--- package.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/apps/server/communication/websockets.js b/app/apps/server/communication/websockets.js index 8be3edc38e0e..dd8da2b64c89 100644 --- a/app/apps/server/communication/websockets.js +++ b/app/apps/server/communication/websockets.js @@ -71,7 +71,8 @@ export class AppServerListener { const appPackage = await this.orch.getAppSourceStorage().fetch(storageItem); - await this.orch.getManager().update(appPackage); + await this.orch.getManager().updateLocal(storageItem, appPackage); + this.clientStreamer.emitWithoutBroadcast(AppEvents.APP_UPDATED, appId); } diff --git a/package-lock.json b/package-lock.json index b4f4b752b5aa..53f2e0e0cd55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5318,9 +5318,9 @@ } }, "@rocket.chat/apps-engine": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.28.0.tgz", - "integrity": "sha512-ALrlGHVO1IhgAQ/rdZVS9nuPHwSE2VtPy3e2xbLzhMloZSpcG/ht9PPrDqIX6ZHHwiDxLbBd2/yT8vt86lXZeg==", + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.28.1.tgz", + "integrity": "sha512-Cg3/sn/vkJ0tVBOmPysTj7syHMPOMWaBwzaumEO+U9oMhDyAAYU53itnV2oUw58fNveYprRracQBLhl8U/kDCg==", "requires": { "adm-zip": "^0.4.9", "cryptiles": "^4.1.3", diff --git a/package.json b/package.json index 8c4109ab850d..c15b83db3a55 100644 --- a/package.json +++ b/package.json @@ -160,7 +160,7 @@ "@nivo/heatmap": "0.73.0", "@nivo/line": "0.62.0", "@nivo/pie": "0.73.0", - "@rocket.chat/apps-engine": "1.28.0", + "@rocket.chat/apps-engine": "^1.28.1", "@rocket.chat/css-in-js": "^0.30.1", "@rocket.chat/emitter": "^0.30.1", "@rocket.chat/fuselage": "^0.30.1", From 672fe95d7e8afbd7d306cf176f54c65dd9be0eea Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Fri, 5 Nov 2021 18:55:03 -0300 Subject: [PATCH 05/14] Bump version to 4.1.1 --- .docker/Dockerfile.rhel | 2 +- .github/history-manual.json | 7 + .github/history.json | 45 +- .snapcraft/resources/prepareRocketChat | 2 +- .snapcraft/snap/snapcraft.yaml | 2 +- HISTORY.md | 2123 +++++++++-------- app/api/server/v1/channels.js | 6 +- app/api/server/v1/chat.js | 8 +- app/api/server/v1/commands.js | 20 +- app/api/server/v1/im.js | 4 +- app/api/server/v1/rooms.js | 12 +- .../methods/getUsersOfRoomWithoutKey.js | 13 +- app/e2e/server/methods/setRoomKeyID.js | 16 +- app/lib/server/lib/processDirectEmail.js | 24 +- app/lib/server/methods/getChannelHistory.js | 10 +- app/lib/server/methods/getMessages.js | 24 +- app/lib/server/methods/getSingleMessage.js | 5 +- .../client/views/app/livechatReadOnly.js | 2 +- app/message-pin/server/pinMessage.js | 21 +- app/message-star/server/starMessage.js | 14 +- app/models/server/models/Messages.js | 11 + app/reactions/server/setReaction.js | 18 +- .../server/service/validationService.js | 44 +- app/threads/server/methods/followMessage.js | 4 +- app/threads/server/methods/unfollowMessage.js | 8 +- app/utils/rocketchat.info | 2 +- app/videobridge/server/methods/bbb.js | 31 +- .../server/api/methods/getReadReceipts.js | 6 +- package-lock.json | 2 +- package.json | 2 +- server/methods/canAccessRoom.js | 85 +- server/methods/getUsersOfRoom.js | 16 +- server/methods/loadHistory.js | 16 +- server/methods/loadMissedMessages.js | 12 +- server/methods/loadNextMessages.js | 11 +- server/methods/loadSurroundingMessages.js | 7 +- server/methods/messageSearch.js | 7 +- server/publications/messages.js | 9 +- server/publications/room/index.js | 10 +- tests/end-to-end/api/05-chat.js | 31 +- tests/end-to-end/api/24-methods.js | 3 +- 41 files changed, 1512 insertions(+), 1183 deletions(-) diff --git a/.docker/Dockerfile.rhel b/.docker/Dockerfile.rhel index 8822de22ef80..f91e8ee83d61 100644 --- a/.docker/Dockerfile.rhel +++ b/.docker/Dockerfile.rhel @@ -1,6 +1,6 @@ FROM registry.access.redhat.com/ubi8/nodejs-12 -ENV RC_VERSION 4.1.0 +ENV RC_VERSION 4.1.1 MAINTAINER buildmaster@rocket.chat diff --git a/.github/history-manual.json b/.github/history-manual.json index de60527e3d41..6258a78a3d94 100644 --- a/.github/history-manual.json +++ b/.github/history-manual.json @@ -123,5 +123,12 @@ "sampaiodiego", "pierre-lehnen-rc" ] + }], + "4.1.1": [{ + "title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)", + "userLogin": "sampaiodiego", + "contributors": [ + "sampaiodiego" + ] }] } diff --git a/.github/history.json b/.github/history.json index 890111d8e940..206a280bd24e 100644 --- a/.github/history.json +++ b/.github/history.json @@ -67032,6 +67032,49 @@ "5.0" ], "pull_requests": [] + }, + "4.1.1": { + "node_version": "12.22.1", + "npm_version": "6.14.1", + "apps_engine_version": "1.28.1", + "mongo_versions": [ + "3.6", + "4.0", + "4.2", + "4.4", + "5.0" + ], + "pull_requests": [ + { + "pr": "23607", + "title": "[FIX] App update flow failing in HA setups", + "userLogin": "d-gubert", + "description": "The flow for app updates is broken in specific scenarios with HA setups. Here we change the method calls in the Apps-Engine to avoid race conditions", + "milestone": "4.1.1", + "contributors": [ + "d-gubert" + ] + }, + { + "pr": "23627", + "title": "[FIX] LDAP users not being re-activated on login", + "userLogin": "pierre-lehnen-rc", + "milestone": "4.1.1", + "contributors": [ + "pierre-lehnen-rc" + ] + }, + { + "pr": "23608", + "title": "[FIX] Advanced LDAP Sync Features", + "userLogin": "pierre-lehnen-rc", + "milestone": "4.1.1", + "contributors": [ + "pierre-lehnen-rc", + "web-flow" + ] + } + ] } } -} \ No newline at end of file +} diff --git a/.snapcraft/resources/prepareRocketChat b/.snapcraft/resources/prepareRocketChat index 92c8f26d454d..8326ee76187e 100755 --- a/.snapcraft/resources/prepareRocketChat +++ b/.snapcraft/resources/prepareRocketChat @@ -1,6 +1,6 @@ #!/bin/bash -curl -SLf "https://releases.rocket.chat/4.1.0/download/" -o rocket.chat.tgz +curl -SLf "https://releases.rocket.chat/4.1.1/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 9c13354e4f6a..d9d599fa7ca0 100644 --- a/.snapcraft/snap/snapcraft.yaml +++ b/.snapcraft/snap/snapcraft.yaml @@ -7,7 +7,7 @@ # 5. `snapcraft snap` name: rocketchat-server -version: 4.1.0 +version: 4.1.1 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 e3aa63d8aa17..68f00f36e9ae 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,35 @@ +# 4.1.1 +`2021-11-05 ยท 4 ๐Ÿ› ยท 1 ๐Ÿ” ยท 4 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` + +### Engine versions +- Node: `12.22.1` +- NPM: `6.14.1` +- MongoDB: `3.6, 4.0, 4.2, 4.4, 5.0` +- Apps-Engine: `1.28.1` + +### ๐Ÿ› Bug fixes + + +- Advanced LDAP Sync Features ([#23608](https://github.com/RocketChat/Rocket.Chat/pull/23608)) + +- App update flow failing in HA setups ([#23607](https://github.com/RocketChat/Rocket.Chat/pull/23607)) + + The flow for app updates is broken in specific scenarios with HA setups. Here we change the method calls in the Apps-Engine to avoid race conditions + +- LDAP users not being re-activated on login ([#23627](https://github.com/RocketChat/Rocket.Chat/pull/23627)) + +- Security Hotfix (https://docs.rocket.chat/guides/security/security-updates) + + +### ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป Core Team ๐Ÿค“ + +- [@d-gubert](https://github.com/d-gubert) +- [@pierre-lehnen-rc](https://github.com/pierre-lehnen-rc) +- [@sampaiodiego](https://github.com/sampaiodiego) + # 4.1.0 -`2021-10-27 ยท 1 ๐ŸŽ‰ ยท 4 ๐Ÿš€ ยท 25 ๐Ÿ› ยท 38 ๐Ÿ” ยท 23 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` +`2021-10-28 ยท 1 ๐ŸŽ‰ ยท 4 ๐Ÿš€ ยท 25 ๐Ÿ› ยท 38 ๐Ÿ” ยท 23 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` ### Engine versions - Node: `12.22.1` @@ -24,19 +53,19 @@ - Make Livechat Instructions setting multi-line ([#23515](https://github.com/RocketChat/Rocket.Chat/pull/23515)) - Since now we're supporting markdown text on this field (via this PR - https://github.com/RocketChat/Rocket.Chat.Livechat/pull/648), it would be nice to make this setting multiline so users can have more space to edit the text + Since now we're supporting markdown text on this field (via this PR - https://github.com/RocketChat/Rocket.Chat.Livechat/pull/648), it would be nice to make this setting multiline so users can have more space to edit the text ![image](https://user-images.githubusercontent.com/34130764/138146712-13e4968b-5312-4d53-b44c-b5699c5e49c1.png) - optimized groups.listAll response time ([#22941](https://github.com/RocketChat/Rocket.Chat/pull/22941)) - groups.listAll endpoint was having performance issues, specially when the total number of groups was high. This happened because the endpoint was loading all objects in memory then using splice to paginate, instead of paginating beforehand. - - Considering 70k groups, this was the performance improvement: - - before - ![image](https://user-images.githubusercontent.com/28611993/129601314-bdf89337-79fa-4446-9f44-95264af4adb3.png) - - after + groups.listAll endpoint was having performance issues, specially when the total number of groups was high. This happened because the endpoint was loading all objects in memory then using splice to paginate, instead of paginating beforehand. + + Considering 70k groups, this was the performance improvement: + + before + ![image](https://user-images.githubusercontent.com/28611993/129601314-bdf89337-79fa-4446-9f44-95264af4adb3.png) + + after ![image](https://user-images.githubusercontent.com/28611993/129601358-5872e166-f923-4c1c-b21d-eb9507365ecf.png) ### ๐Ÿ› Bug fixes @@ -44,7 +73,8 @@ - **APPS:** Communication problem when updating and uninstalling apps in cluster ([#23418](https://github.com/RocketChat/Rocket.Chat/pull/23418)) - - Make the hook responsible for receiving app update events inside a cluster fetch the app's package (zip file) in the correct place. + - Make the hook responsible for receiving app update events inside a cluster fetch the app's package (zip file) in the correct place. + - Also shows a warning message on uninstalls inside a cluster. As there are many servers writing to the same place, some race conditions may occur. This prevents problems related to terminating the process in the middle due to errors being thrown and leaving the server in a faulty state. - **ENTERPRISE:** Omnichannel agent is not leaving the room when a forwarded chat is queued ([#23404](https://github.com/RocketChat/Rocket.Chat/pull/23404)) @@ -71,10 +101,10 @@ - Markdown quote message style ([#23462](https://github.com/RocketChat/Rocket.Chat/pull/23462)) - Before: - ![image](https://user-images.githubusercontent.com/17487063/137496669-3abecab4-cf90-45cb-8b1b-d9411a5682dd.png) - - After: + Before: + ![image](https://user-images.githubusercontent.com/17487063/137496669-3abecab4-cf90-45cb-8b1b-d9411a5682dd.png) + + After: ![image](https://user-images.githubusercontent.com/17487063/137496905-fd727f90-f707-4ec6-8139-ba2eb1a2146e.png) - MONGO_OPTIONS being ignored for oplog connection ([#23314](https://github.com/RocketChat/Rocket.Chat/pull/23314) by [@cuonghuunguyen](https://github.com/cuonghuunguyen)) @@ -93,8 +123,8 @@ - Read only description in team creation ([#23213](https://github.com/RocketChat/Rocket.Chat/pull/23213)) - ![image](https://user-images.githubusercontent.com/27704687/133608433-8ca788a3-71a8-4d40-8c40-8156ab03c606.png) - + ![image](https://user-images.githubusercontent.com/27704687/133608433-8ca788a3-71a8-4d40-8c40-8156ab03c606.png) + ![image](https://user-images.githubusercontent.com/27704687/133608400-4cdc7a67-95e5-46c6-8c65-29ab107cd314.png) - resumeToken not working ([#23379](https://github.com/RocketChat/Rocket.Chat/pull/23379)) @@ -103,7 +133,8 @@ - SAML Users' roles being reset to default on login ([#23411](https://github.com/RocketChat/Rocket.Chat/pull/23411)) - - Remove `roles` field update on `insertOrUpdateSAMLUser` function; + - Remove `roles` field update on `insertOrUpdateSAMLUser` function; + - Add SAML `syncRoles` event; - Server crashing when Routing method is not available at start ([#23473](https://github.com/RocketChat/Rocket.Chat/pull/23473)) @@ -184,14 +215,14 @@ - Chore: Startup Time ([#23210](https://github.com/RocketChat/Rocket.Chat/pull/23210)) - The settings logic has been improved as a whole. - - All the logic to get the data from the env var was confusing. - - Setting default values was tricky to understand. - - Every time the server booted, all settings were updated and callbacks were called 2x or more (horrible for environments with multiple instances and generating a turbulent startup). - + The settings logic has been improved as a whole. + + All the logic to get the data from the env var was confusing. + + Setting default values was tricky to understand. + + Every time the server booted, all settings were updated and callbacks were called 2x or more (horrible for environments with multiple instances and generating a turbulent startup). + `Settings.get(......, callback);` was deprecated. We now have better methods for each case. - Chore: Update Apps-Engine version ([#23375](https://github.com/RocketChat/Rocket.Chat/pull/23375)) @@ -214,10 +245,10 @@ - Regression: Mail body contains `undefined` text ([#23552](https://github.com/RocketChat/Rocket.Chat/pull/23552)) - ### Before - ![image](https://user-images.githubusercontent.com/2263066/138733018-10449892-5c2d-46fb-9355-00e98e0d6c9f.png) - - ### After + ### Before + ![image](https://user-images.githubusercontent.com/2263066/138733018-10449892-5c2d-46fb-9355-00e98e0d6c9f.png) + + ### After ![image](https://user-images.githubusercontent.com/2263066/138733074-a1b88a77-bf64-41c3-a6c3-ac9e1cb63de1.png) - Regression: Prevent settings from getting updated ([#23556](https://github.com/RocketChat/Rocket.Chat/pull/23556)) @@ -308,7 +339,8 @@ - SAML Users' roles being reset to default on login ([#23411](https://github.com/RocketChat/Rocket.Chat/pull/23411)) - - Remove `roles` field update on `insertOrUpdateSAMLUser` function; + - Remove `roles` field update on `insertOrUpdateSAMLUser` function; + - Add SAML `syncRoles` event;
@@ -340,7 +372,8 @@ - **APPS:** Communication problem when updating and uninstalling apps in cluster ([#23418](https://github.com/RocketChat/Rocket.Chat/pull/23418)) - - Make the hook responsible for receiving app update events inside a cluster fetch the app's package (zip file) in the correct place. + - Make the hook responsible for receiving app update events inside a cluster fetch the app's package (zip file) in the correct place. + - Also shows a warning message on uninstalls inside a cluster. As there are many servers writing to the same place, some race conditions may occur. This prevents problems related to terminating the process in the middle due to errors being thrown and leaving the server in a faulty state. - Server crashing when Routing method is not available at start ([#23473](https://github.com/RocketChat/Rocket.Chat/pull/23473)) @@ -467,18 +500,20 @@ - **ENTERPRISE:** "Download CSV" button doesn't work in the Engagement Dashboard's Active Users section ([#23013](https://github.com/RocketChat/Rocket.Chat/pull/23013)) - - Fix "Download CSV" button in the Engagement Dashboard's Active Users section; - - Add column headers to the CSV file downloaded from the Engagement Dashboard's Active Users section; + - Fix "Download CSV" button in the Engagement Dashboard's Active Users section; + + - Add column headers to the CSV file downloaded from the Engagement Dashboard's Active Users section; + - Split the data in multiple CSV files. - **ENTERPRISE:** CSV file downloaded in the Engagement Dashboard's New Users section contains undefined data ([#23014](https://github.com/RocketChat/Rocket.Chat/pull/23014)) - - Fix CSV file downloaded in the Engagement Dashboard's New Users section; + - Fix CSV file downloaded in the Engagement Dashboard's New Users section; - Add column headers to the CSV file downloaded from the Engagement Dashboard's New Users section. - **ENTERPRISE:** Missing headers in CSV files downloaded from the Engagement Dashboard ([#23223](https://github.com/RocketChat/Rocket.Chat/pull/23223)) - - Add headers to all CSV files downloaded from the "Messages" and "Channels" tabs from the Engagement Dashboard; + - Add headers to all CSV files downloaded from the "Messages" and "Channels" tabs from the Engagement Dashboard; - Add headers to the CSV file downloaded from the "Users by time of day" section (in the "Users" tab). - LDAP Refactoring ([#23171](https://github.com/RocketChat/Rocket.Chat/pull/23171)) @@ -493,17 +528,24 @@ - Remove deprecated endpoints ([#23162](https://github.com/RocketChat/Rocket.Chat/pull/23162)) - The following REST endpoints were removed: - - - `/api/v1/emoji-custom` - - `/api/v1/info` - - `/api/v1/permissions` - - `/api/v1/permissions.list` - - The following Real time API Methods were removed: - - - `getFullUserData` - - `getServerInfo` + The following REST endpoints were removed: + + + - `/api/v1/emoji-custom` + + - `/api/v1/info` + + - `/api/v1/permissions` + + - `/api/v1/permissions.list` + + The following Real time API Methods were removed: + + + - `getFullUserData` + + - `getServerInfo` + - `livechat:saveOfficeHours` - Remove Google Vision features ([#23160](https://github.com/RocketChat/Rocket.Chat/pull/23160)) @@ -512,8 +554,8 @@ - Remove old migrations up to version 2.4.14 ([#23277](https://github.com/RocketChat/Rocket.Chat/pull/23277)) - To update to version 4.0.0 you'll need to be running at least version 3.0.0, otherwise you might loose some database migrations which might have unexpected effects. - + To update to version 4.0.0 you'll need to be running at least version 3.0.0, otherwise you might loose some database migrations which might have unexpected effects. + This aims to clean up the code, since upgrades jumping 2 major versions are too risky and hard to maintain, we'll keep only migration from that last major (in this case 3.x). - Remove patch info from endpoint /api/info for non-logged in users ([#16050](https://github.com/RocketChat/Rocket.Chat/pull/16050) by [@MarcosSpessatto](https://github.com/MarcosSpessatto)) @@ -522,18 +564,18 @@ - Stop sending audio notifications via stream ([#23108](https://github.com/RocketChat/Rocket.Chat/pull/23108)) - Remove audio preferences and make them tied to desktop notification preferences. - + Remove audio preferences and make them tied to desktop notification preferences. + TL;DR: new message sounds will play only if you receive a desktop notification. you'll still be able to chose to not play any sound though - Webhook will fail if user is not part of the channel ([#23310](https://github.com/RocketChat/Rocket.Chat/pull/23310)) - Remove deprecated behavior added by https://github.com/RocketChat/Rocket.Chat/pull/18024 that accepts webhook integrations sending messages even if the user is not part of the channel. - - Starting from 4.0.0 the webhook request will fail with `error-not-allowed` error: - - ``` - {"success":false,"error":"error-not-allowed"} + Remove deprecated behavior added by https://github.com/RocketChat/Rocket.Chat/pull/18024 that accepts webhook integrations sending messages even if the user is not part of the channel. + + Starting from 4.0.0 the webhook request will fail with `error-not-allowed` error: + + ``` + {"success":false,"error":"error-not-allowed"} ``` ### ๐ŸŽ‰ New features @@ -551,23 +593,26 @@ - Seats Cap ([#23017](https://github.com/RocketChat/Rocket.Chat/pull/23017) by [@g-thome](https://github.com/g-thome)) - - Adding New Members - - Awareness of seats usage while adding new members - - Seats Cap about to be reached - - Seats Cap reached - - Request more seats - - Warning Admins - - System telling admins max seats are about to exceed - - System telling admins max seats were exceed - - Metric on Info Page - - Request more seats - - Warning Members - - Invite link - - Block creating new invite links - - Block existing invite links (feedback on register process) - - Register to Workspaces - - Emails - - System telling admins max seats are about to exceed + - Adding New Members + - Awareness of seats usage while adding new members + - Seats Cap about to be reached + - Seats Cap reached + - Request more seats + + - Warning Admins + - System telling admins max seats are about to exceed + - System telling admins max seats were exceed + - Metric on Info Page + - Request more seats + + - Warning Members + - Invite link + - Block creating new invite links + - Block existing invite links (feedback on register process) + - Register to Workspaces + + - Emails + - System telling admins max seats are about to exceed - System telling admins max seats were exceed ### ๐Ÿš€ Improvements @@ -575,10 +620,10 @@ - **APPS:** New storage strategy for Apps-Engine file packages ([#22657](https://github.com/RocketChat/Rocket.Chat/pull/22657)) - This is an enabler for our initiative to support NPM packages in the Apps-Engine. - - Currently, the packages (zip files) for Rocket.Chat Apps are stored as a base64 encoded string in a document in the database, which constrains us due to the size limit of a document in MongoDB (16Mb). - + This is an enabler for our initiative to support NPM packages in the Apps-Engine. + + Currently, the packages (zip files) for Rocket.Chat Apps are stored as a base64 encoded string in a document in the database, which constrains us due to the size limit of a document in MongoDB (16Mb). + When we allow apps to include NPM packages, the size of the App package itself will be potentially _very large_ (I'm looking at you `node_modules`). Thus we'll be changing the strategy to store apps either with GridFS or the host's File System itself. - **APPS:** Return task ids when using the scheduler api ([#23023](https://github.com/RocketChat/Rocket.Chat/pull/23023)) @@ -618,9 +663,9 @@ - "Read Only" and "Allow Reacting" system messages are missing in rooms ([#23037](https://github.com/RocketChat/Rocket.Chat/pull/23037)) - - Add system message to notify changes on the **"Read Only"** setting; - - Add system message to notify changes on the **"Allow Reacting"** setting; - - Fix "Allow Reacting" setting's description (updated from "Only authorized users can write new messages" to "Only authorized users can react to messages"). + - Add system message to notify changes on the **"Read Only"** setting; + - Add system message to notify changes on the **"Allow Reacting"** setting; + - Fix "Allow Reacting" setting's description (updated from "Only authorized users can write new messages" to "Only authorized users can react to messages"). ![system-messages](https://user-images.githubusercontent.com/36537004/130883527-9eb47fcd-c8e5-41fb-af34-5d99bd0a6780.PNG) - Add check before placing chat on-hold to confirm that contact sent last message ([#23053](https://github.com/RocketChat/Rocket.Chat/pull/23053)) @@ -635,9 +680,9 @@ - Inaccurate use of 'Mobile notifications' instead of 'Push notifications' in i18n strings ([#22978](https://github.com/RocketChat/Rocket.Chat/pull/22978)) - - Fix inaccurate use of 'Mobile notifications' (which is misleading in German) by 'Push notifications'; - - Update `'Notification_Mobile_Default_For'` key to `'Notification_Push_Default_For'` (and text to 'Send Push Notifications For' for English Language); - - Update `'Accounts_Default_User_Preferences_mobileNotifications'` key to `'Accounts_Default_User_Preferences_pushNotifications'`; + - Fix inaccurate use of 'Mobile notifications' (which is misleading in German) by 'Push notifications'; + - Update `'Notification_Mobile_Default_For'` key to `'Notification_Push_Default_For'` (and text to 'Send Push Notifications For' for English Language); + - Update `'Accounts_Default_User_Preferences_mobileNotifications'` key to `'Accounts_Default_User_Preferences_pushNotifications'`; - Update `'Mobile_Notifications_Default_Alert'` key to `'Mobile_Push_Notifications_Default_Alert'`; - Logging out from other clients ([#23276](https://github.com/RocketChat/Rocket.Chat/pull/23276)) @@ -646,7 +691,7 @@ - Modals is cutting pixels of the content ([#23243](https://github.com/RocketChat/Rocket.Chat/pull/23243)) - Fuselage Dependency: [543](https://github.com/RocketChat/Rocket.Chat.Fuselage/pull/543) + Fuselage Dependency: [543](https://github.com/RocketChat/Rocket.Chat.Fuselage/pull/543) ![image](https://user-images.githubusercontent.com/27704687/134049227-3cd1deed-34ba-454f-a95e-e99b79a7a7b9.png) - Omnichannel On hold chats being forwarded to offline agents ([#23185](https://github.com/RocketChat/Rocket.Chat/pull/23185)) @@ -655,15 +700,15 @@ - Prevent users to edit an existing role when adding a new one with the same name used before. ([#22407](https://github.com/RocketChat/Rocket.Chat/pull/22407) by [@lucassartor](https://github.com/lucassartor)) - ### before - ![Peek 2021-07-13 16-31](https://user-images.githubusercontent.com/27704687/125513721-953d84f4-1c95-45ca-80e1-b00992b874f6.gif) - - ### after + ### before + ![Peek 2021-07-13 16-31](https://user-images.githubusercontent.com/27704687/125513721-953d84f4-1c95-45ca-80e1-b00992b874f6.gif) + + ### after ![Peek 2021-07-13 16-34](https://user-images.githubusercontent.com/27704687/125514098-91ee8014-51e5-4c62-9027-5538acf57d08.gif) - Remove doubled "Canned Responses" strings ([#23056](https://github.com/RocketChat/Rocket.Chat/pull/23056)) - - Remove doubled canned response setting introduced in #22703 (by setting id change); + - Remove doubled canned response setting introduced in #22703 (by setting id change); - Update "Canned Responses" keys to "Canned_Responses". - Remove margin from quote inside quote ([#21779](https://github.com/RocketChat/Rocket.Chat/pull/21779)) @@ -674,16 +719,21 @@ - Sidebar not closing when clicking in Home or Directory on mobile view ([#23218](https://github.com/RocketChat/Rocket.Chat/pull/23218)) - ### Additional fixed - - Merge Burger menu components into a single component - - Show a badge with no-read messages in the Burger Button: - ![image](https://user-images.githubusercontent.com/27704687/133679378-20fea2c0-4ac1-4b4e-886e-45154cc6afea.png) + ### Additional fixed + + - Merge Burger menu components into a single component + + - Show a badge with no-read messages in the Burger Button: + ![image](https://user-images.githubusercontent.com/27704687/133679378-20fea2c0-4ac1-4b4e-886e-45154cc6afea.png) + - remove useSidebarClose hook - Stop queue when Omnichannel is disabled or the routing method does not support it ([#23261](https://github.com/RocketChat/Rocket.Chat/pull/23261)) - - Add missing key logs - - Stop queue (and logs) when livechat is disabled or when routing method does not support queue + - Add missing key logs + + - Stop queue (and logs) when livechat is disabled or when routing method does not support queue + - Stop ignoring offline bot agents from delegation (previously, if a bot was offline, even with "Assign new conversations to bot agent" enabled, bot will be ignored and chat will be left in limbo (since bot was assigned, but offline). - Toolbox click not working on Safari(iOS) ([#23244](https://github.com/RocketChat/Rocket.Chat/pull/23244)) @@ -790,17 +840,17 @@ - Regression: Blank screen in Jitsi video calls ([#23322](https://github.com/RocketChat/Rocket.Chat/pull/23322)) - - Fix Jitsi calls being disposed even when "Open in new window" setting is disabled; + - Fix Jitsi calls being disposed even when "Open in new window" setting is disabled; - Fix misspelling on `CallJitsWithData.js` file name. - Regression: Create new loggers based on server log level ([#23297](https://github.com/RocketChat/Rocket.Chat/pull/23297)) - Regression: Fix app storage migration ([#23286](https://github.com/RocketChat/Rocket.Chat/pull/23286)) - The previous version of this migration didn't take into consideration apps that were installed prior to [Rocket.Chat@3.8.0](https://github.com/RocketChat/Rocket.Chat/releases/tag/3.8.0), which [removed the typescript compiler from the server](https://github.com/RocketChat/Rocket.Chat/pull/18687) and into the CLI. As a result, the zip files inside each installed app's document in the database had typescript files in them instead of the now required javascript files. - - As the new strategy of source code storage for apps changes the way the app is loaded, those zip files containing the source code are read everytime the app is started (or [in this particular case, updated](https://github.com/RocketChat/Rocket.Chat/pull/23286/files#diff-caf9f7a22478639e58d6514be039140a42ce1ab2d999c3efe5678c38ee36d0ccR43)), and as the zips' contents were wrong, the operation was failing. - + The previous version of this migration didn't take into consideration apps that were installed prior to [Rocket.Chat@3.8.0](https://github.com/RocketChat/Rocket.Chat/releases/tag/3.8.0), which [removed the typescript compiler from the server](https://github.com/RocketChat/Rocket.Chat/pull/18687) and into the CLI. As a result, the zip files inside each installed app's document in the database had typescript files in them instead of the now required javascript files. + + As the new strategy of source code storage for apps changes the way the app is loaded, those zip files containing the source code are read everytime the app is started (or [in this particular case, updated](https://github.com/RocketChat/Rocket.Chat/pull/23286/files#diff-caf9f7a22478639e58d6514be039140a42ce1ab2d999c3efe5678c38ee36d0ccR43)), and as the zips' contents were wrong, the operation was failing. + The fix extract the data from old apps and creates new zip files with the compiled `js` already present. - Regression: Fix Bugsnag not started error ([#23308](https://github.com/RocketChat/Rocket.Chat/pull/23308)) @@ -977,8 +1027,10 @@ - **ENTERPRISE:** Maximum waiting time for chats in Omnichannel queue ([#22955](https://github.com/RocketChat/Rocket.Chat/pull/22955)) - - Add new settings to support closing chats that have been too long on waiting queue - - Moved old settings to new "Queue Management" section + - Add new settings to support closing chats that have been too long on waiting queue + + - Moved old settings to new "Queue Management" section + - Fix issue when closing a livechat room that caused client to not to know if room was open or not - Banner for the updates regarding authentication services ([#23055](https://github.com/RocketChat/Rocket.Chat/pull/23055) by [@g-thome](https://github.com/g-thome)) @@ -993,10 +1045,10 @@ - Separate RegEx Settings for Channels and Usernames validation ([#21937](https://github.com/RocketChat/Rocket.Chat/pull/21937) by [@aditya-mitra](https://github.com/aditya-mitra)) - Now, there are 2 separate settings for validating names - One for **channels** and another for **usernames**. - - This change also removes the old `UTF8_Names_Validation` setting and adds 2 new settings `UTF8_User_Names_Validation` and `UTF8_Channel_Names_Validation`. - + Now, there are 2 separate settings for validating names - One for **channels** and another for **usernames**. + + This change also removes the old `UTF8_Names_Validation` setting and adds 2 new settings `UTF8_User_Names_Validation` and `UTF8_Channel_Names_Validation`. + https://user-images.githubusercontent.com/55396651/116969904-af5bb800-acd4-11eb-9fc4-dacac60cb08f.mp4 ### ๐Ÿš€ Improvements @@ -1012,13 +1064,13 @@ - Rewrite File Upload Modal ([#22750](https://github.com/RocketChat/Rocket.Chat/pull/22750)) - Image preview: - ![image](https://user-images.githubusercontent.com/40830821/127223432-dccd2182-aec0-430f-8d70-03ac88aec791.png) - - Video preview: - ![image](https://user-images.githubusercontent.com/40830821/127225982-f8b21840-0d9c-4aff-a354-16188c7ed66e.png) - - Files larger than 10mb: + Image preview: + ![image](https://user-images.githubusercontent.com/40830821/127223432-dccd2182-aec0-430f-8d70-03ac88aec791.png) + + Video preview: + ![image](https://user-images.githubusercontent.com/40830821/127225982-f8b21840-0d9c-4aff-a354-16188c7ed66e.png) + + Files larger than 10mb: ![image](https://user-images.githubusercontent.com/40830821/127222611-5265040f-a06b-4ec5-b528-89b40e6a9072.png) - Types from currentChatsPage.tsx ([#22967](https://github.com/RocketChat/Rocket.Chat/pull/22967)) @@ -1034,14 +1086,14 @@ - "Users By Time of the Day" chart displays incorrect data for Local Timezone ([#22836](https://github.com/RocketChat/Rocket.Chat/pull/22836)) - - Add local timezone conversion to the "Users By Time of the Day" chart in the Engagement Dashboard; + - Add local timezone conversion to the "Users By Time of the Day" chart in the Engagement Dashboard; - Simplify date creations by using `endOf` and `startOf` methods. - Atlassian Crowd connection not working ([#22996](https://github.com/RocketChat/Rocket.Chat/pull/22996) by [@piotrkochan](https://github.com/piotrkochan)) - Audio recording doesn't stop in direct messages on channel switch ([#22880](https://github.com/RocketChat/Rocket.Chat/pull/22880)) - - Cancel audio recordings on message bar destroy event. + - Cancel audio recordings on message bar destroy event. ![test-22372](https://user-images.githubusercontent.com/36537004/128569780-d83747b0-fb9c-4dc6-9bc5-7ae573e720c8.gif) - Bad words falling if message is empty ([#22930](https://github.com/RocketChat/Rocket.Chat/pull/22930)) @@ -1066,21 +1118,23 @@ - Return transcript/dashboards based on timezone settings ([#22850](https://github.com/RocketChat/Rocket.Chat/pull/22850)) - - Added new setting to manage timezones - - Applied new setting to omnichannel dashboards (realtime, analytics) [NOTE: Other dashboards aren't using this setting actually) + - Added new setting to manage timezones + + - Applied new setting to omnichannel dashboards (realtime, analytics) [NOTE: Other dashboards aren't using this setting actually) + - Change getAnalyticsBetweenDate query to filter out system messages instead of substracting them - Tab margin style ([#22851](https://github.com/RocketChat/Rocket.Chat/pull/22851)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/128103848-2a25ba7e-0e59-4502-9bcd-2569cad9379a.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/128103848-2a25ba7e-0e59-4502-9bcd-2569cad9379a.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/128103633-ec7b93fc-4667-4dc9-bad3-bfffaff3974e.png) - Threads and discussions searches don't display proper results ([#22914](https://github.com/RocketChat/Rocket.Chat/pull/22914)) - - _Fix_ issue in discussions search (which wasn't working after a search with no results was made); + - _Fix_ issue in discussions search (which wasn't working after a search with no results was made); - _Improve_ discussions and threads searches: both searches (`chat.getDiscussions` and `chat.getThreadsList`) are now case insensitive (do NOT differ capital from lower letters) and match incomplete words or terms. - Threads List being requested more than expected ([#22879](https://github.com/RocketChat/Rocket.Chat/pull/22879)) @@ -1115,8 +1169,8 @@ - Chore: Script to start Rocket.Chat in HA mode during development ([#22398](https://github.com/RocketChat/Rocket.Chat/pull/22398)) - Sometimes we need to start Rocket.Chat in High-Availability mode (cluster) during development to test how a feature behaves or hunt down a bug. Currently, this involves a lot of commands with details that might be lost if you haven't done it in a while. - + Sometimes we need to start Rocket.Chat in High-Availability mode (cluster) during development to test how a feature behaves or hunt down a bug. Currently, this involves a lot of commands with details that might be lost if you haven't done it in a while. + This PR intends to provide a really simple way for us to start many instances of Rocket.Chat connected in a cluster. - Chore: Update Livechat widget to 1.9.4 ([#22990](https://github.com/RocketChat/Rocket.Chat/pull/22990)) @@ -1133,13 +1187,13 @@ - Regression: File upload name suggestion ([#22953](https://github.com/RocketChat/Rocket.Chat/pull/22953)) - Before: - ![image](https://user-images.githubusercontent.com/40830821/129774936-ecdbe9a1-5e3f-4a0a-ad1e-6f13eb15c60b.png) - ![image](https://user-images.githubusercontent.com/40830821/129775011-fb0df01d-74e4-41ae-bb47-dcf4cc17735e.png) - - - After: - ![image](https://user-images.githubusercontent.com/40830821/129774877-928a8aa0-c003-4e57-8b33-ea6accc32774.png) + Before: + ![image](https://user-images.githubusercontent.com/40830821/129774936-ecdbe9a1-5e3f-4a0a-ad1e-6f13eb15c60b.png) + ![image](https://user-images.githubusercontent.com/40830821/129775011-fb0df01d-74e4-41ae-bb47-dcf4cc17735e.png) + + + After: + ![image](https://user-images.githubusercontent.com/40830821/129774877-928a8aa0-c003-4e57-8b33-ea6accc32774.png) ![image](https://user-images.githubusercontent.com/40830821/129774972-d67debaf-0ce9-44fb-93cb-d7612dd18edf.png) - Regression: Fix creation of self-DMs ([#23015](https://github.com/RocketChat/Rocket.Chat/pull/23015)) @@ -1207,7 +1261,8 @@ - Fix Auto Selection algorithm on community edition ([#22991](https://github.com/RocketChat/Rocket.Chat/pull/22991)) - - When using the autoselection algo on community editions, all agents were marked as unavailable due to an unapplied filter + - When using the autoselection algo on community editions, all agents were marked as unavailable due to an unapplied filter + - Fixed an issue when both user & system setting to manange EE max number of chats allowed were set to 0
@@ -1247,7 +1302,7 @@ - Apps-Engine's scheduler failing to update run tasks ([#22882](https://github.com/RocketChat/Rocket.Chat/pull/22882)) - [Agenda](https://github.com/agenda/agenda), the library that manages scheduling, depended on setting a job property named `nextRunAt` as `undefined` to signal whether it should be run on schedule or not. [Rocket.Chat's current Mongo driver](https://github.com/RocketChat/Rocket.Chat/pull/22399) ignores `undefined` values when updating documents and this was causing jobs to never stop running as Agenda couldn't clear that property (set them as `undefined`). + [Agenda](https://github.com/agenda/agenda), the library that manages scheduling, depended on setting a job property named `nextRunAt` as `undefined` to signal whether it should be run on schedule or not. [Rocket.Chat's current Mongo driver](https://github.com/RocketChat/Rocket.Chat/pull/22399) ignores `undefined` values when updating documents and this was causing jobs to never stop running as Agenda couldn't clear that property (set them as `undefined`). This updates Rocket.Chat's dependency on Agenda.js to point to [a fork that fixes the problem](https://github.com/RocketChat/agenda/releases/tag/3.1.2). - Close omnichannel conversations when agent is deactivated ([#22917](https://github.com/RocketChat/Rocket.Chat/pull/22917)) @@ -1301,7 +1356,7 @@ - Monitoring Track messages' round trip time ([#22676](https://github.com/RocketChat/Rocket.Chat/pull/22676)) - Track messages' roundtrip time from backend saves time to the time when received back from the oplog allowing track of oplog slowness. + Track messages' roundtrip time from backend saves time to the time when received back from the oplog allowing track of oplog slowness. Prometheus metric: `rocketchat_messages_roundtrip_time` - REST endpoint to remove User from Role ([#20485](https://github.com/RocketChat/Rocket.Chat/pull/20485) by [@Cosnavel](https://github.com/Cosnavel) & [@lucassartor](https://github.com/lucassartor)) @@ -1313,19 +1368,22 @@ - Change message deletion confirmation modal to toast ([#22544](https://github.com/RocketChat/Rocket.Chat/pull/22544)) - Changed a timed modal for a toast message + Changed a timed modal for a toast message ![image](https://user-images.githubusercontent.com/40830821/124192670-0646f900-da9c-11eb-941c-9ae35421f6ef.png) - Configuration for indices in Apps-Engine models ([#22705](https://github.com/RocketChat/Rocket.Chat/pull/22705)) - * Add `appId` field to the data saved by the Scheduler - * Add `appId` index to `rocketchat_apps_persistence` model - * Skip "trash collection" when deleting records from `rocketchat_apps_persistence` - * Add a new setting to control for how long we should keep logs from the apps - - ![image](https://user-images.githubusercontent.com/1810309/126246666-907f9d98-1d84-4dfe-a80a-7dd874d36fa8.png) - - + * Add `appId` field to the data saved by the Scheduler + + * Add `appId` index to `rocketchat_apps_persistence` model + + * Skip "trash collection" when deleting records from `rocketchat_apps_persistence` + + * Add a new setting to control for how long we should keep logs from the apps + + ![image](https://user-images.githubusercontent.com/1810309/126246666-907f9d98-1d84-4dfe-a80a-7dd874d36fa8.png) + + ![image](https://user-images.githubusercontent.com/1810309/126246655-2ce3cb5f-b2f5-456e-a9c4-beccd9b3ef41.png) - Make `shortcut` field of canned responses unique ([#22700](https://github.com/RocketChat/Rocket.Chat/pull/22700)) @@ -1348,37 +1406,38 @@ - Replace remaing discussion creation modals with React modal. ([#22448](https://github.com/RocketChat/Rocket.Chat/pull/22448)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/123840524-cbe72b80-d8e4-11eb-9ddb-23a9f9d90aac.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/123840524-cbe72b80-d8e4-11eb-9ddb-23a9f9d90aac.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/123840219-74e15680-d8e4-11eb-95aa-00a990ffe0e7.png) - Return open room if available for visitors ([#22742](https://github.com/RocketChat/Rocket.Chat/pull/22742)) - Rewrite Enter Encryption Password Modal ([#22456](https://github.com/RocketChat/Rocket.Chat/pull/22456)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/123182889-bbf3c580-d466-11eb-8d4d-9cfc3d224e33.png) - - ### after - ![image](https://user-images.githubusercontent.com/27704687/123182916-cada7800-d466-11eb-96ee-850be190d419.png) - - ### Aditional Improves: + ### before + ![image](https://user-images.githubusercontent.com/27704687/123182889-bbf3c580-d466-11eb-8d4d-9cfc3d224e33.png) + + ### after + ![image](https://user-images.githubusercontent.com/27704687/123182916-cada7800-d466-11eb-96ee-850be190d419.png) + + ### Aditional Improves: + - Added a visual validation in the password field - Rewrite OTR modals ([#22583](https://github.com/RocketChat/Rocket.Chat/pull/22583)) - ![image](https://user-images.githubusercontent.com/40830821/124513267-cb510800-ddb0-11eb-8165-f103029c348f.png) - ![image](https://user-images.githubusercontent.com/40830821/124513354-04897800-ddb1-11eb-96f4-41fe906ca0d7.png) + ![image](https://user-images.githubusercontent.com/40830821/124513267-cb510800-ddb0-11eb-8165-f103029c348f.png) + ![image](https://user-images.githubusercontent.com/40830821/124513354-04897800-ddb1-11eb-96f4-41fe906ca0d7.png) ![image](https://user-images.githubusercontent.com/40830821/124513395-1b2fcf00-ddb1-11eb-83e4-3f8f9b4676ba.png) - Rewrite Save Encryption Password Modal ([#22447](https://github.com/RocketChat/Rocket.Chat/pull/22447)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/122980201-c337a800-d36e-11eb-8e2b-68534cea8e1e.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/122980201-c337a800-d36e-11eb-8e2b-68534cea8e1e.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/122980409-f8dc9100-d36e-11eb-9c15-aff779c84a91.png) - Rewrite sidebar footer as React Component ([#22687](https://github.com/RocketChat/Rocket.Chat/pull/22687)) @@ -1393,12 +1452,12 @@ - Wrong error message when trying to create a blocked username ([#22452](https://github.com/RocketChat/Rocket.Chat/pull/22452) by [@lucassartor](https://github.com/lucassartor)) - When trying to create a user with a blocked username, the UI was showing generic error message that it wasn't very detailed. - - Old error message: - ![image](https://user-images.githubusercontent.com/49413772/123120080-6d203e80-d41a-11eb-8c87-64e34334c856.png) - - New error message: + When trying to create a user with a blocked username, the UI was showing generic error message that it wasn't very detailed. + + Old error message: + ![image](https://user-images.githubusercontent.com/49413772/123120080-6d203e80-d41a-11eb-8c87-64e34334c856.png) + + New error message: ![aaa](https://user-images.githubusercontent.com/49413772/123120251-8c1ed080-d41a-11eb-8dc2-d7484923d851.PNG) ### ๐Ÿ› Bug fixes @@ -1406,19 +1465,19 @@ - **ENTERPRISE:** Engagement Dashboard displaying incorrect data about active users ([#22381](https://github.com/RocketChat/Rocket.Chat/pull/22381)) - - Fix sessions' and users' grouping in the Engagement Dashboard API endpoints; - - Fix the data displayed in the charts from the "Active users", "Users by time of day" and "When is the chat busier?" sections of the Engagement Dashboard; + - Fix sessions' and users' grouping in the Engagement Dashboard API endpoints; + - Fix the data displayed in the charts from the "Active users", "Users by time of day" and "When is the chat busier?" sections of the Engagement Dashboard; - Replace label used to describe the amount of Active Users in the License section of the Info page. - **ENTERPRISE:** Make AutoSelect algo take current agent load in consideration ([#22611](https://github.com/RocketChat/Rocket.Chat/pull/22611)) - **ENTERPRISE:** Race condition on Omnichannel visitor abandoned callback ([#22413](https://github.com/RocketChat/Rocket.Chat/pull/22413)) - As you can see [here](https://github.com/RocketChat/Rocket.Chat/blob/857791c39c97b51b5b6fd3718e0c816959a81c3b/ee/app/livechat-enterprise/server/lib/Helper.js#L127) the `predictedVisitorAbandonment` flag is not set if the room object doesn't have `v.lastMessageTs` property. So we need to always make sure the `v.lastMessageTs` is set before this method is called. - - Currently the `v.lastMessageTs` is being set in [this](https://github.com/RocketChat/Rocket.Chat/blob/857791c39c97b51b5b6fd3718e0c816959a81c3b/app/livechat/server/hooks/saveLastVisitorMessageTs.js#L4) (lets call this **hook-1**) hook which has `HIGH` priority - and the `predictedVisitorAbandonment` check is inturn performed in [this](https://github.com/RocketChat/Rocket.Chat/blob/857791c39c97b51b5b6fd3718e0c816959a81c3b/ee/app/livechat-enterprise/server/hooks/setPredictedVisitorAbandonmentTime.js#L5) (let call this **hook-2**) hook which is also `HIGH` priority. - + As you can see [here](https://github.com/RocketChat/Rocket.Chat/blob/857791c39c97b51b5b6fd3718e0c816959a81c3b/ee/app/livechat-enterprise/server/lib/Helper.js#L127) the `predictedVisitorAbandonment` flag is not set if the room object doesn't have `v.lastMessageTs` property. So we need to always make sure the `v.lastMessageTs` is set before this method is called. + + Currently the `v.lastMessageTs` is being set in [this](https://github.com/RocketChat/Rocket.Chat/blob/857791c39c97b51b5b6fd3718e0c816959a81c3b/app/livechat/server/hooks/saveLastVisitorMessageTs.js#L4) (lets call this **hook-1**) hook which has `HIGH` priority + and the `predictedVisitorAbandonment` check is inturn performed in [this](https://github.com/RocketChat/Rocket.Chat/blob/857791c39c97b51b5b6fd3718e0c816959a81c3b/ee/app/livechat-enterprise/server/hooks/setPredictedVisitorAbandonmentTime.js#L5) (let call this **hook-2**) hook which is also `HIGH` priority. + So ideally we'd except the **hook-1** to be called b4 **hook-2**, however currently since both of them are at same priority, there is no way to control which one is executed first. Hence in this PR, I'm making the priority of **hook-2** as `MEDIUM` to keeping the priority of **hook-1** the same as b4, i.e. `HIGH`. This should make sure that the **hook-1** is always executed b4 **hook-2** - Admin page crashing when commit hash is null ([#22057](https://github.com/RocketChat/Rocket.Chat/pull/22057) by [@cprice-kgi](https://github.com/cprice-kgi)) @@ -1427,39 +1486,41 @@ - Blank screen in message auditing DM tab ([#22763](https://github.com/RocketChat/Rocket.Chat/pull/22763)) - The DM tab in message auditing was displaying a blank screen, instead of the actual tab. - + The DM tab in message auditing was displaying a blank screen, instead of the actual tab. + ![image](https://user-images.githubusercontent.com/28611993/127041404-dfca7f6a-2b8b-4c15-9cbd-c6238fac0063.png) - Bugs in AutoCompleteDepartment ([#22414](https://github.com/RocketChat/Rocket.Chat/pull/22414)) - Call button is still displayed when the user doesn't have permission to use it ([#22170](https://github.com/RocketChat/Rocket.Chat/pull/22170)) - - Hide 'Call' buttons from the tab bar for muted users; + - Hide 'Call' buttons from the tab bar for muted users; + - Display an error when a muted user attempts to enter a call using the 'Click to Join!' button. - Can't see full user profile on team's room ([#22355](https://github.com/RocketChat/Rocket.Chat/pull/22355)) - ### before - ![before](https://user-images.githubusercontent.com/27704687/121966860-bbac4980-cd45-11eb-8d48-2b0457110fc7.gif) - - ### after - ![after](https://user-images.githubusercontent.com/27704687/121966870-bea73a00-cd45-11eb-9c89-ec52ac17e20f.gif) - - ### aditional fix :rocket: + ### before + ![before](https://user-images.githubusercontent.com/27704687/121966860-bbac4980-cd45-11eb-8d48-2b0457110fc7.gif) + + ### after + ![after](https://user-images.githubusercontent.com/27704687/121966870-bea73a00-cd45-11eb-9c89-ec52ac17e20f.gif) + + ### aditional fix :rocket: + - unnecessary `TeamsMembers` component removed - Cannot create a discussion from top left sidebar as a user ([#22618](https://github.com/RocketChat/Rocket.Chat/pull/22618) by [@lucassartor](https://github.com/lucassartor)) - When trying to create a discussion using the top left sidebar modal with an role that don't have the `view-other-user-channels ` permission, an empty list would be shown, which is a wrong behavior. - Also, when being able to use this modal, discussions were listed as options, which is also a wrong behavior as there can't be nested discussions. - - This PR looks to fix both these issues. - - **Old behavior:** - ![old](https://user-images.githubusercontent.com/49413772/124960017-3c333280-dff2-11eb-86cd-b2638311517e.png) - - **New behavior:** + When trying to create a discussion using the top left sidebar modal with an role that don't have the `view-other-user-channels ` permission, an empty list would be shown, which is a wrong behavior. + Also, when being able to use this modal, discussions were listed as options, which is also a wrong behavior as there can't be nested discussions. + + This PR looks to fix both these issues. + + **Old behavior:** + ![old](https://user-images.githubusercontent.com/49413772/124960017-3c333280-dff2-11eb-86cd-b2638311517e.png) + + **New behavior:** ![image](https://user-images.githubusercontent.com/49413772/124958882-05a8e800-dff1-11eb-8203-b34a4f1c98a0.png) - Channel is automatically getting added to the first option in move to team feature ([#22670](https://github.com/RocketChat/Rocket.Chat/pull/22670)) @@ -1474,12 +1535,12 @@ - Create discussion modal - cancel button and invite users alignment ([#22718](https://github.com/RocketChat/Rocket.Chat/pull/22718)) - Changes in "open discussion" modal - - > Added cancel button - > Fixed alignment in invite user - - + Changes in "open discussion" modal + + > Added cancel button + > Fixed alignment in invite user + + ![image](https://user-images.githubusercontent.com/28611993/126388304-6ac76574-6924-426e-843d-afd53dc1c874.png) - crush in the getChannelHistory method ([#22667](https://github.com/RocketChat/Rocket.Chat/pull/22667) by [@MaestroArt](https://github.com/MaestroArt)) @@ -1514,27 +1575,29 @@ - Quote message not working for Livechat visitors ([#22586](https://github.com/RocketChat/Rocket.Chat/pull/22586)) - ### Before: - ![image](https://user-images.githubusercontent.com/34130764/124583613-de2b1180-de70-11eb-82aa-18564b317626.png) - ### After: + ### Before: + ![image](https://user-images.githubusercontent.com/34130764/124583613-de2b1180-de70-11eb-82aa-18564b317626.png) + ### After: ![image](https://user-images.githubusercontent.com/34130764/124583775-12063700-de71-11eb-8ab5-b0169fac2d40.png) - Redirect to login after delete own account ([#22499](https://github.com/RocketChat/Rocket.Chat/pull/22499)) - Redirect the user to login after delete own account - - ### Aditional fixes: - - Visual issue in password input on Delete Own Account Modal - - ### before - ![image](https://user-images.githubusercontent.com/27704687/123711503-f5ea1080-d846-11eb-96aa-8ed638ca665c.png) - - ### after + Redirect the user to login after delete own account + + ### Aditional fixes: + + - Visual issue in password input on Delete Own Account Modal + + ### before + ![image](https://user-images.githubusercontent.com/27704687/123711503-f5ea1080-d846-11eb-96aa-8ed638ca665c.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/123711336-b3c0cf00-d846-11eb-9408-a686d8668ba5.png) - Remove stack traces from Meteor errors when debug setting is disabled ([#22699](https://github.com/RocketChat/Rocket.Chat/pull/22699)) - - Fix 'not iterable' errors in the `normalizeMessage` function; + - Fix 'not iterable' errors in the `normalizeMessage` function; + - Remove stack traces from errors thrown by the `jitsi:updateTimeout` (and other `Meteor.Error`s) method. - Rewrite CurrentChats to TS ([#22424](https://github.com/RocketChat/Rocket.Chat/pull/22424)) @@ -1623,15 +1686,16 @@ - Regression: Data in the "Active Users" section is delayed in 1 day ([#22794](https://github.com/RocketChat/Rocket.Chat/pull/22794)) - - Fix 1 day delay in the Engagement Dashboard's "Active Users" section; - - Downgrade `@nivo/line` version. - **Expected behavior:** + - Fix 1 day delay in the Engagement Dashboard's "Active Users" section; + + - Downgrade `@nivo/line` version. + **Expected behavior:** ![active-users-engagement-dashboard](https://user-images.githubusercontent.com/36537004/127372185-390dc42f-bc90-4841-a22b-731f0aafcafe.PNG) - Regression: Data in the "New Users" section is delayed in 1 day ([#22751](https://github.com/RocketChat/Rocket.Chat/pull/22751)) - - Update nivo version (which was causing errors in the bar chart); - - Fix 1 day delay in '7 days' and '30 days' periods; + - Update nivo version (which was causing errors in the bar chart); + - Fix 1 day delay in '7 days' and '30 days' periods; - Update tooltip theme. - Regression: Federation warnings on ci ([#22765](https://github.com/RocketChat/Rocket.Chat/pull/22765) by [@g-thome](https://github.com/g-thome)) @@ -1656,9 +1720,9 @@ - Regression: Fix tooltip style in the "Busiest Chat Times" chart ([#22813](https://github.com/RocketChat/Rocket.Chat/pull/22813)) - - Fix tooltip in the Engagement Dashboard's "Busiest Chat Times" chart (Hours). - - **Expected behavior:** + - Fix tooltip in the Engagement Dashboard's "Busiest Chat Times" chart (Hours). + + **Expected behavior:** ![busiest-times-ed](https://user-images.githubusercontent.com/36537004/127527827-465397ed-f089-4fb7-9ab2-6fa8cea6abdf.PNG) - Regression: Fix users not being able to see the scope of the canned mโ€ฆ ([#22760](https://github.com/RocketChat/Rocket.Chat/pull/22760)) @@ -1675,10 +1739,10 @@ - Regression: Prevent custom status from being visible in sequential messages ([#22733](https://github.com/RocketChat/Rocket.Chat/pull/22733)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/126641946-866dae96-1983-43a5-b689-b24670473ad0.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/126641946-866dae96-1983-43a5-b689-b24670473ad0.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/126641752-3163eb95-1cd4-4d99-a61a-4d06d9e7e13e.png) - Regression: Properly force newline in attachment fields ([#22727](https://github.com/RocketChat/Rocket.Chat/pull/22727)) @@ -1859,30 +1923,32 @@ - Add `teams.convertToChannel` endpoint ([#22188](https://github.com/RocketChat/Rocket.Chat/pull/22188)) - - Add new `teams.converToChannel` endpoint; - - Update `ConvertToTeam` modal text (since this action can now be reversed); + - Add new `teams.converToChannel` endpoint; + + - Update `ConvertToTeam` modal text (since this action can now be reversed); + - Remove corresponding team memberships when a team is deleted or converted to a channel; - Add setting to configure default role for user on manual registration ([#20650](https://github.com/RocketChat/Rocket.Chat/pull/20650) by [@lucassartor](https://github.com/lucassartor)) - Add an `admin` setting to determine the initial `role` for new users who registered manually (through the register form and via API, not using an authentication service), normally all new users are assigned to the `user` role. - - The setting can be found in `Admin`->`Accounts`->`Registration`. - - ![image](https://user-images.githubusercontent.com/49413772/107252603-47b70900-6a14-11eb-9cc6-df76720b7365.png) - The setting initial value is false, so the default behaviour stays the same while creating a new server or upgrading one. - - https://user-images.githubusercontent.com/49413772/107253220-ddeb2f00-6a14-11eb-85b4-f770dbbe4970.mp4 - + Add an `admin` setting to determine the initial `role` for new users who registered manually (through the register form and via API, not using an authentication service), normally all new users are assigned to the `user` role. + + The setting can be found in `Admin`->`Accounts`->`Registration`. + + ![image](https://user-images.githubusercontent.com/49413772/107252603-47b70900-6a14-11eb-9cc6-df76720b7365.png) + The setting initial value is false, so the default behaviour stays the same while creating a new server or upgrading one. + + https://user-images.githubusercontent.com/49413772/107253220-ddeb2f00-6a14-11eb-85b4-f770dbbe4970.mp4 + Video showing an example of the setting being used and creating an new user with the default roles via API. - Content-Security-Policy for inline scripts ([#20724](https://github.com/RocketChat/Rocket.Chat/pull/20724)) - Security policies were applied for inline scripts cases. Due to the libraries and components we use it is not possible to disable inline styles and images as they would break Oembeds and other libraries. - - - basically the inline scripts were moved to a js file - + Security policies were applied for inline scripts cases. Due to the libraries and components we use it is not possible to disable inline styles and images as they would break Oembeds and other libraries. + + + basically the inline scripts were moved to a js file + and besides that some suggars syntax like `addScript` and `addStyle` were added, this way the application already takes care of inserting the elements and providing the content automatically. - Open modals in side effects outside React ([#22247](https://github.com/RocketChat/Rocket.Chat/pull/22247)) @@ -1898,15 +1964,17 @@ - Add BBB and Jitsi to Team ([#22312](https://github.com/RocketChat/Rocket.Chat/pull/22312)) - Added 2 new settings: - - `Admin > Video Conference > Big Blue Button > Enable for teams` + Added 2 new settings: + + - `Admin > Video Conference > Big Blue Button > Enable for teams` + - `Admin > Video Conference > Jitsi > Enable in teams` - Add debouncing to units selects filters ([#22097](https://github.com/RocketChat/Rocket.Chat/pull/22097)) - Add modal to close chats when tags/comments are not required ([#22245](https://github.com/RocketChat/Rocket.Chat/pull/22245) by [@rafaelblink](https://github.com/rafaelblink)) - When neither tags or comments are required to close a livechat, show this modal instead: + When neither tags or comments are required to close a livechat, show this modal instead: ![Screen Shot 2021-05-20 at 7 33 19 PM](https://user-images.githubusercontent.com/20868078/119057741-6af23c80-b9a3-11eb-902f-f8a7458ad11c.png) - Fallback messages on contextual bar ([#22376](https://github.com/RocketChat/Rocket.Chat/pull/22376)) @@ -1929,10 +1997,10 @@ - Remove differentiation between public x private channels in sidebar ([#22160](https://github.com/RocketChat/Rocket.Chat/pull/22160)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/119752184-e7d55880-be72-11eb-9167-be2f305ddb3f.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/119752184-e7d55880-be72-11eb-9167-be2f305ddb3f.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/119752125-c8d6c680-be72-11eb-8444-2e0c7cb1c600.png) - Rewrite create direct modal ([#22209](https://github.com/RocketChat/Rocket.Chat/pull/22209)) @@ -1941,8 +2009,8 @@ - Rewrite Create Discussion Modal (only through sidebar) ([#22224](https://github.com/RocketChat/Rocket.Chat/pull/22224)) - This is only available by creating a new discussion when clicking on the sidebar button. Other places will be implemented afterwards. - + This is only available by creating a new discussion when clicking on the sidebar button. Other places will be implemented afterwards. + ![image](https://user-images.githubusercontent.com/40830821/120556093-6af63180-c3d2-11eb-97ea-63c5423049dc.png) - Send only relevant data via WebSocket ([#22258](https://github.com/RocketChat/Rocket.Chat/pull/22258)) @@ -1956,12 +2024,12 @@ - **EE:** Canned responses can't be deleted ([#22095](https://github.com/RocketChat/Rocket.Chat/pull/22095) by [@rafaelblink](https://github.com/rafaelblink)) - Deletion button has been removed from the edition option. - - ## Before - ![image](https://user-images.githubusercontent.com/2493803/119059416-9f1b2c80-b9a6-11eb-933a-4efa1ac0552a.png) - - ### After + Deletion button has been removed from the edition option. + + ## Before + ![image](https://user-images.githubusercontent.com/2493803/119059416-9f1b2c80-b9a6-11eb-933a-4efa1ac0552a.png) + + ### After ![Rocket Chat (2)](https://user-images.githubusercontent.com/2493803/119172517-72b1ef80-ba3c-11eb-9178-04a12176f312.gif) - **ENTERPRISE:** Omnichannel enterprise permissions being added back to its default roles ([#22322](https://github.com/RocketChat/Rocket.Chat/pull/22322)) @@ -1970,19 +2038,19 @@ - **ENTERPRISE:** Prevent Visitor Abandonment after forwarding chat ([#22243](https://github.com/RocketChat/Rocket.Chat/pull/22243)) - Currently the Visitor Abandonment timer isn't affected when the chat is forwarded. However this is affecting the UX in certain situations like eg: A bot forwarding a chat to an human agent - ![image](https://user-images.githubusercontent.com/34130764/120896383-e4925780-c63e-11eb-937e-ffd7c4836159.png) - + Currently the Visitor Abandonment timer isn't affected when the chat is forwarded. However this is affecting the UX in certain situations like eg: A bot forwarding a chat to an human agent + ![image](https://user-images.githubusercontent.com/34130764/120896383-e4925780-c63e-11eb-937e-ffd7c4836159.png) + To solve this issue, we'll now be stoping the Visitor Abandonment timer once a chat is forwarded. - **IMPROVE:** Prevent creation of duplicated roles and new `roles.update` endpoint ([#22279](https://github.com/RocketChat/Rocket.Chat/pull/22279) by [@lucassartor](https://github.com/lucassartor)) - Currently, the action of updating a role is broken: because roles have their `_id` = `name`, when updating a role there's no way to validate if the user is trying to update or create a new role with a name that already exists - which causes wrong behaviors, such as roles with the same name and not being able to update them. - - To proper fix this, this PR looks to change the creation of roles. Now, roles have a unique `_id` value and there's a endpoint to update roles: `/api/v1/roles.update`. - - Doing so, it's possible to validate on both endpoints (`roles.create` and `roles.update`) to not allow roles with duplicated names. - + Currently, the action of updating a role is broken: because roles have their `_id` = `name`, when updating a role there's no way to validate if the user is trying to update or create a new role with a name that already exists - which causes wrong behaviors, such as roles with the same name and not being able to update them. + + To proper fix this, this PR looks to change the creation of roles. Now, roles have a unique `_id` value and there's a endpoint to update roles: `/api/v1/roles.update`. + + Doing so, it's possible to validate on both endpoints (`roles.create` and `roles.update`) to not allow roles with duplicated names. + **OBS:** The unique id changes only reflect new roles, the standard roles (such as admin and user) still have `_id` = `name`, but new roles now **can't** have the same name as them. - `channels.history`, `groups.history` and `im.history` REST endpoints not respecting hide system message config ([#22364](https://github.com/RocketChat/Rocket.Chat/pull/22364)) @@ -1999,10 +2067,10 @@ - Can't delete file from Room's file list ([#22191](https://github.com/RocketChat/Rocket.Chat/pull/22191)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/120215931-bb239700-c20c-11eb-9494-d4bc017df390.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/120215931-bb239700-c20c-11eb-9494-d4bc017df390.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/120216113-f8882480-c20c-11eb-9afb-b127e66a43da.png) - Cancel button and success toast at Leave Team modal ([#22373](https://github.com/RocketChat/Rocket.Chat/pull/22373)) @@ -2013,10 +2081,10 @@ - Convert and Move team permission ([#22350](https://github.com/RocketChat/Rocket.Chat/pull/22350)) - ### before - https://user-images.githubusercontent.com/45966964/114909360-5c04f100-9e1d-11eb-9363-f308e5d0be68.mp4 - - ### after + ### before + https://user-images.githubusercontent.com/45966964/114909360-5c04f100-9e1d-11eb-9363-f308e5d0be68.mp4 + + ### after https://user-images.githubusercontent.com/45966964/114909388-61fad200-9e1d-11eb-9bbe-114b55954a9f.mp4 - CORS error while interacting with any action button on Livechat ([#22150](https://github.com/RocketChat/Rocket.Chat/pull/22150)) @@ -2035,50 +2103,50 @@ - Members tab visual issues ([#22138](https://github.com/RocketChat/Rocket.Chat/pull/22138)) - ## Before - ![image](https://user-images.githubusercontent.com/27704687/119558283-95fbd800-bd77-11eb-91b4-91821f365bf3.png) - - ## After + ## Before + ![image](https://user-images.githubusercontent.com/27704687/119558283-95fbd800-bd77-11eb-91b4-91821f365bf3.png) + + ## After ![image](https://user-images.githubusercontent.com/27704687/119558120-6947c080-bd77-11eb-8ecb-7fedc07afa82.png) - Memory leak generated by Stream Cast usage ([#22329](https://github.com/RocketChat/Rocket.Chat/pull/22329)) - Stream Cast uses a different approach to broadcast data to the instances, it uses the DDP subscription method that requires a collection on the other side, if no collection exists with the given name `broadcast-stream` it caches in memory waiting for the collection to be set later. The cache is cleared only when a reconnection happens. - + Stream Cast uses a different approach to broadcast data to the instances, it uses the DDP subscription method that requires a collection on the other side, if no collection exists with the given name `broadcast-stream` it caches in memory waiting for the collection to be set later. The cache is cleared only when a reconnection happens. + This PR overrides the function that processes the data for that specific connection, preventing the cache and everything else to be processed since we already have our low-level listener to process the data. - Message box hiding on mobile view (Safari) ([#22212](https://github.com/RocketChat/Rocket.Chat/pull/22212)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/120404256-5b1c1600-c31c-11eb-96e9-860e4132db5f.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/120404256-5b1c1600-c31c-11eb-96e9-860e4132db5f.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/120404406-acc4a080-c31c-11eb-9efb-c2ad88664fda.png) - Missing burger menu on direct messages ([#22211](https://github.com/RocketChat/Rocket.Chat/pull/22211)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/120403671-09bf5700-c31b-11eb-92a1-a2f589bd85fc.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/120403671-09bf5700-c31b-11eb-92a1-a2f589bd85fc.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/120403693-1643af80-c31b-11eb-8027-dbdc4f560647.png) - Missing Throbber while thread list is loading ([#22316](https://github.com/RocketChat/Rocket.Chat/pull/22316)) - ### before - List was starting with no results even if there's results: - - ![image](https://user-images.githubusercontent.com/27704687/121606744-1e8ba100-ca25-11eb-9b31-706fb998d05f.png) - - ### after + ### before + List was starting with no results even if there's results: + + ![image](https://user-images.githubusercontent.com/27704687/121606744-1e8ba100-ca25-11eb-9b31-706fb998d05f.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/121606635-e97f4e80-ca24-11eb-81f7-af8b0cc41c89.png) - Not possible to edit some messages inside threads ([#22325](https://github.com/RocketChat/Rocket.Chat/pull/22325)) - ### Before - ![before](https://user-images.githubusercontent.com/27704687/121755733-4eeb4200-caee-11eb-9d77-1b498c38c478.gif) - - ### After + ### Before + ![before](https://user-images.githubusercontent.com/27704687/121755733-4eeb4200-caee-11eb-9d77-1b498c38c478.gif) + + ### After ![after](https://user-images.githubusercontent.com/27704687/121755736-514d9c00-caee-11eb-9897-78fcead172f2.gif) - Notifications not using user's name ([#22309](https://github.com/RocketChat/Rocket.Chat/pull/22309)) @@ -2105,10 +2173,10 @@ - Sidebar not closing when clicking on a channel ([#22271](https://github.com/RocketChat/Rocket.Chat/pull/22271)) - ### before - ![before](https://user-images.githubusercontent.com/27704687/121074843-c6e20100-c7aa-11eb-88db-76e39b57b064.gif) - - ### after + ### before + ![before](https://user-images.githubusercontent.com/27704687/121074843-c6e20100-c7aa-11eb-88db-76e39b57b064.gif) + + ### after ![after](https://user-images.githubusercontent.com/27704687/121074860-cb0e1e80-c7aa-11eb-9e96-06d75044b763.gif) - Sound notification is not emitted when the Omnichannel chat comes from another department ([#22291](https://github.com/RocketChat/Rocket.Chat/pull/22291)) @@ -2119,9 +2187,9 @@ - Undefined error when forwarding chats to offline department ([#22154](https://github.com/RocketChat/Rocket.Chat/pull/22154) by [@rafaelblink](https://github.com/rafaelblink)) - ![Screen Shot 2021-05-26 at 5 29 17 PM](https://user-images.githubusercontent.com/59577424/119727520-c495b380-be48-11eb-88a2-158017c7ad0a.png) - - Omnichannel agents are facing the error shown above when forwarding chats to offline departments. + ![Screen Shot 2021-05-26 at 5 29 17 PM](https://user-images.githubusercontent.com/59577424/119727520-c495b380-be48-11eb-88a2-158017c7ad0a.png) + + Omnichannel agents are facing the error shown above when forwarding chats to offline departments. The error usually takes place when the routing system algorithm is **Manual Selection**. - Unread bar in channel flash quickly and then disappear ([#22275](https://github.com/RocketChat/Rocket.Chat/pull/22275)) @@ -2152,15 +2220,15 @@ - Chore: Change modals for remove user from team && leave team ([#22141](https://github.com/RocketChat/Rocket.Chat/pull/22141)) - ![image](https://user-images.githubusercontent.com/40830821/119576154-93f14380-bd8e-11eb-8885-f889f2939bf4.png) + ![image](https://user-images.githubusercontent.com/40830821/119576154-93f14380-bd8e-11eb-8885-f889f2939bf4.png) ![image](https://user-images.githubusercontent.com/40830821/119576219-b5eac600-bd8e-11eb-832c-ea7a17a56bdd.png) - Chore: Check PR Title on every submission ([#22140](https://github.com/RocketChat/Rocket.Chat/pull/22140)) - Chore: Enable push gateway only if the server is registered ([#22346](https://github.com/RocketChat/Rocket.Chat/pull/22346) by [@lucassartor](https://github.com/lucassartor)) - Currently, when creating an unregistered server, the default value of the push gateway setting is set to true and is disabled (it can't be changed unless the server is registered). This is a wrong behavior as an unregistered server **can't** use the push gateway. - + Currently, when creating an unregistered server, the default value of the push gateway setting is set to true and is disabled (it can't be changed unless the server is registered). This is a wrong behavior as an unregistered server **can't** use the push gateway. + This PR creates a validation to check if the server is registered when enabling the push gateway. That way, even if the push gateway setting is turned on, but the server is unregistered, the push gateway **won't** work - it will behave like it is off. - Chore: Enforce TypeScript on Storybook ([#22317](https://github.com/RocketChat/Rocket.Chat/pull/22317)) @@ -2177,7 +2245,7 @@ - Chore: Update delete team modal to new design ([#22127](https://github.com/RocketChat/Rocket.Chat/pull/22127)) - Now the modal has only 2 steps (steps 1 and 2 were merged) + Now the modal has only 2 steps (steps 1 and 2 were merged) ![image](https://user-images.githubusercontent.com/40830821/119414580-2e398480-bcc6-11eb-9a47-515568257974.png) - Language update from LingoHub ๐Ÿค– on 2021-05-31Z ([#22196](https://github.com/RocketChat/Rocket.Chat/pull/22196)) @@ -2204,10 +2272,10 @@ - Regression: Missing flexDirection on select field ([#22300](https://github.com/RocketChat/Rocket.Chat/pull/22300)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/121425905-532a2a80-c949-11eb-885f-e8ddaf5c8d5c.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/121425905-532a2a80-c949-11eb-885f-e8ddaf5c8d5c.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/121425770-283fd680-c949-11eb-8d94-86886f174599.png) - Regression: RoomProvider using wrong types ([#22370](https://github.com/RocketChat/Rocket.Chat/pull/22370)) @@ -2348,50 +2416,50 @@ - **ENTERPRISE:** Introduce Load Rotation routing algorithm for Omnichannel ([#22090](https://github.com/RocketChat/Rocket.Chat/pull/22090) by [@rafaelblink](https://github.com/rafaelblink)) - This PR introduces a new Auto Chat Distribution (ACD) algorithm for Omnichannel: **Load Rotation**. - The algorithm distributes chats to agents one by one, which means that when a new chat arrives, the agent with the oldest routing assignment time will be selected to serve the chat, regardless of the number of chats in progress each agent has. - + This PR introduces a new Auto Chat Distribution (ACD) algorithm for Omnichannel: **Load Rotation**. + The algorithm distributes chats to agents one by one, which means that when a new chat arrives, the agent with the oldest routing assignment time will be selected to serve the chat, regardless of the number of chats in progress each agent has. + ![Screen Shot 2021-05-20 at 5 17 40 PM](https://user-images.githubusercontent.com/59577424/119043752-c61a3400-b98f-11eb-8543-f3176879af1d.png) - Back button for Omnichannel ([#21647](https://github.com/RocketChat/Rocket.Chat/pull/21647) by [@rafaelblink](https://github.com/rafaelblink)) - New Message Parser ([#21962](https://github.com/RocketChat/Rocket.Chat/pull/21962)) - The objective is to put an end to the confusion that we face having multiple parsers, and the problems that this brings, it is still experimental then users need to choose to use it. - - The benefits are multiple. no more unexpected cases or grammatical collisions (in addition to more flexible nested cases like bold within link labels). - Besides, we no longer render raw html, instead we use components, so the xss attacks are over (the easy ones at least). Without further discoveries and at the fronted, we only reder what is delivered thus improving our performance. + The objective is to put an end to the confusion that we face having multiple parsers, and the problems that this brings, it is still experimental then users need to choose to use it. + + The benefits are multiple. no more unexpected cases or grammatical collisions (in addition to more flexible nested cases like bold within link labels). + Besides, we no longer render raw html, instead we use components, so the xss attacks are over (the easy ones at least). Without further discoveries and at the fronted, we only reder what is delivered thus improving our performance. This can be used in multiple places, (message, alert, sidenav and in the entire mobile application.) - Option to notify failed login attempts to a channel ([#21968](https://github.com/RocketChat/Rocket.Chat/pull/21968)) - Option to prevent users from using Invisible status ([#20084](https://github.com/RocketChat/Rocket.Chat/pull/20084) by [@lucassartor](https://github.com/lucassartor)) - Add an `admin` option to allow/disallow the `Invisible` status option from all users. This option is available in the `Accounts` section. - - ![2021-01-06-11-55-22](https://user-images.githubusercontent.com/49413772/103782988-ebc52300-5016-11eb-8a29-dd540c21e11c.gif) - - If the option is turned off, the `users.setStatus` endpoint is also restricted from users trying to change their status to `Invisible`, throwing the following error: - ```json - { - "success": false, - "error": "Invisible status is disabled [error-not-allowed]", - "stack": "Error: Invisible status is disabled [error-not-allowed]\n at DDPCommon.MethodInvocation. (app/api/server/v1/users.js:425:13)\n at packages/dispatch_run-as-user.js:211:14\n at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1234:12)\n at Object.Meteor.runAsUser (packages/dispatch_run-as-user.js:210:33)\n at Object.post (app/api/server/v1/users.js:415:10)\n at app/api/server/api.js:394:82\n at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1234:12)\n at Object._internalRouteActionHandler [as action] (app/api/server/api.js:394:39)\n at Route.share.Route.Route._callEndpoint (packages/nimble_restivus/lib/route.coffee:150:32)\n at packages/nimble_restivus/lib/route.coffee:59:33\n at packages/simple_json-routes.js:98:9", - "errorType": "error-not-allowed", - "details": { - "method": "users.setStatus" - } - } + Add an `admin` option to allow/disallow the `Invisible` status option from all users. This option is available in the `Accounts` section. + + ![2021-01-06-11-55-22](https://user-images.githubusercontent.com/49413772/103782988-ebc52300-5016-11eb-8a29-dd540c21e11c.gif) + + If the option is turned off, the `users.setStatus` endpoint is also restricted from users trying to change their status to `Invisible`, throwing the following error: + ```json + { + "success": false, + "error": "Invisible status is disabled [error-not-allowed]", + "stack": "Error: Invisible status is disabled [error-not-allowed]\n at DDPCommon.MethodInvocation. (app/api/server/v1/users.js:425:13)\n at packages/dispatch_run-as-user.js:211:14\n at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1234:12)\n at Object.Meteor.runAsUser (packages/dispatch_run-as-user.js:210:33)\n at Object.post (app/api/server/v1/users.js:415:10)\n at app/api/server/api.js:394:82\n at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1234:12)\n at Object._internalRouteActionHandler [as action] (app/api/server/api.js:394:39)\n at Route.share.Route.Route._callEndpoint (packages/nimble_restivus/lib/route.coffee:150:32)\n at packages/nimble_restivus/lib/route.coffee:59:33\n at packages/simple_json-routes.js:98:9", + "errorType": "error-not-allowed", + "details": { + "method": "users.setStatus" + } + } ``` - Paginated and Filtered selects on new/edit unit ([#22052](https://github.com/RocketChat/Rocket.Chat/pull/22052) by [@rafaelblink](https://github.com/rafaelblink)) - REQUIRES https://github.com/RocketChat/Rocket.Chat.Fuselage/pull/447 - - Adds infinite scrolling selects to the units edit/create with the ability to be filtered by text as well - - ![Screen Shot 2021-05-17 at 9 24 19 AM](https://user-images.githubusercontent.com/20868078/118487999-abc32a80-b6f1-11eb-8d58-d031111ea0fb.png) - + REQUIRES https://github.com/RocketChat/Rocket.Chat.Fuselage/pull/447 + + Adds infinite scrolling selects to the units edit/create with the ability to be filtered by text as well + + ![Screen Shot 2021-05-17 at 9 24 19 AM](https://user-images.githubusercontent.com/20868078/118487999-abc32a80-b6f1-11eb-8d58-d031111ea0fb.png) + This Affects the monitors and departments inputs - Remove exif metadata from uploaded files ([#22044](https://github.com/RocketChat/Rocket.Chat/pull/22044)) @@ -2419,13 +2487,17 @@ - Inconsistent and misleading 2FA settings ([#22042](https://github.com/RocketChat/Rocket.Chat/pull/22042) by [@lucassartor](https://github.com/lucassartor)) - Currently, there are some inconsistencies and incorrect behaviors on the 2FA settings, such as: - - - When disabling the TOTP 2FA, all 2FA are disabled; - - There are no option to disable only the TOTP 2FA; - - If 2FA are disabled, the other settings aren't blocked (the e-mail 2FA setting, for example); - - It lacks some labels to warn the user of some specific 2FA options. - + Currently, there are some inconsistencies and incorrect behaviors on the 2FA settings, such as: + + + - When disabling the TOTP 2FA, all 2FA are disabled; + + - There are no option to disable only the TOTP 2FA; + + - If 2FA are disabled, the other settings aren't blocked (the e-mail 2FA setting, for example); + + - It lacks some labels to warn the user of some specific 2FA options. + This PR looks to fix those issues. - LDAP port setting input type to allow only numbers ([#21912](https://github.com/RocketChat/Rocket.Chat/pull/21912) by [@Deepak-learner](https://github.com/Deepak-learner)) @@ -2447,16 +2519,16 @@ - **APPS:** Scheduler duplicating recurrent tasks after server restart ([#21866](https://github.com/RocketChat/Rocket.Chat/pull/21866)) - Reintroduces the old method for creating recurring tasks in the apps' scheduler bridge to ensure tasks won't be duplicated. - - By introducing the [`skipImmediate` property option](https://github.com/RocketChat/Rocket.Chat/pull/21353) at the [`scheduleRecurring`](https://github.com/RocketChat/Rocket.Chat/blob/f8171f464ed8a7487795651767695fb33a1c709e/app/apps/server/bridges/scheduler.js#L119) method, the `every` method from _agenda.js_, which ensured no duplicates were created, was removed in favor of a more manual procedure. The new procedure was not taking into account the management of duplicates and as a result multiple copies of the same task could be created and they would get executed at the same time. - + Reintroduces the old method for creating recurring tasks in the apps' scheduler bridge to ensure tasks won't be duplicated. + + By introducing the [`skipImmediate` property option](https://github.com/RocketChat/Rocket.Chat/pull/21353) at the [`scheduleRecurring`](https://github.com/RocketChat/Rocket.Chat/blob/f8171f464ed8a7487795651767695fb33a1c709e/app/apps/server/bridges/scheduler.js#L119) method, the `every` method from _agenda.js_, which ensured no duplicates were created, was removed in favor of a more manual procedure. The new procedure was not taking into account the management of duplicates and as a result multiple copies of the same task could be created and they would get executed at the same time. + In the case of server restarts, every time this event happened and the app had the `startupSetting` configured to use _recurring tasks_, they would get recreated the same number of times. In the case of a server that restarts frequently (_n_ times), there would be the same (_n_) number of tasks duplicated (and running) in the system. - **ENTERPRISE:** Omnichannel Monitors can't forward chats to departments that they are not supervising ([#22128](https://github.com/RocketChat/Rocket.Chat/pull/22128)) - Currently, Omnichannel Monitors just can't forward chats to a department that is part of a `Business Unit` they're not supervising. This issue is causing critical problems on customer operations since this behaviour is not by design. - The reason this issue is taking place is that, by design, Monitors just have access to departments related to the `Business Units` they're monitoring, but this restriction is designed only for Omnichannel management areas, which means in case the monitor is, also, an agent, they're supposed to be able to forward a chat to any available departments regardless the `Business Units` it's associated with. + Currently, Omnichannel Monitors just can't forward chats to a department that is part of a `Business Unit` they're not supervising. This issue is causing critical problems on customer operations since this behaviour is not by design. + The reason this issue is taking place is that, by design, Monitors just have access to departments related to the `Business Units` they're monitoring, but this restriction is designed only for Omnichannel management areas, which means in case the monitor is, also, an agent, they're supposed to be able to forward a chat to any available departments regardless the `Business Units` it's associated with. So, initially, the restriction was implemented on the `Department Model` and, now, we're implementing the logic properly and introducing a new parameter to department endpoints, so the client will define which type of departments it needs. - **ENTERPRISE:** Omnichannel Monitors can't forward chats to departments that they are not supervising ([#22142](https://github.com/RocketChat/Rocket.Chat/pull/22142)) @@ -2495,18 +2567,18 @@ - Correcting a the wrong Archived label in edit room ([#21717](https://github.com/RocketChat/Rocket.Chat/pull/21717) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - ![image](https://user-images.githubusercontent.com/45966964/116584997-3cd78a80-a918-11eb-81fa-8a7eb5318ae9.png) - + ![image](https://user-images.githubusercontent.com/45966964/116584997-3cd78a80-a918-11eb-81fa-8a7eb5318ae9.png) + A label exists for Archived, and it has not been used. So I replaced it with the existing one. the label 'Archived' does not exist. - Custom OAuth not being completely deleted ([#21637](https://github.com/RocketChat/Rocket.Chat/pull/21637) by [@siva2204](https://github.com/siva2204)) - Directory Table's Sort Function ([#21921](https://github.com/RocketChat/Rocket.Chat/pull/21921)) - ### TableRow Margin Issue: - ![image](https://user-images.githubusercontent.com/27704687/116907348-d6a07f80-ac17-11eb-9411-edfe0906bfe1.png) - - ### Table Sort Action Issue: + ### TableRow Margin Issue: + ![image](https://user-images.githubusercontent.com/27704687/116907348-d6a07f80-ac17-11eb-9411-edfe0906bfe1.png) + + ### Table Sort Action Issue: ![directory](https://user-images.githubusercontent.com/27704687/116907441-f20b8a80-ac17-11eb-8790-bfce19e89a67.gif) - Discussion names showing a random value ([#22172](https://github.com/RocketChat/Rocket.Chat/pull/22172)) @@ -2517,54 +2589,54 @@ - Emails being sent with HTML entities getting escaped multiple times ([#21994](https://github.com/RocketChat/Rocket.Chat/pull/21994) by [@bhavayAnand9](https://github.com/bhavayAnand9)) - fixes an issue where if password contains special HTML character like &, in the email it would end up something like `&amp;` - - - password was going through multiple escapeHTML function calls - `secure&123 => secure&123 => secure&amp;123 + fixes an issue where if password contains special HTML character like &, in the email it would end up something like `&amp;` + + + password was going through multiple escapeHTML function calls + `secure&123 => secure&123 => secure&amp;123 ` - Error when you look at the members list of a room in which you are not a member ([#21952](https://github.com/RocketChat/Rocket.Chat/pull/21952) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - Before, when you look at the members of a room in which you are not a member the app crashed, i corrected this problem. - Indeed, there was a check on each currentSubscription. to see if it was not undefined except on currentSubscription.blocker - + Before, when you look at the members of a room in which you are not a member the app crashed, i corrected this problem. + Indeed, there was a check on each currentSubscription. to see if it was not undefined except on currentSubscription.blocker + https://user-images.githubusercontent.com/45966964/117087470-d3101400-ad4f-11eb-8f44-0ebca830a4d8.mp4 - errors when viewing a room that you're not subscribed to ([#21984](https://github.com/RocketChat/Rocket.Chat/pull/21984)) - Files list will not show deleted files. ([#21732](https://github.com/RocketChat/Rocket.Chat/pull/21732) by [@Darshilp326](https://github.com/Darshilp326)) - When you delete files from the header option, deleted files will not be shown. - + When you delete files from the header option, deleted files will not be shown. + https://user-images.githubusercontent.com/55157259/115730786-38552400-a3a4-11eb-9684-7f510920db66.mp4 - Fixed the fact that when a team was deleted, not all channels were unlinked from the team ([#21942](https://github.com/RocketChat/Rocket.Chat/pull/21942) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - Fixed the fact that when a team was deleted, not all channels were unlinked from the team. Only the first room of the rooms list was unlinked. - - After the fix, there is nos more errors: - - + Fixed the fact that when a team was deleted, not all channels were unlinked from the team. Only the first room of the rooms list was unlinked. + + After the fix, there is nos more errors: + + https://user-images.githubusercontent.com/45966964/117055182-2a47c180-ad1b-11eb-806f-07fb3fa7ec12.mp4 - Fixing Jitsi call ended Issue. ([#21808](https://github.com/RocketChat/Rocket.Chat/pull/21808)) - The new rewrite in react of contextual call component broke the Jitsi "click to join" messages. The issue being after 10 seconds of initiating the call, the message "click to join" always returned "Call Ended" even if the call was still going on. - This was due to the fact that after closing the contextual bar, the react component gets unmounted and we are not able to keep track of ongoing call and increase jitsi room timeout. - - This PR solves this issue by using the setInterval methods on component will unmount. When the call component unmounts, we keep on checking the state of jitsi call and based on conditions increase the jitsi room timeout. After the call is ended all setInterval calls are closed. - + The new rewrite in react of contextual call component broke the Jitsi "click to join" messages. The issue being after 10 seconds of initiating the call, the message "click to join" always returned "Call Ended" even if the call was still going on. + This was due to the fact that after closing the contextual bar, the react component gets unmounted and we are not able to keep track of ongoing call and increase jitsi room timeout. + + This PR solves this issue by using the setInterval methods on component will unmount. When the call component unmounts, we keep on checking the state of jitsi call and based on conditions increase the jitsi room timeout. After the call is ended all setInterval calls are closed. + This PR also removes the implementation of HEARTBEAT events of JitsiBridge. This is because this is no longer needed and all logic is being taken care of by the unmount function. - Handle NPS errors instead of throwing them ([#21945](https://github.com/RocketChat/Rocket.Chat/pull/21945)) - Header Tag Visual Issues ([#21991](https://github.com/RocketChat/Rocket.Chat/pull/21991)) - ### Normal - ![image](https://user-images.githubusercontent.com/27704687/117504793-69635600-af59-11eb-8b79-9d8f631490ee.png) - - ### Hover + ### Normal + ![image](https://user-images.githubusercontent.com/27704687/117504793-69635600-af59-11eb-8b79-9d8f631490ee.png) + + ### Hover ![image](https://user-images.githubusercontent.com/27704687/117504934-97489a80-af59-11eb-87c3-0a62731e9ce3.png) - Horizontal scrollbar not showing on tables ([#21852](https://github.com/RocketChat/Rocket.Chat/pull/21852)) @@ -2573,17 +2645,17 @@ - iFrame size on embedded videos ([#21992](https://github.com/RocketChat/Rocket.Chat/pull/21992)) - ### Before - ![image](https://user-images.githubusercontent.com/27704687/117508802-8bf86d80-af5f-11eb-9eb8-29e55b73eac5.png) - - ### After + ### Before + ![image](https://user-images.githubusercontent.com/27704687/117508802-8bf86d80-af5f-11eb-9eb8-29e55b73eac5.png) + + ### After ![image](https://user-images.githubusercontent.com/27704687/117508870-a4688800-af5f-11eb-9176-7f24de5fc424.png) - Incorrect error message when opening channel in anonymous read ([#22066](https://github.com/RocketChat/Rocket.Chat/pull/22066) by [@lucassartor](https://github.com/lucassartor)) - Every time you open a public channel with threads in it when using anonymous read an `Incorrect User` error will be thrown. - This is an incorrect behaviour as everything that is public should be valid for an anonymous user. - + Every time you open a public channel with threads in it when using anonymous read an `Incorrect User` error will be thrown. + This is an incorrect behaviour as everything that is public should be valid for an anonymous user. + Some files are adapted to that and have already removed this kind of incorrect error, but there are some that need some fix, this PR aims to do that. - Incorrect Team's Info spacing ([#22021](https://github.com/RocketChat/Rocket.Chat/pull/22021)) @@ -2596,19 +2668,21 @@ - Make the FR translation consistent with the 'room' translation + typos ([#21913](https://github.com/RocketChat/Rocket.Chat/pull/21913) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - In the FR translation files, there were two terms that were used to refer to **'room'**: - - 'salon' (149 times used) - - ![image](https://user-images.githubusercontent.com/45966964/116829860-ac62a980-aba6-11eb-8212-e6f15ed0af82.png) - - - 'salle' (46 times used) - - ![image](https://user-images.githubusercontent.com/45966964/116829871-be444c80-aba6-11eb-9b42-e213fee6586a.png) - - The problem is that both were used in the same context and sometimes even in the same option list. - However, since 'salon' is a better translation and was also in the majority, I used the translation 'salon' wherever 'salle' was marked. - - For example: + In the FR translation files, there were two terms that were used to refer to **'room'**: + + - 'salon' (149 times used) + + ![image](https://user-images.githubusercontent.com/45966964/116829860-ac62a980-aba6-11eb-8212-e6f15ed0af82.png) + + + - 'salle' (46 times used) + + ![image](https://user-images.githubusercontent.com/45966964/116829871-be444c80-aba6-11eb-9b42-e213fee6586a.png) + + The problem is that both were used in the same context and sometimes even in the same option list. + However, since 'salon' is a better translation and was also in the majority, I used the translation 'salon' wherever 'salle' was marked. + + For example: ![image](https://user-images.githubusercontent.com/45966964/116830523-1da45b80-abab-11eb-81f8-5225d51cecc6.png) - Maximum 25 channels can be loaded in the teams' channels list ([#21708](https://github.com/RocketChat/Rocket.Chat/pull/21708) by [@Jeanstaquet](https://github.com/Jeanstaquet)) @@ -2623,8 +2697,8 @@ - No warning message is sent when user is removed from a team's main channel ([#21949](https://github.com/RocketChat/Rocket.Chat/pull/21949)) - - Send a warning message to a team's main channel when a user is removed from the team; - - Trigger events while removing a user from a team's main channel; + - Send a warning message to a team's main channel when a user is removed from the team; + - Trigger events while removing a user from a team's main channel; - Fix `usersCount` field in the team's main room when a user is removed from the team (`usersCount` is now decreased by 1). - Not possible accept video call if "Hide right sidebar with click" is enabled ([#22175](https://github.com/RocketChat/Rocket.Chat/pull/22175)) @@ -2645,14 +2719,14 @@ - Prevent the userInfo tab to return 'User not found' each time if a certain member of a DM group has been deleted ([#21970](https://github.com/RocketChat/Rocket.Chat/pull/21970) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - Prevent the userInfo tab to return 'User not found' if a member of a DM group has been deleted. - This happens if the user that has been deleted is the one originally displayed on the userInfo tab in a DM group with >2 users. - + Prevent the userInfo tab to return 'User not found' if a member of a DM group has been deleted. + This happens if the user that has been deleted is the one originally displayed on the userInfo tab in a DM group with >2 users. + https://user-images.githubusercontent.com/45966964/117221081-db785580-ae08-11eb-9b33-2314a99eb037.mp4 - Prune messages not cleaning up unread threads ([#21326](https://github.com/RocketChat/Rocket.Chat/pull/21326) by [@renancleyson-dev](https://github.com/renancleyson-dev)) - Fixes permanent unread messages when admin prune at least two different thread messages in the room that were unread by some user. + Fixes permanent unread messages when admin prune at least two different thread messages in the room that were unread by some user. ![screencapture-localhost-3000-channel-general-thread-2021-03-26-13_17_16](https://user-images.githubusercontent.com/43624243/112678973-62b9cd00-8e4a-11eb-9af9-56f17cc66baf.png) - Redirect on remove user from channel by user profile tab ([#21951](https://github.com/RocketChat/Rocket.Chat/pull/21951)) @@ -2663,8 +2737,8 @@ - Removed fields from User Info for which the user doesn't have permissions. ([#20923](https://github.com/RocketChat/Rocket.Chat/pull/20923) by [@Darshilp326](https://github.com/Darshilp326)) - Removed LastLogin, CreatedAt and Roles for users who don't have permission. - + Removed LastLogin, CreatedAt and Roles for users who don't have permission. + https://user-images.githubusercontent.com/55157259/109381351-f2c62e80-78ff-11eb-9289-e11072bf62f8.mp4 - Replace `query` param by `name`, `username` and `status` on the `teams.members` endpoint ([#21539](https://github.com/RocketChat/Rocket.Chat/pull/21539)) @@ -2677,39 +2751,39 @@ - Unable to edit a 'direct' room setting in the admin due to the room name ([#21636](https://github.com/RocketChat/Rocket.Chat/pull/21636) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - When you are in the admin and want to change a room 'd' setting, it doesn't work because it takes into account the name that is set automatically and therefore tries to save that name. Since the name is not valid and should not be registered, we cannot change the setting for the 'd' room. - I made sure that when you want to change a setting in a 'd' room, that you don't take the name into account - - - https://user-images.githubusercontent.com/45966964/115150919-cd85af00-a06a-11eb-9667-ef3dcfc5adb6.mp4 - - + When you are in the admin and want to change a room 'd' setting, it doesn't work because it takes into account the name that is set automatically and therefore tries to save that name. Since the name is not valid and should not be registered, we cannot change the setting for the 'd' room. + I made sure that when you want to change a setting in a 'd' room, that you don't take the name into account + + + https://user-images.githubusercontent.com/45966964/115150919-cd85af00-a06a-11eb-9667-ef3dcfc5adb6.mp4 + + Behind the scene, the name is not saved - Unable to edit a user who does not have an email via the admin or via the user's profile ([#21626](https://github.com/RocketChat/Rocket.Chat/pull/21626) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - If a user does not have an email address, they cannot change it via their profile or via the admin. I fixed this issue. I have created several profiles and there was one that didn't have an email, I don't know how I did it, I am working on it. I had not modified the db to delete his email, hence the fix - - in admin - - https://user-images.githubusercontent.com/45966964/115112617-9b9b1c80-9f86-11eb-8e3a-950c3c1a1746.mp4 - - - - in the user profile - + If a user does not have an email address, they cannot change it via their profile or via the admin. I fixed this issue. I have created several profiles and there was one that didn't have an email, I don't know how I did it, I am working on it. I had not modified the db to delete his email, hence the fix + + in admin + + https://user-images.githubusercontent.com/45966964/115112617-9b9b1c80-9f86-11eb-8e3a-950c3c1a1746.mp4 + + + + in the user profile + https://user-images.githubusercontent.com/45966964/115112620-a0f86700-9f86-11eb-97b1-56eaba42216b.mp4 - Unable to get channels, sort by most recent message ([#21701](https://github.com/RocketChat/Rocket.Chat/pull/21701) by [@sumukhah](https://github.com/sumukhah)) - Unable to update app manually ([#21215](https://github.com/RocketChat/Rocket.Chat/pull/21215)) - It allows for update of apps using a zip file. - - When installing apps using the zip file, either by url or the file form, if the app was already installed, an error would be thrown stating the condition and forbidding the installation. Now, when sending a zip file of an app that is already installed, the user is presented with the following modal: - - ![2021-04-30-113936_627x235_scrot](https://user-images.githubusercontent.com/733282/116711383-2cbbbb80-a9a9-11eb-8c77-22d6802cb9f5.png) - + It allows for update of apps using a zip file. + + When installing apps using the zip file, either by url or the file form, if the app was already installed, an error would be thrown stating the condition and forbidding the installation. Now, when sending a zip file of an app that is already installed, the user is presented with the following modal: + + ![2021-04-30-113936_627x235_scrot](https://user-images.githubusercontent.com/733282/116711383-2cbbbb80-a9a9-11eb-8c77-22d6802cb9f5.png) + If the app also requires permissions to be reviewed, the modal that handles permission reviews will be shown after this one is accepted. - Unpin message reactivity ([#22029](https://github.com/RocketChat/Rocket.Chat/pull/22029)) @@ -2720,20 +2794,20 @@ - User Impersonation through sendMessage API ([#20391](https://github.com/RocketChat/Rocket.Chat/pull/20391) by [@lucassartor](https://github.com/lucassartor)) - Create a new permission: `message-impersonate`. For new installs only bot role will have the permission and for updating installs the permission will also be given to user role, so it won't break running deployments. - - If a message is being sent with `avatar` or `alias` properties, it validates if the sender has the `message-impersonate` permission, if not, an error is throwed: - ```json - { - "success": false, - "error": "Not enough permission", - "stack": "Error: Not enough permission\n ..." - } + Create a new permission: `message-impersonate`. For new installs only bot role will have the permission and for updating installs the permission will also be given to user role, so it won't break running deployments. + + If a message is being sent with `avatar` or `alias` properties, it validates if the sender has the `message-impersonate` permission, if not, an error is throwed: + ```json + { + "success": false, + "error": "Not enough permission", + "stack": "Error: Not enough permission\n ..." + } ``` - Visibility of burger menu on certain width ([#20736](https://github.com/RocketChat/Rocket.Chat/pull/20736) by [@yash-rajpal](https://github.com/yash-rajpal)) - Burger was not visible on a certain width, specifically between 600 to 780. if width is more than 780px sidebar is shown, if less than 600 then burger icon was shown. But it wasn't shown between 600px to 780 px. + Burger was not visible on a certain width, specifically between 600 to 780. if width is more than 780px sidebar is shown, if less than 600 then burger icon was shown. But it wasn't shown between 600px to 780 px. It was because for showing burger icon we were only checking for `isMobile` which is lenght only less than 600. So i added one more check for condition if length is less than 780 px. - When closing chats a comment is always required ([#21947](https://github.com/RocketChat/Rocket.Chat/pull/21947)) @@ -2748,8 +2822,8 @@ - Wrong icon on "Move to team" option in the channel info actions ([#21944](https://github.com/RocketChat/Rocket.Chat/pull/21944)) - ![image](https://user-images.githubusercontent.com/40830821/117061659-d9bf6c80-acf8-11eb-8e29-be47e702dedd.png) - + ![image](https://user-images.githubusercontent.com/40830821/117061659-d9bf6c80-acf8-11eb-8e29-be47e702dedd.png) + Depends on https://github.com/RocketChat/Rocket.Chat.Fuselage/pull/444
@@ -2766,8 +2840,10 @@ - Add two more test cases to the slash-command test suite ([#21317](https://github.com/RocketChat/Rocket.Chat/pull/21317) by [@EduardoPicolo](https://github.com/EduardoPicolo)) - Added two more test cases to the slash-command test suite: - - 'should return an error when the command does not exist''; + Added two more test cases to the slash-command test suite: + + - 'should return an error when the command does not exist''; + - 'should return an error when no command is provided'; - Bump actions/stale from v3.0.8 to v3.0.18 ([#21877](https://github.com/RocketChat/Rocket.Chat/pull/21877) by [@dependabot[bot]](https://github.com/dependabot[bot])) @@ -2802,9 +2878,9 @@ - i18n: Add missing translation string in account preference ([#21448](https://github.com/RocketChat/Rocket.Chat/pull/21448) by [@sumukhah](https://github.com/sumukhah)) - "Test Desktop Notifications" was missing in translation, Added to the file. - Screenshot 2021-04-05 at 3 58 01 PM - + "Test Desktop Notifications" was missing in translation, Added to the file. + Screenshot 2021-04-05 at 3 58 01 PM + Screenshot 2021-04-05 at 3 58 32 PM - i18n: Correct a typo in German ([#21711](https://github.com/RocketChat/Rocket.Chat/pull/21711) by [@Jeanstaquet](https://github.com/Jeanstaquet)) @@ -2831,10 +2907,10 @@ - Regression: discussions display on sidebar ([#22157](https://github.com/RocketChat/Rocket.Chat/pull/22157)) - ### group by type active - ![image](https://user-images.githubusercontent.com/27704687/119741996-37a92500-be5d-11eb-8b36-4067a7a229f1.png) - - ### group by type inactive + ### group by type active + ![image](https://user-images.githubusercontent.com/27704687/119741996-37a92500-be5d-11eb-8b36-4067a7a229f1.png) + + ### group by type inactive ![image](https://user-images.githubusercontent.com/27704687/119742054-56a7b700-be5d-11eb-8810-e31d4216f573.png) - regression: fix departments with empty ancestors not being returned ([#22068](https://github.com/RocketChat/Rocket.Chat/pull/22068)) @@ -2845,8 +2921,8 @@ - regression: Fix Users list in the Administration ([#22034](https://github.com/RocketChat/Rocket.Chat/pull/22034) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - The app crashed if no custom fields for user profiles have been created by the admin. I fixed this issue. This bug was introduced by a recent commit. - + The app crashed if no custom fields for user profiles have been created by the admin. I fixed this issue. This bug was introduced by a recent commit. + https://user-images.githubusercontent.com/45966964/118210838-5b3a9b80-b46b-11eb-9fe5-5b813848190c.mp4 - Regression: Improve migration 225 ([#22099](https://github.com/RocketChat/Rocket.Chat/pull/22099)) @@ -2863,7 +2939,7 @@ - Regression: not allowed to edit roles due to a new verification ([#22159](https://github.com/RocketChat/Rocket.Chat/pull/22159)) - introduced by https://github.com/RocketChat/Rocket.Chat/pull/21905 + introduced by https://github.com/RocketChat/Rocket.Chat/pull/21905 ![Peek 2021-05-26 22-21](https://user-images.githubusercontent.com/27704687/119750970-b9567e00-be70-11eb-9d52-04c8595950df.gif) - regression: Select Team Modal margin ([#22030](https://github.com/RocketChat/Rocket.Chat/pull/22030)) @@ -2874,10 +2950,10 @@ - Regression: Visual issue on sort list item ([#22158](https://github.com/RocketChat/Rocket.Chat/pull/22158)) - ### before - ![image](https://user-images.githubusercontent.com/27704687/119743703-d84d1400-be60-11eb-97cc-c8256b2c8b07.png) - - ### after + ### before + ![image](https://user-images.githubusercontent.com/27704687/119743703-d84d1400-be60-11eb-97cc-c8256b2c8b07.png) + + ### after ![image](https://user-images.githubusercontent.com/27704687/119743638-b18edd80-be60-11eb-828d-22cc5e1b2f5b.png) - Release 3.14.2 ([#22135](https://github.com/RocketChat/Rocket.Chat/pull/22135)) @@ -3063,12 +3139,12 @@ - Paginated and Filtered selects on new/edit unit ([#22052](https://github.com/RocketChat/Rocket.Chat/pull/22052) by [@rafaelblink](https://github.com/rafaelblink)) - REQUIRES https://github.com/RocketChat/Rocket.Chat.Fuselage/pull/447 - - Adds infinite scrolling selects to the units edit/create with the ability to be filtered by text as well - - ![Screen Shot 2021-05-17 at 9 24 19 AM](https://user-images.githubusercontent.com/20868078/118487999-abc32a80-b6f1-11eb-8d58-d031111ea0fb.png) - + REQUIRES https://github.com/RocketChat/Rocket.Chat.Fuselage/pull/447 + + Adds infinite scrolling selects to the units edit/create with the ability to be filtered by text as well + + ![Screen Shot 2021-05-17 at 9 24 19 AM](https://user-images.githubusercontent.com/20868078/118487999-abc32a80-b6f1-11eb-8d58-d031111ea0fb.png) + This Affects the monitors and departments inputs ### ๐Ÿš€ Improvements @@ -3144,18 +3220,24 @@ - New set of rules for client code ([#21318](https://github.com/RocketChat/Rocket.Chat/pull/21318)) - This _small_ PR does the following: - - - Now **React** is the web client's first-class citizen, being **loaded before Blaze**. Thus, `BlazeLayout` calls render templates inside of a React component (`BlazeLayoutWrapper`); - - Main client startup code, including polyfills, is written in **TypeScript**; - - At the moment, routes are treated as regular startup code; it's expected that `FlowRouter` will be deprecated in favor of a new routing library; - - **React** was updated to major version **17**, deprecating the usage of `React` as namespace (e.g. use `memo()` instead of `React.memo()`); - - The `client/` and `ee/client/` directory are linted with a **custom ESLint configuration** that includes: - - **Prettier**; - - `react-hooks/*` rules for TypeScript files; - - `react/no-multi-comp`, enforcing the rule of **one single React component per module**; - - `react/display-name`, which enforces that **React components must have a name for debugging**; - - `import/named`, avoiding broken named imports. + This _small_ PR does the following: + + + - Now **React** is the web client's first-class citizen, being **loaded before Blaze**. Thus, `BlazeLayout` calls render templates inside of a React component (`BlazeLayoutWrapper`); + + - Main client startup code, including polyfills, is written in **TypeScript**; + + - At the moment, routes are treated as regular startup code; it's expected that `FlowRouter` will be deprecated in favor of a new routing library; + + - **React** was updated to major version **17**, deprecating the usage of `React` as namespace (e.g. use `memo()` instead of `React.memo()`); + + - The `client/` and `ee/client/` directory are linted with a **custom ESLint configuration** that includes: + - **Prettier**; + - `react-hooks/*` rules for TypeScript files; + - `react/no-multi-comp`, enforcing the rule of **one single React component per module**; + - `react/display-name`, which enforces that **React components must have a name for debugging**; + - `import/named`, avoiding broken named imports. + - A bunch of components were refactored to match the new ESLint rules. - On Hold system messages ([#21360](https://github.com/RocketChat/Rocket.Chat/pull/21360) by [@rafaelblink](https://github.com/rafaelblink)) @@ -3164,12 +3246,15 @@ - Password history ([#21607](https://github.com/RocketChat/Rocket.Chat/pull/21607)) - - Store each user's previously used passwords in a `passwordHistory` field (in the `users` record); - - Users' previously used passwords are stored in their `passwordHistory` even when the setting is disabled; - - Add "Password History" setting -- when enabled, it blocks users from reusing their most recent passwords; - - Convert `comparePassword` file to TypeScript. - - ![Password_Change](https://user-images.githubusercontent.com/36537004/115035168-ac726200-9ea2-11eb-93c6-fc8182ba5f3f.png) + - Store each user's previously used passwords in a `passwordHistory` field (in the `users` record); + + - Users' previously used passwords are stored in their `passwordHistory` even when the setting is disabled; + + - Add "Password History" setting -- when enabled, it blocks users from reusing their most recent passwords; + + - Convert `comparePassword` file to TypeScript. + + ![Password_Change](https://user-images.githubusercontent.com/36537004/115035168-ac726200-9ea2-11eb-93c6-fc8182ba5f3f.png) ![Password_History](https://user-images.githubusercontent.com/36537004/115035175-ad0af880-9ea2-11eb-9f40-94c6327a9854.png) - REST endpoint `teams.update` ([#21134](https://github.com/RocketChat/Rocket.Chat/pull/21134) by [@g-thome](https://github.com/g-thome)) @@ -3187,14 +3272,18 @@ - Add error messages to the creation of channels or usernames containing reserved words ([#21016](https://github.com/RocketChat/Rocket.Chat/pull/21016)) - Display error messages when the user attempts to create or edit users' or channels' names with any of the following words (**case-insensitive**): - - admin; - - administrator; - - system; - - user. - ![create-channel](https://user-images.githubusercontent.com/36537004/110132223-b421ef80-7da9-11eb-82bc-f0d4e1df967f.png) - ![register-username](https://user-images.githubusercontent.com/36537004/110132234-b71ce000-7da9-11eb-904e-580233625951.png) - ![change-channel](https://user-images.githubusercontent.com/36537004/110143057-96f31e00-7db5-11eb-994a-39ae9e63392e.png) + Display error messages when the user attempts to create or edit users' or channels' names with any of the following words (**case-insensitive**): + + - admin; + + - administrator; + + - system; + + - user. + ![create-channel](https://user-images.githubusercontent.com/36537004/110132223-b421ef80-7da9-11eb-82bc-f0d4e1df967f.png) + ![register-username](https://user-images.githubusercontent.com/36537004/110132234-b71ce000-7da9-11eb-904e-580233625951.png) + ![change-channel](https://user-images.githubusercontent.com/36537004/110143057-96f31e00-7db5-11eb-994a-39ae9e63392e.png) ![change-username](https://user-images.githubusercontent.com/36537004/110143065-98244b00-7db5-11eb-9d13-afc5dc9866de.png) - add permission check when adding a channel to a team ([#21689](https://github.com/RocketChat/Rocket.Chat/pull/21689) by [@g-thome](https://github.com/g-thome)) @@ -3219,7 +3308,8 @@ - Resize custom emojis on upload instead of saving at max res ([#21593](https://github.com/RocketChat/Rocket.Chat/pull/21593)) - - Create new MediaService (ideally, should be in charge of all media-related operations) + - Create new MediaService (ideally, should be in charge of all media-related operations) + - Resize emojis to 128x128 ### ๐Ÿ› Bug fixes @@ -3239,25 +3329,25 @@ - Allows more than 25 discussions/files to be loaded in the contextualbar ([#21511](https://github.com/RocketChat/Rocket.Chat/pull/21511) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - In some places, you could not load more than 25 threads/discussions/files on the screen when searching the lists in the contextualbar. - Threads & list are numbered for a better view of the solution - - + In some places, you could not load more than 25 threads/discussions/files on the screen when searching the lists in the contextualbar. + Threads & list are numbered for a better view of the solution + + https://user-images.githubusercontent.com/45966964/114222225-93335800-996e-11eb-833f-568e83129aae.mp4 - Allows more than 25 threads to be loaded, fixes #21507 ([#21508](https://github.com/RocketChat/Rocket.Chat/pull/21508) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - Allows to display more than 25 users maximum in the users list ([#21518](https://github.com/RocketChat/Rocket.Chat/pull/21518) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - Now when you scroll to the bottom of the users list, it shows more users. Before the fix, the limit for the query for loadMore was calculated so that no additional users could be loaded. - - Before - - https://user-images.githubusercontent.com/45966964/114249739-baece500-999b-11eb-9bb0-3a5bcee18ad8.mp4 - - After - - + Now when you scroll to the bottom of the users list, it shows more users. Before the fix, the limit for the query for loadMore was calculated so that no additional users could be loaded. + + Before + + https://user-images.githubusercontent.com/45966964/114249739-baece500-999b-11eb-9bb0-3a5bcee18ad8.mp4 + + After + + https://user-images.githubusercontent.com/45966964/114249895-364e9680-999c-11eb-985c-47aedc763488.mp4 - App installation from marketplace not correctly displaying the permissions ([#21470](https://github.com/RocketChat/Rocket.Chat/pull/21470)) @@ -3324,19 +3414,19 @@ - Margins on contextual bar information ([#21457](https://github.com/RocketChat/Rocket.Chat/pull/21457)) - ### Room - **Before** - ![image](https://user-images.githubusercontent.com/27704687/115080812-ba8fa500-9ed9-11eb-9078-3625603bf92b.png) - - **After** - ![image](https://user-images.githubusercontent.com/27704687/115080966-e9a61680-9ed9-11eb-929f-6516c1563e99.png) - - ### Livechat + ### Room + **Before** + ![image](https://user-images.githubusercontent.com/27704687/115080812-ba8fa500-9ed9-11eb-9078-3625603bf92b.png) + + **After** + ![image](https://user-images.githubusercontent.com/27704687/115080966-e9a61680-9ed9-11eb-929f-6516c1563e99.png) + + ### Livechat ![image](https://user-images.githubusercontent.com/27704687/113640101-1859fc80-9651-11eb-88f8-09a899953988.png) - Message Block ordering ([#21464](https://github.com/RocketChat/Rocket.Chat/pull/21464)) - Reactions should come before reply button. + Reactions should come before reply button. ![image](https://user-images.githubusercontent.com/40830821/113748926-6f0e1780-96df-11eb-93a5-ddcfa891413e.png) - Message link null corrupts message rendering ([#21579](https://github.com/RocketChat/Rocket.Chat/pull/21579) by [@g-thome](https://github.com/g-thome)) @@ -3389,15 +3479,19 @@ - Typos/missing elements in the French translation ([#21525](https://github.com/RocketChat/Rocket.Chat/pull/21525) by [@Jeanstaquet](https://github.com/Jeanstaquet)) - - I have corrected some typos in the translation - - I added a translation for missing words - - I took the opportunity to correct a mistranslated word - - Test_Desktop_Notifications was missing in the EN and FR file + - I have corrected some typos in the translation + + - I added a translation for missing words + + - I took the opportunity to correct a mistranslated word + + - Test_Desktop_Notifications was missing in the EN and FR file ![image](https://user-images.githubusercontent.com/45966964/114290186-e7792d80-9a7d-11eb-8164-3b5e72e93703.png) - Updating a message causing URLs to be parsed even within markdown code ([#21489](https://github.com/RocketChat/Rocket.Chat/pull/21489)) - - Fix `updateMessage` to avoid parsing URLs inside markdown + - Fix `updateMessage` to avoid parsing URLs inside markdown + - Honor `parseUrls` property when updating messages - Use async await in TeamChannels delete channel action ([#21534](https://github.com/RocketChat/Rocket.Chat/pull/21534)) @@ -3410,8 +3504,8 @@ - Wrong user in user info ([#21451](https://github.com/RocketChat/Rocket.Chat/pull/21451)) - Fixed some race conditions in admin. - + Fixed some race conditions in admin. + Self DMs used to be created with the userId duplicated. Sometimes rooms can have 2 equal uids, but it's a self DM. Fixed a getter so this isn't a problem anymore.
@@ -3420,22 +3514,30 @@ - Doc: Corrected links to documentation of rocket.chat README.md ([#20478](https://github.com/RocketChat/Rocket.Chat/pull/20478) by [@joshi008](https://github.com/joshi008)) - The link for documentation in the readme was previously https://rocket.chat/docs/ while that was not working and according to the website it was https://docs.rocket.chat/ - The link for deployment methods in readme was corrected from https://rocket.chat/docs/installation/paas-deployments/ to https://docs.rocket.chat/installation/paas-deployments + The link for documentation in the readme was previously https://rocket.chat/docs/ while that was not working and according to the website it was https://docs.rocket.chat/ + The link for deployment methods in readme was corrected from https://rocket.chat/docs/installation/paas-deployments/ to https://docs.rocket.chat/installation/paas-deployments Some more links to the documentations were giving 404 error which hence updated. - [Improve] Remove useless tabbar options from Omnichannel rooms ([#21561](https://github.com/RocketChat/Rocket.Chat/pull/21561) by [@rafaelblink](https://github.com/rafaelblink)) - A React-based replacement for BlazeLayout ([#21527](https://github.com/RocketChat/Rocket.Chat/pull/21527)) - - The Meteor package **`kadira:blaze-layout` was removed**; - - A **global subscription** for the current application layout (**`appLayout`**) replaces `BlazeLayout` entirely; - - The **`#react-root` element** is rendered on server-side instead of dynamically injected into the DOM tree; - - The **"page loading" throbber** is now rendered on the React tree; - - The **`renderRouteComponent` helper was removed**; - - Some code run without any criteria on **`main` template** module was moved into **client startup modules**; - - React portals used to embed Blaze templates have their own subscription (**`blazePortals`**); - - Some **route components were refactored** to remove a URL path trap originally disabled by `renderRouteComponent`; + - The Meteor package **`kadira:blaze-layout` was removed**; + + - A **global subscription** for the current application layout (**`appLayout`**) replaces `BlazeLayout` entirely; + + - The **`#react-root` element** is rendered on server-side instead of dynamically injected into the DOM tree; + + - The **"page loading" throbber** is now rendered on the React tree; + + - The **`renderRouteComponent` helper was removed**; + + - Some code run without any criteria on **`main` template** module was moved into **client startup modules**; + + - React portals used to embed Blaze templates have their own subscription (**`blazePortals`**); + + - Some **route components were refactored** to remove a URL path trap originally disabled by `renderRouteComponent`; + - A new component to embed the DOM nodes generated by **`RoomManager`** was created. - Add ')' after Date and Time in DB migration ([#21519](https://github.com/RocketChat/Rocket.Chat/pull/21519) by [@im-adithya](https://github.com/im-adithya)) @@ -3458,8 +3560,8 @@ - Chore: Meteor update to 2.1.1 ([#21494](https://github.com/RocketChat/Rocket.Chat/pull/21494)) - Basically Node update to version 12.22.1 - + Basically Node update to version 12.22.1 + Meteor change log https://github.com/meteor/meteor/blob/devel/History.md#v211-2021-04-06 - Chore: Remove control character from room model operation ([#21493](https://github.com/RocketChat/Rocket.Chat/pull/21493)) @@ -3468,7 +3570,8 @@ - Fix: Missing module `eventemitter3` for micro services ([#21611](https://github.com/RocketChat/Rocket.Chat/pull/21611)) - - Fix error when running micro services after version 3.12 + - Fix error when running micro services after version 3.12 + - Fix build of docker image version latest for micro services - Language update from LingoHub ๐Ÿค– on 2021-04-05Z ([#21446](https://github.com/RocketChat/Rocket.Chat/pull/21446)) @@ -3481,9 +3584,12 @@ - QoL improvements to add channel to team flow ([#21778](https://github.com/RocketChat/Rocket.Chat/pull/21778)) - - Fixed canAccessRoom validation - - Added e2e tests - - Removed channels that user cannot add to the team from autocomplete suggestions + - Fixed canAccessRoom validation + + - Added e2e tests + + - Removed channels that user cannot add to the team from autocomplete suggestions + - Improved error messages - Regression: Bold, italic and strike render (Original markdown) ([#21747](https://github.com/RocketChat/Rocket.Chat/pull/21747)) @@ -3506,10 +3612,10 @@ - Regression: Legacy Banner Position ([#21598](https://github.com/RocketChat/Rocket.Chat/pull/21598)) - ### Before: - ![image](https://user-images.githubusercontent.com/27704687/114961773-dc3c4e00-9e3f-11eb-9a32-e882db3fbfbc.png) - - ### After + ### Before: + ![image](https://user-images.githubusercontent.com/27704687/114961773-dc3c4e00-9e3f-11eb-9a32-e882db3fbfbc.png) + + ### After ![image](https://user-images.githubusercontent.com/27704687/114961673-a6976500-9e3f-11eb-9238-a12870d7db8f.png) - regression: Markdown broken on safari ([#21780](https://github.com/RocketChat/Rocket.Chat/pull/21780)) @@ -3719,56 +3825,62 @@ - **APPS:** New event interfaces for pre/post user leaving a room ([#20917](https://github.com/RocketChat/Rocket.Chat/pull/20917) by [@lucassartor](https://github.com/lucassartor)) - Added events and errors that trigger when a user leaves a room. + Added events and errors that trigger when a user leaves a room. That way it can communicate with the Apps-Engine by the `IPreRoomUserLeave` and `IPostRoomUserLeave` event interfaces. - **Enterprise:** Omnichannel On-Hold Queue ([#20945](https://github.com/RocketChat/Rocket.Chat/pull/20945)) - ### About this feature - This feature has been introduced to deal with Inactive chats. A chat is considered Inactive if an Omnichannel End User (aka Visitor) has not replied back to an agent in some time. These types of inactive chats become very important when an organisation has a limit set for `Max Simultaneous Chats per agent` which is defined by the following setting :point_down: , as more number of Inactive chats would directly affect an agent's productivity. - ![image](https://user-images.githubusercontent.com/34130764/111533003-4d7ad980-878c-11eb-8c1c-2796678a07db.png) - - Before this feature, we only had one option to deal with such Inactive/Abandoned chats - which was to auto close abandoned chats via this setting :point_down: - ![image](https://user-images.githubusercontent.com/34130764/111534353-e65e2480-878d-11eb-82a5-71368064ef45.png) - - however closing a chat isn't a best option for some cases. Let me take an example to explain a scenario - - > An agent is assisting a customer for installing a very huge software which is likely to take more than 20-30 minutes to download. In such scenarios closing a chat isn't the best approach since even after the lengthy download the customer might still need some assist from the agent. - > So basically this chat is going to block the agent's queue until the customer is able to finish his time-consuming download task in which he/she doesn't require any agent's assistance. Due to the `Max Simultaneous Chats per agent` limit, the agent is also not able to use this extra time to help other customer thus affecting his overall productivity. - - **So how does the On-Hold feature solve this problem?** - With the On-Hold feature, an agent is now able to place a chat on-hold. On-Hold chatsย **donโ€™t count towards the maximum number of concurrent chats**ย an agent can have. So in our above example, the agent can simply now place the customer on-hold for 20-30 minutes until the customer downloads the software and within this time, the agent can serve other customers - hence increasing the productivity of an agent. - - ---------------------------------------- - ### Working of the new On-Hold feature - - #### How can you place a chat on Hold ? - - A chat can be placed on-hold via 2 means - 1. Automatically place Abandoned chats On-hold - ![image](https://user-images.githubusercontent.com/34130764/111537074-06431780-8791-11eb-8d23-99f5d9f8ec45.png) - Via this :top: option you can define a timer which will get started when a customer sends a message. If we don't receive any message from the customer within this timer, the timer will get expired and the chat will be considered as Abandoned. - ![image](https://user-images.githubusercontent.com/34130764/111537346-53bf8480-8791-11eb-8dc7-260633b4e98f.png) - The via this :top: setting you can choose to automatically place this abandoned chat On Hold - 2. Manually place a chat On Hold - As an admin, you can allow an agent to manually place a chat on-hold. To do so, you'll need to turn on this :point_down: setting - ![image](https://user-images.githubusercontent.com/34130764/111537545-97b28980-8791-11eb-86fd-db45b87e9cc1.png) - Now an agent will be able to see a new `On Hold` button within their `Visitor Info Panel` like this :point_down: , provided the agent has sent the last message - ![image](https://user-images.githubusercontent.com/34130764/111537853-f24be580-8791-11eb-9561-d77ba430c625.png) - - #### How can you resume a On Hold chat ? - An On Hold chat can be resumed via 2 means - - 1. If the Customer sends a message - If the Customer / Omnichannel End User sends a message to the On Hold chat, the On Hold chat will get automatically resumed. - 2. Manually by agent - An Agent can manually resume the On Hold chat via clicking the `Resume` button in the bottom of a chat room. - ![image](https://user-images.githubusercontent.com/34130764/111538666-f88e9180-8792-11eb-8d14-01453b8e3db0.png) - - #### What would happen if the agent already reached maximum chats, and a On-Hold chat gets resumed ? - Based on how the chat was resumed, there are multiple cases are each case is dealt differently - - - If an agent manually tries to resume the On Hold chat, he/she will get an error saying `Maximum Simultaneous chat limit reached` + ### About this feature + This feature has been introduced to deal with Inactive chats. A chat is considered Inactive if an Omnichannel End User (aka Visitor) has not replied back to an agent in some time. These types of inactive chats become very important when an organisation has a limit set for `Max Simultaneous Chats per agent` which is defined by the following setting :point_down: , as more number of Inactive chats would directly affect an agent's productivity. + ![image](https://user-images.githubusercontent.com/34130764/111533003-4d7ad980-878c-11eb-8c1c-2796678a07db.png) + + Before this feature, we only had one option to deal with such Inactive/Abandoned chats - which was to auto close abandoned chats via this setting :point_down: + ![image](https://user-images.githubusercontent.com/34130764/111534353-e65e2480-878d-11eb-82a5-71368064ef45.png) + + however closing a chat isn't a best option for some cases. Let me take an example to explain a scenario + + > An agent is assisting a customer for installing a very huge software which is likely to take more than 20-30 minutes to download. In such scenarios closing a chat isn't the best approach since even after the lengthy download the customer might still need some assist from the agent. + > So basically this chat is going to block the agent's queue until the customer is able to finish his time-consuming download task in which he/she doesn't require any agent's assistance. Due to the `Max Simultaneous Chats per agent` limit, the agent is also not able to use this extra time to help other customer thus affecting his overall productivity. + + **So how does the On-Hold feature solve this problem?** + With the On-Hold feature, an agent is now able to place a chat on-hold. On-Hold chatsย **donโ€™t count towards the maximum number of concurrent chats**ย an agent can have. So in our above example, the agent can simply now place the customer on-hold for 20-30 minutes until the customer downloads the software and within this time, the agent can serve other customers - hence increasing the productivity of an agent. + + ---------------------------------------- + ### Working of the new On-Hold feature + + #### How can you place a chat on Hold ? + + A chat can be placed on-hold via 2 means + + 1. Automatically place Abandoned chats On-hold + ![image](https://user-images.githubusercontent.com/34130764/111537074-06431780-8791-11eb-8d23-99f5d9f8ec45.png) + Via this :top: option you can define a timer which will get started when a customer sends a message. If we don't receive any message from the customer within this timer, the timer will get expired and the chat will be considered as Abandoned. + ![image](https://user-images.githubusercontent.com/34130764/111537346-53bf8480-8791-11eb-8dc7-260633b4e98f.png) + The via this :top: setting you can choose to automatically place this abandoned chat On Hold + + 2. Manually place a chat On Hold + As an admin, you can allow an agent to manually place a chat on-hold. To do so, you'll need to turn on this :point_down: setting + ![image](https://user-images.githubusercontent.com/34130764/111537545-97b28980-8791-11eb-86fd-db45b87e9cc1.png) + Now an agent will be able to see a new `On Hold` button within their `Visitor Info Panel` like this :point_down: , provided the agent has sent the last message + ![image](https://user-images.githubusercontent.com/34130764/111537853-f24be580-8791-11eb-9561-d77ba430c625.png) + + #### How can you resume a On Hold chat ? + An On Hold chat can be resumed via 2 means + + + 1. If the Customer sends a message + If the Customer / Omnichannel End User sends a message to the On Hold chat, the On Hold chat will get automatically resumed. + + 2. Manually by agent + An Agent can manually resume the On Hold chat via clicking the `Resume` button in the bottom of a chat room. + ![image](https://user-images.githubusercontent.com/34130764/111538666-f88e9180-8792-11eb-8d14-01453b8e3db0.png) + + #### What would happen if the agent already reached maximum chats, and a On-Hold chat gets resumed ? + Based on how the chat was resumed, there are multiple cases are each case is dealt differently + + + - If an agent manually tries to resume the On Hold chat, he/she will get an error saying `Maximum Simultaneous chat limit reached` + - If a customer replies back on an On Hold chat and the last serving agent has reached maximum capacity, then this customer will be placed on the queue again from where based on the Routing Algorithm selected, the chat will get transferred to any available agent - Ability to hide 'Room topic changed' system messages ([#21062](https://github.com/RocketChat/Rocket.Chat/pull/21062) by [@Tirieru](https://github.com/Tirieru)) @@ -3779,33 +3891,39 @@ - Teams ([#20966](https://github.com/RocketChat/Rocket.Chat/pull/20966) by [@g-thome](https://github.com/g-thome)) - ## Teams - - - - You can easily group your users as Teams on Rocket.Chat. The feature takes the hassle out of managing multiple users one by one and allows you to handle them at the same time efficiently. - - - - Teams can be public or private and each team can have its own channels, which also can be public or private. - - It's possible to add existing channels to a Team or create new ones inside a Team. - - It's possible to invite people outside a Team to join Team's channels. - - It's possible to convert channels to Teams - - It's possible to add all team members to a channel at once - - Team members have roles - - - ![image](https://user-images.githubusercontent.com/70927132/113421955-4f56b680-93a2-11eb-80dc-9b70a3f09b3e.png) - - - - **Quickly onboard new users with Autojoin channels** - - Teams can have Auto-join channels โ€“ channels to which the team members are automatically added, so you donโ€™t need to go through the manual process of adding users repetitively - - ![image](https://user-images.githubusercontent.com/70927132/113419284-81194e80-939d-11eb-9fff-aeb05cbc8089.png) - - **Instantly mention multiple members at once** (available in EE) - + ## Teams + + + + You can easily group your users as Teams on Rocket.Chat. The feature takes the hassle out of managing multiple users one by one and allows you to handle them at the same time efficiently. + + + + - Teams can be public or private and each team can have its own channels, which also can be public or private. + + - It's possible to add existing channels to a Team or create new ones inside a Team. + + - It's possible to invite people outside a Team to join Team's channels. + + - It's possible to convert channels to Teams + + - It's possible to add all team members to a channel at once + + - Team members have roles + + + ![image](https://user-images.githubusercontent.com/70927132/113421955-4f56b680-93a2-11eb-80dc-9b70a3f09b3e.png) + + + + **Quickly onboard new users with Autojoin channels** + + Teams can have Auto-join channels โ€“ channels to which the team members are automatically added, so you donโ€™t need to go through the manual process of adding users repetitively + + ![image](https://user-images.githubusercontent.com/70927132/113419284-81194e80-939d-11eb-9fff-aeb05cbc8089.png) + + **Instantly mention multiple members at once** (available in EE) + With Teams, you donโ€™t need to remember everyoneโ€™s name to communicate with a team quickly. Just mention a Team โ€” @engineers, for instance โ€” and all members will be instantly notified. ### ๐Ÿš€ Improvements @@ -3815,22 +3933,22 @@ - Added modal-box for preview after recording audio. ([#20370](https://github.com/RocketChat/Rocket.Chat/pull/20370) by [@Darshilp326](https://github.com/Darshilp326)) - A modal box will be displayed so that users can change the filename and add description. - - **Before** - - https://user-images.githubusercontent.com/55157259/105687301-4e2a8880-5f1e-11eb-873d-dc8a880a2fc8.mp4 - - **After** - + A modal box will be displayed so that users can change the filename and add description. + + **Before** + + https://user-images.githubusercontent.com/55157259/105687301-4e2a8880-5f1e-11eb-873d-dc8a880a2fc8.mp4 + + **After** + https://user-images.githubusercontent.com/55157259/105687342-597db400-5f1e-11eb-8b61-8f9d9ebad0c4.mp4 - Adds toast after follow/unfollow messages and following icon for followed messages without threads. ([#20025](https://github.com/RocketChat/Rocket.Chat/pull/20025) by [@RonLek](https://github.com/RonLek)) - There was no alert on following/unfollowing a message previously. Also, it was impossible to make out a followed message with no threads from an unfollowed one. - - This PR would show an alert on following/unfollowing a message and also display a small bell icon (similar to the ones for starred and pinned messages) when a message with no thread is followed. - + There was no alert on following/unfollowing a message previously. Also, it was impossible to make out a followed message with no threads from an unfollowed one. + + This PR would show an alert on following/unfollowing a message and also display a small bell icon (similar to the ones for starred and pinned messages) when a message with no thread is followed. + https://user-images.githubusercontent.com/28918901/103813540-43e73e00-5086-11eb-8592-2877eb650f3e.mp4 - Back to threads list button on threads contextual bar ([#20882](https://github.com/RocketChat/Rocket.Chat/pull/20882)) @@ -3843,12 +3961,12 @@ - Improve Apps permission modal ([#21193](https://github.com/RocketChat/Rocket.Chat/pull/21193) by [@lucassartor](https://github.com/lucassartor)) - Improve the UI of the Apps permission modal when installing an App that requires permissions. - - **New UI:** - ![after](https://user-images.githubusercontent.com/49413772/111685622-e817fe80-8806-11eb-998d-b56623560e74.PNG) - - **Old UI:** + Improve the UI of the Apps permission modal when installing an App that requires permissions. + + **New UI:** + ![after](https://user-images.githubusercontent.com/49413772/111685622-e817fe80-8806-11eb-998d-b56623560e74.PNG) + + **Old UI:** ![before](https://user-images.githubusercontent.com/49413772/111685897-375e2f00-8807-11eb-814e-cb8060dc1830.PNG) - Make debug logs of Apps configurable via Log_Level setting in the Admin panel ([#21000](https://github.com/RocketChat/Rocket.Chat/pull/21000) by [@cuonghuunguyen](https://github.com/cuonghuunguyen)) @@ -3859,15 +3977,15 @@ - Sort Users List In Case Insensitive Manner ([#20790](https://github.com/RocketChat/Rocket.Chat/pull/20790) by [@aditya-mitra](https://github.com/aditya-mitra)) - The users listed in the admin panel were sorted in a case-sensitive manner , where the capitals came first and then the small letters (like - *A B C a b c*). This Change fixes this by sorting the names in a caseinsensitive manner (now - *A a B b C c*). - - ### Before - - ![before](https://user-images.githubusercontent.com/55396651/108189880-3fa74980-7137-11eb-99da-6498707b4bf8.png) - - - ### With This Change - + The users listed in the admin panel were sorted in a case-sensitive manner , where the capitals came first and then the small letters (like - *A B C a b c*). This Change fixes this by sorting the names in a caseinsensitive manner (now - *A a B b C c*). + + ### Before + + ![before](https://user-images.githubusercontent.com/55396651/108189880-3fa74980-7137-11eb-99da-6498707b4bf8.png) + + + ### With This Change + ![after](https://user-images.githubusercontent.com/55396651/108190177-9dd42c80-7137-11eb-8b4e-b7cef4ba512f.png) ### ๐Ÿ› Bug fixes @@ -3881,12 +3999,12 @@ - **APPS:** Warn message while installing app in air-gapped environment ([#20992](https://github.com/RocketChat/Rocket.Chat/pull/20992) by [@lucassartor](https://github.com/lucassartor)) - Change **error** message to a **warn** message when uploading a `.zip` file app into a air-gapped environment. - - The **error** message was giving the impression for the user that the app wasn't properly being installed , which it wasn't the case: - ![error](https://user-images.githubusercontent.com/49413772/109855273-d3e4d680-7c36-11eb-824b-ad455d24710c.PNG) - - A more detailed **warn** message can fix that impression for the user: + Change **error** message to a **warn** message when uploading a `.zip` file app into a air-gapped environment. + + The **error** message was giving the impression for the user that the app wasn't properly being installed , which it wasn't the case: + ![error](https://user-images.githubusercontent.com/49413772/109855273-d3e4d680-7c36-11eb-824b-ad455d24710c.PNG) + + A more detailed **warn** message can fix that impression for the user: ![warn](https://user-images.githubusercontent.com/49413772/109855383-f2e36880-7c36-11eb-8d61-c442980bd8fd.PNG) - Add missing `unreads` field to `users.info` REST endpoint ([#20905](https://github.com/RocketChat/Rocket.Chat/pull/20905)) @@ -3901,10 +4019,10 @@ - Correct direction for admin mapview text ([#20897](https://github.com/RocketChat/Rocket.Chat/pull/20897) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) - ![Screenshot from 2021-02-25 02-49-21](https://user-images.githubusercontent.com/38764067/109068512-f8602080-7715-11eb-8e22-d610f9d046d8.png) - ![Screenshot from 2021-02-25 02-49-46](https://user-images.githubusercontent.com/38764067/109068516-fa29e400-7715-11eb-9119-1c79abce278f.png) - ![Screenshot from 2021-02-25 02-49-57](https://user-images.githubusercontent.com/38764067/109068519-fbf3a780-7715-11eb-8b3d-0dc32f898725.png) - + ![Screenshot from 2021-02-25 02-49-21](https://user-images.githubusercontent.com/38764067/109068512-f8602080-7715-11eb-8e22-d610f9d046d8.png) + ![Screenshot from 2021-02-25 02-49-46](https://user-images.githubusercontent.com/38764067/109068516-fa29e400-7715-11eb-9119-1c79abce278f.png) + ![Screenshot from 2021-02-25 02-49-57](https://user-images.githubusercontent.com/38764067/109068519-fbf3a780-7715-11eb-8b3d-0dc32f898725.png) + The text says the share button will be on the left of the messagebox once enabled. However, it actually is on the right. - Correct ignored message CSS ([#20928](https://github.com/RocketChat/Rocket.Chat/pull/20928) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) @@ -3921,13 +4039,13 @@ - Custom emojis to override default ([#20359](https://github.com/RocketChat/Rocket.Chat/pull/20359) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) - Due to the sequence of the imports and how the emojiRenderer prioritizes lists, the custom emojis could not override the emojione emojis. Making two small changes fixed the issue. - - With the custom emoji for `:facepalm:` added, you can check out the result below: - ### Before - ![Screenshot from 2021-01-25 02-20-04](https://user-images.githubusercontent.com/38764067/105643088-dfb0e080-5eb3-11eb-8a00-582c53fbe9a4.png) - - ### After + Due to the sequence of the imports and how the emojiRenderer prioritizes lists, the custom emojis could not override the emojione emojis. Making two small changes fixed the issue. + + With the custom emoji for `:facepalm:` added, you can check out the result below: + ### Before + ![Screenshot from 2021-01-25 02-20-04](https://user-images.githubusercontent.com/38764067/105643088-dfb0e080-5eb3-11eb-8a00-582c53fbe9a4.png) + + ### After ![Screenshot from 2021-01-25 02-18-58](https://user-images.githubusercontent.com/38764067/105643076-cdcf3d80-5eb3-11eb-84b8-5dbc4f1135df.png) - Empty URL in user avatar doesn't show error and enables save ([#20440](https://github.com/RocketChat/Rocket.Chat/pull/20440) by [@im-adithya](https://github.com/im-adithya)) @@ -3940,12 +4058,12 @@ - Fix the search list showing the last channel ([#21160](https://github.com/RocketChat/Rocket.Chat/pull/21160) by [@shrinish123](https://github.com/shrinish123)) - The search list now also properly shows the last channel - Before : - - ![searchlist](https://user-images.githubusercontent.com/56491104/111471487-f3a7ee80-874e-11eb-9c6e-19bbf0731d60.png) - - After : + The search list now also properly shows the last channel + Before : + + ![searchlist](https://user-images.githubusercontent.com/56491104/111471487-f3a7ee80-874e-11eb-9c6e-19bbf0731d60.png) + + After : ![search_final](https://user-images.githubusercontent.com/56491104/111471521-fe628380-874e-11eb-8fa3-d1edb57587e1.png) - Follow thread action on threads list ([#20881](https://github.com/RocketChat/Rocket.Chat/pull/20881)) @@ -3970,13 +4088,13 @@ - Multi Select isn't working in Export Messages ([#21236](https://github.com/RocketChat/Rocket.Chat/pull/21236) by [@PriyaBihani](https://github.com/PriyaBihani)) - While exporting messages, we were not able to select multiple Users like this: - - https://user-images.githubusercontent.com/69837339/111953057-169a2000-8b0c-11eb-94a4-0e1657683f96.mp4 - - Now we can select multiple users: - - + While exporting messages, we were not able to select multiple Users like this: + + https://user-images.githubusercontent.com/69837339/111953057-169a2000-8b0c-11eb-94a4-0e1657683f96.mp4 + + Now we can select multiple users: + + https://user-images.githubusercontent.com/69837339/111953097-274a9600-8b0c-11eb-9177-bec388b042bd.mp4 - New Channel popover not closing ([#21080](https://github.com/RocketChat/Rocket.Chat/pull/21080)) @@ -3985,31 +4103,31 @@ - OEmbedURLWidget - Show Full Embedded Text Description ([#20569](https://github.com/RocketChat/Rocket.Chat/pull/20569) by [@aditya-mitra](https://github.com/aditya-mitra)) - Embeds were cutoff when either _urls had a long description_. - This was handled by removing `overflow:hidden;text-overflow:ellipsis;` from the inline styles in [`oembedUrlWidget.html`](https://github.com/RocketChat/Rocket.Chat/blob/develop/app/oembed/client/oembedUrlWidget.html#L28). - - ### Earlier - - ![earlier](https://user-images.githubusercontent.com/55396651/107110825-00dcde00-6871-11eb-866e-13cabc5b0d05.png) - - ### Now - + Embeds were cutoff when either _urls had a long description_. + This was handled by removing `overflow:hidden;text-overflow:ellipsis;` from the inline styles in [`oembedUrlWidget.html`](https://github.com/RocketChat/Rocket.Chat/blob/develop/app/oembed/client/oembedUrlWidget.html#L28). + + ### Earlier + + ![earlier](https://user-images.githubusercontent.com/55396651/107110825-00dcde00-6871-11eb-866e-13cabc5b0d05.png) + + ### Now + ![now](https://user-images.githubusercontent.com/55396651/107110794-ca06c800-6870-11eb-9b3b-168679936612.png) - Reactions list showing users in reactions option of message action. ([#20753](https://github.com/RocketChat/Rocket.Chat/pull/20753) by [@Darshilp326](https://github.com/Darshilp326)) - Reactions list shows emojis with respected users who have reacted with that emoji. - + Reactions list shows emojis with respected users who have reacted with that emoji. + https://user-images.githubusercontent.com/55157259/107857609-5870e000-6e55-11eb-8137-494a9f71b171.mp4 - Removing truncation from profile ([#20352](https://github.com/RocketChat/Rocket.Chat/pull/20352) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) - Truncating text in profile view was making some information completely inaccessible. Removed it from the user status and the custom fields where if the information is longer, the user would actually want to see all of it. - - ### Before - ![Screenshot from 2021-01-24 20-54-44](https://user-images.githubusercontent.com/38764067/105634935-7e264d00-5e86-11eb-8a6c-9f2a363e0f6c.png) - - ### After + Truncating text in profile view was making some information completely inaccessible. Removed it from the user status and the custom fields where if the information is longer, the user would actually want to see all of it. + + ### Before + ![Screenshot from 2021-01-24 20-54-44](https://user-images.githubusercontent.com/38764067/105634935-7e264d00-5e86-11eb-8a6c-9f2a363e0f6c.png) + + ### After ![Screenshot from 2021-01-24 20-54-06](https://user-images.githubusercontent.com/38764067/105634940-82eb0100-5e86-11eb-8b90-e97a43c5e938.png) - Replace wrong field description on Room Information panel ([#21395](https://github.com/RocketChat/Rocket.Chat/pull/21395) by [@rafaelblink](https://github.com/rafaelblink)) @@ -4020,8 +4138,8 @@ - Set establishing to false if OTR timeouts ([#21183](https://github.com/RocketChat/Rocket.Chat/pull/21183) by [@Darshilp326](https://github.com/Darshilp326)) - Set establishing false if OTR timeouts. - + Set establishing false if OTR timeouts. + https://user-images.githubusercontent.com/55157259/111617086-b30cab80-8808-11eb-8740-3b4ffacfc322.mp4 - Sidebar scroll missing full height ([#21071](https://github.com/RocketChat/Rocket.Chat/pull/21071)) @@ -4060,20 +4178,33 @@ - Chore: Add tests for Meteor methods ([#20901](https://github.com/RocketChat/Rocket.Chat/pull/20901)) - Add end-to-end tests for the following meteor methods - - - [x] public-settings:get - - [x] rooms:get - - [x] subscriptions:get - - [x] permissions:get - - [x] loadMissedMessages - - [x] loadHistory - - [x] listCustomUserStatus - - [x] getUserRoles - - [x] getRoomRoles (called by the API, already covered) - - [x] getMessages - - [x] getUsersOfRoom - - [x] loadNextMessages + Add end-to-end tests for the following meteor methods + + + - [x] public-settings:get + + - [x] rooms:get + + - [x] subscriptions:get + + - [x] permissions:get + + - [x] loadMissedMessages + + - [x] loadHistory + + - [x] listCustomUserStatus + + - [x] getUserRoles + + - [x] getRoomRoles (called by the API, already covered) + + - [x] getMessages + + - [x] getUsersOfRoom + + - [x] loadNextMessages + - [x] getThreadMessages - Chore: Meteor update 2.1 ([#21061](https://github.com/RocketChat/Rocket.Chat/pull/21061)) @@ -4086,8 +4217,10 @@ - Improve: Increase testing coverage ([#21015](https://github.com/RocketChat/Rocket.Chat/pull/21015)) - Add test for - - settings/raw + Add test for + + - settings/raw + - minimongo/comparisons - Improve: NPS survey fetch ([#21263](https://github.com/RocketChat/Rocket.Chat/pull/21263)) @@ -4106,17 +4239,19 @@ - Regression: Add scope to permission checks in Team's endpoints ([#21369](https://github.com/RocketChat/Rocket.Chat/pull/21369)) - - Include scope (team's main room ID) in the permission checks; + - Include scope (team's main room ID) in the permission checks; - Remove the `teamName` parameter from the `members`, `addMembers`, `updateMember` and `removeMembers` methods (since `teamId` will always be defined). - Regression: Add support to filter on `teams.listRooms` endpoint ([#21327](https://github.com/RocketChat/Rocket.Chat/pull/21327)) - - Add support for queries (within the `query` parameter); + - Add support for queries (within the `query` parameter); + - Add support to pagination (`offset` and `count`) when an user doesn't have the permission to get all rooms. - Regression: Add teams support to directory ([#21351](https://github.com/RocketChat/Rocket.Chat/pull/21351)) - - Change `directory.js` to reduce function complexity + - Change `directory.js` to reduce function complexity + - Add `teams` type of item. Directory will return all public teams & private teams the user is part of. - Regression: add view room action on Teams Channels ([#21295](https://github.com/RocketChat/Rocket.Chat/pull/21295)) @@ -4169,18 +4304,19 @@ - Regression: Quick action button missing for Omnichannel On-Hold queue ([#21285](https://github.com/RocketChat/Rocket.Chat/pull/21285)) - - Move the Manual On Hold button to the new Omnichannel Header - ![image](https://user-images.githubusercontent.com/34130764/112291749-6ae10380-8cb6-11eb-94cd-e05efc14b1bf.png) - ![image](https://user-images.githubusercontent.com/34130764/112304146-27d95d00-8cc3-11eb-85db-dde04a110dd1.png) - + - Move the Manual On Hold button to the new Omnichannel Header + ![image](https://user-images.githubusercontent.com/34130764/112291749-6ae10380-8cb6-11eb-94cd-e05efc14b1bf.png) + ![image](https://user-images.githubusercontent.com/34130764/112304146-27d95d00-8cc3-11eb-85db-dde04a110dd1.png) + + - Minor fixes - regression: Remove Breadcrumbs and update Tag component ([#21399](https://github.com/RocketChat/Rocket.Chat/pull/21399)) - Regression: Remove channel action on add channel's modal don't work ([#21356](https://github.com/RocketChat/Rocket.Chat/pull/21356)) - ![removechannel-on-add-existing-modal](https://user-images.githubusercontent.com/27704687/112911017-eda8fa80-90ca-11eb-9c24-47a70be0c314.gif) - + ![removechannel-on-add-existing-modal](https://user-images.githubusercontent.com/27704687/112911017-eda8fa80-90ca-11eb-9c24-47a70be0c314.gif) + ![image](https://user-images.githubusercontent.com/27704687/112911052-02858e00-90cb-11eb-85a2-0ef1f5f9ffd9.png) - Regression: Remove primary color from button in TeamChannels component ([#21293](https://github.com/RocketChat/Rocket.Chat/pull/21293)) @@ -4209,10 +4345,10 @@ - Regression: Unify Contact information displayed on the Room header and Room Info ([#21312](https://github.com/RocketChat/Rocket.Chat/pull/21312) by [@rafaelblink](https://github.com/rafaelblink)) - ![image](https://user-images.githubusercontent.com/34130764/112586659-35592900-8e22-11eb-94be-32bdff7ca883.png) - - ![image](https://user-images.githubusercontent.com/2493803/112913130-788bf400-90cf-11eb-84c6-782b203e100a.png) - + ![image](https://user-images.githubusercontent.com/34130764/112586659-35592900-8e22-11eb-94be-32bdff7ca883.png) + + ![image](https://user-images.githubusercontent.com/2493803/112913130-788bf400-90cf-11eb-84c6-782b203e100a.png) + ![image](https://user-images.githubusercontent.com/2493803/112913146-817cc580-90cf-11eb-87ad-ef79766be2b3.png) - Regression: Unify team actions to add a room to a team ([#21386](https://github.com/RocketChat/Rocket.Chat/pull/21386)) @@ -4221,8 +4357,10 @@ - Regression: Update .invite endpoints to support multiple users at once ([#21328](https://github.com/RocketChat/Rocket.Chat/pull/21328)) - - channels.invite now supports passing an array as a param (either with usernames or userIds) via `usernames` or `userIds` properties. - - You can still use the endpoint to invite only one user via the old params `userId`, `username` or `user`. + - channels.invite now supports passing an array as a param (either with usernames or userIds) via `usernames` or `userIds` properties. + + - You can still use the endpoint to invite only one user via the old params `userId`, `username` or `user`. + - Same changes apply to groups.invite - Regression: user actions in admin ([#21307](https://github.com/RocketChat/Rocket.Chat/pull/21307)) @@ -4357,7 +4495,7 @@ - Close Call contextual bar after starting jitsi call. ([#21004](https://github.com/RocketChat/Rocket.Chat/pull/21004) by [@yash-rajpal](https://github.com/yash-rajpal)) - After jitsi call is started, if the call is started in a new window then we should close contextual tab bar. + After jitsi call is started, if the call is started in a new window then we should close contextual tab bar. So, when 'YES' is pressed on modal, we call handleClose function if openNewWindow is true, as call doesn't starts on tab bar, it starts on new window. ### ๐Ÿ› Bug fixes @@ -4367,7 +4505,7 @@ - Stopping Jitsi reload ([#20973](https://github.com/RocketChat/Rocket.Chat/pull/20973) by [@yash-rajpal](https://github.com/yash-rajpal)) - The Function where Jitsi call is started gets called many times due to `room.usernames` dep of useMemo, this dep triggers reloading of this function many times. + The Function where Jitsi call is started gets called many times due to `room.usernames` dep of useMemo, this dep triggers reloading of this function many times. So removing this dep from useMemo dependencies ### ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป Contributors ๐Ÿ˜ @@ -4395,10 +4533,10 @@ - Cloud Workspace bridge ([#20838](https://github.com/RocketChat/Rocket.Chat/pull/20838)) - Adds the new CloudWorkspace functionality. - - It allows apps to request the access token for the workspace it's installed on, so it can perform actions with other Rocket.Chat services, such as the Omni Gateway. - + Adds the new CloudWorkspace functionality. + + It allows apps to request the access token for the workspace it's installed on, so it can perform actions with other Rocket.Chat services, such as the Omni Gateway. + https://github.com/RocketChat/Rocket.Chat.Apps-engine/pull/382 - Header with Breadcrumbs ([#20609](https://github.com/RocketChat/Rocket.Chat/pull/20609)) @@ -4416,10 +4554,10 @@ - Add symbol to indicate apps' required settings in the UI ([#20447](https://github.com/RocketChat/Rocket.Chat/pull/20447)) - - Apps are able to define **required** settings. These settings should not be left blank by the user and an error will be thrown and shown in the interface if an user attempts to save changes in the app details page leaving any required fields blank; - ![prt_screen_required_app_settings_warning](https://user-images.githubusercontent.com/36537004/106032964-e73cd900-60af-11eb-8eab-c11fd651b593.png) - - - A sign (*) is added to the label of app settings' fields that are required so as to highlight the fields which must not be left blank. + - Apps are able to define **required** settings. These settings should not be left blank by the user and an error will be thrown and shown in the interface if an user attempts to save changes in the app details page leaving any required fields blank; + ![prt_screen_required_app_settings_warning](https://user-images.githubusercontent.com/36537004/106032964-e73cd900-60af-11eb-8eab-c11fd651b593.png) + + - A sign (*) is added to the label of app settings' fields that are required so as to highlight the fields which must not be left blank. ![prt_screen_required_app_settings](https://user-images.githubusercontent.com/36537004/106014879-ae473900-609c-11eb-9b9e-95de7bbf20a5.png) - Add visual validation on users admin forms ([#20308](https://github.com/RocketChat/Rocket.Chat/pull/20308)) @@ -4440,20 +4578,20 @@ - Adds tooltip for sidebar header icons ([#19934](https://github.com/RocketChat/Rocket.Chat/pull/19934) by [@RonLek](https://github.com/RonLek)) - Previously the header icons in the sidebar didn't show a tooltip when hovered over. This PR fixes that. - + Previously the header icons in the sidebar didn't show a tooltip when hovered over. This PR fixes that. + ![Screenshot from 2020-12-22 15-17-41](https://user-images.githubusercontent.com/28918901/102874804-f2756700-4468-11eb-8324-b7f3194e62fe.png) - Better Presentation of Blockquotes ([#20750](https://github.com/RocketChat/Rocket.Chat/pull/20750) by [@aditya-mitra](https://github.com/aditya-mitra)) - Changed the values of `margin-top` and `margin-bottom` for *first* and *last* childs in blockquotes to increase readability. - - ### Before - - ![before](https://user-images.githubusercontent.com/55396651/107858662-3e3a0080-6e5b-11eb-8274-9bd956807235.png) - - ### Now - + Changed the values of `margin-top` and `margin-bottom` for *first* and *last* childs in blockquotes to increase readability. + + ### Before + + ![before](https://user-images.githubusercontent.com/55396651/107858662-3e3a0080-6e5b-11eb-8274-9bd956807235.png) + + ### Now + ![now](https://user-images.githubusercontent.com/55396651/107858471-480f3400-6e5a-11eb-9ccb-3f1be2fed0a4.png) - Change header based on room type ([#20612](https://github.com/RocketChat/Rocket.Chat/pull/20612)) @@ -4474,13 +4612,18 @@ - Replace react-window for react-virtuoso package ([#20392](https://github.com/RocketChat/Rocket.Chat/pull/20392)) - Remove: - - react-window - - react-window-infinite-loader - - simplebar-react - - Include: - - react-virtuoso + Remove: + + - react-window + + - react-window-infinite-loader + + - simplebar-react + + Include: + + - react-virtuoso + - rc-scrollbars - Rewrite Call as React component ([#19778](https://github.com/RocketChat/Rocket.Chat/pull/19778)) @@ -4496,13 +4639,13 @@ - Add debouncing to add users search field. ([#20297](https://github.com/RocketChat/Rocket.Chat/pull/20297) by [@Darshilp326](https://github.com/Darshilp326)) - BEFORE - - https://user-images.githubusercontent.com/55157259/105350722-98a3c080-5c11-11eb-82f3-d9a62a4fa50b.mp4 - - - AFTER - + BEFORE + + https://user-images.githubusercontent.com/55157259/105350722-98a3c080-5c11-11eb-82f3-d9a62a4fa50b.mp4 + + + AFTER + https://user-images.githubusercontent.com/55157259/105350757-a2c5bf00-5c11-11eb-91db-25c0b9e01a28.mp4 - Add tooltips to Thread header buttons ([#20456](https://github.com/RocketChat/Rocket.Chat/pull/20456) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) @@ -4515,8 +4658,8 @@ - Added check for view admin permission page ([#20403](https://github.com/RocketChat/Rocket.Chat/pull/20403) by [@yash-rajpal](https://github.com/yash-rajpal)) - Admin Permission page was visible to all, if you add admin/permissions after the base url. This should not be visible to all user, only people with certain permissions should be able to see this page. - I am also able to see permissions page for open workspace of Rocket chat. + Admin Permission page was visible to all, if you add admin/permissions after the base url. This should not be visible to all user, only people with certain permissions should be able to see this page. + I am also able to see permissions page for open workspace of Rocket chat. ![image](https://user-images.githubusercontent.com/58601732/105829728-bfd00880-5fea-11eb-9121-6c53a752f140.png) - Adding the accidentally deleted tag template, used by other templates ([#20772](https://github.com/RocketChat/Rocket.Chat/pull/20772) by [@yash-rajpal](https://github.com/yash-rajpal)) @@ -4525,8 +4668,8 @@ - Admin cannot clear user details like bio or nickname ([#20785](https://github.com/RocketChat/Rocket.Chat/pull/20785) by [@yash-rajpal](https://github.com/yash-rajpal)) - When the API users.update is called to update user data, it passes data to saveUser function. Here before saving data like bio or nickname we are checking if they are available or not. If data is available then we are saving it, but we are not doing anything when data isn't available. - + When the API users.update is called to update user data, it passes data to saveUser function. Here before saving data like bio or nickname we are checking if they are available or not. If data is available then we are saving it, but we are not doing anything when data isn't available. + So unsetting data if data isn't available to save. Will also fix bio and other fields. :) - Admin Panel pages not visible in Safari ([#20912](https://github.com/RocketChat/Rocket.Chat/pull/20912)) @@ -4543,24 +4686,24 @@ - Blank Personal Access Token Bug ([#20193](https://github.com/RocketChat/Rocket.Chat/pull/20193) by [@RonLek](https://github.com/RonLek)) - Adds error when personal access token is blank thereby disallowing the creation of one. - + Adds error when personal access token is blank thereby disallowing the creation of one. + https://user-images.githubusercontent.com/28918901/104483631-5adde100-55ee-11eb-9938-64146bce127e.mp4 - CAS login failing due to TOTP requirement ([#20840](https://github.com/RocketChat/Rocket.Chat/pull/20840)) - Changed password input field for password access in edit room info. ([#20356](https://github.com/RocketChat/Rocket.Chat/pull/20356) by [@Darshilp326](https://github.com/Darshilp326)) - Password field would be secured with asterisks in edit room info - - https://user-images.githubusercontent.com/55157259/105641758-cad04f00-5eab-11eb-90de-0c91263edd55.mp4 - + Password field would be secured with asterisks in edit room info + + https://user-images.githubusercontent.com/55157259/105641758-cad04f00-5eab-11eb-90de-0c91263edd55.mp4 + . - Channel mentions showing user subscribed channels twice ([#20484](https://github.com/RocketChat/Rocket.Chat/pull/20484) by [@Darshilp326](https://github.com/Darshilp326)) - Channel mention shows user subscribed channels twice. - + Channel mention shows user subscribed channels twice. + https://user-images.githubusercontent.com/55157259/106183033-b353d780-61c5-11eb-8aab-1dbb62b02ff8.mp4 - CORS config not accepting multiple origins ([#20696](https://github.com/RocketChat/Rocket.Chat/pull/20696) by [@g-thome](https://github.com/g-thome)) @@ -4571,26 +4714,26 @@ - Default Attachments - Remove Extra Margin in Field Attachments ([#20618](https://github.com/RocketChat/Rocket.Chat/pull/20618) by [@aditya-mitra](https://github.com/aditya-mitra)) - A large amount of unnecessary margin which existed in the **Field Attachments inside the `DefaultAttachments`** has been fixed. - - ### Earlier - - ![earlier](https://user-images.githubusercontent.com/55396651/107056792-ba4b9d00-67f8-11eb-9153-05281416cddb.png) - - ### Now - + A large amount of unnecessary margin which existed in the **Field Attachments inside the `DefaultAttachments`** has been fixed. + + ### Earlier + + ![earlier](https://user-images.githubusercontent.com/55396651/107056792-ba4b9d00-67f8-11eb-9153-05281416cddb.png) + + ### Now + ![now](https://user-images.githubusercontent.com/55396651/107057196-3219c780-67f9-11eb-84db-e4a0addfc168.png) - Default Attachments - Show Full Attachment.Text with Markdown ([#20606](https://github.com/RocketChat/Rocket.Chat/pull/20606) by [@aditya-mitra](https://github.com/aditya-mitra)) - Removed truncating of text in `Attachment.Text`. - Added `Attachment.Text` to be parsed to markdown by default. - - ### Earlier - ![earlier](https://user-images.githubusercontent.com/55396651/106910781-92d8cf80-6727-11eb-82ec-818df7544ff0.png) - - ### Now - + Removed truncating of text in `Attachment.Text`. + Added `Attachment.Text` to be parsed to markdown by default. + + ### Earlier + ![earlier](https://user-images.githubusercontent.com/55396651/106910781-92d8cf80-6727-11eb-82ec-818df7544ff0.png) + + ### Now + ![now](https://user-images.githubusercontent.com/55396651/106910840-a126eb80-6727-11eb-8bd6-d86383dd9181.png) - Don't ask again not rendering ([#20745](https://github.com/RocketChat/Rocket.Chat/pull/20745)) @@ -4611,21 +4754,21 @@ - Feedback on bulk invite ([#20339](https://github.com/RocketChat/Rocket.Chat/pull/20339) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) - Resolved structure where no response was being received. Changed from callback to async/await. - Added error in case of empty submission, or if no valid emails were found. - + Resolved structure where no response was being received. Changed from callback to async/await. + Added error in case of empty submission, or if no valid emails were found. + https://user-images.githubusercontent.com/38764067/105613964-dfe5a900-5deb-11eb-80f2-21fc8dee57c0.mp4 - Filters are not being applied correctly in Omnichannel Current Chats list ([#20320](https://github.com/RocketChat/Rocket.Chat/pull/20320) by [@rafaelblink](https://github.com/rafaelblink)) - ### Before - ![image](https://user-images.githubusercontent.com/2493803/105537672-082cb500-5cd1-11eb-8f1b-1726ba60420a.png) - - ### After - ![image](https://user-images.githubusercontent.com/2493803/105537773-2d212800-5cd1-11eb-8746-048deb9502d9.png) - - ![image](https://user-images.githubusercontent.com/2493803/106494728-88090b00-6499-11eb-922e-5386107e2389.png) - + ### Before + ![image](https://user-images.githubusercontent.com/2493803/105537672-082cb500-5cd1-11eb-8f1b-1726ba60420a.png) + + ### After + ![image](https://user-images.githubusercontent.com/2493803/105537773-2d212800-5cd1-11eb-8746-048deb9502d9.png) + + ![image](https://user-images.githubusercontent.com/2493803/106494728-88090b00-6499-11eb-922e-5386107e2389.png) + ![image](https://user-images.githubusercontent.com/2493803/106494751-90f9dc80-6499-11eb-901b-5e4dbdc678ba.png) - Fix Empty highlighted words field ([#20329](https://github.com/RocketChat/Rocket.Chat/pull/20329) by [@yash-rajpal](https://github.com/yash-rajpal)) @@ -4654,11 +4797,11 @@ - List of Omnichannel triggers is not listing data ([#20624](https://github.com/RocketChat/Rocket.Chat/pull/20624) by [@rafaelblink](https://github.com/rafaelblink)) - ### Before - ![image](https://user-images.githubusercontent.com/2493803/107095379-7308e080-67e7-11eb-8251-7e7ff891087a.png) - - - ### After + ### Before + ![image](https://user-images.githubusercontent.com/2493803/107095379-7308e080-67e7-11eb-8251-7e7ff891087a.png) + + + ### After ![image](https://user-images.githubusercontent.com/2493803/107095261-3b019d80-67e7-11eb-8425-8612b03ac50a.png) - Livechat bridge permission checkers ([#20653](https://github.com/RocketChat/Rocket.Chat/pull/20653) by [@lolimay](https://github.com/lolimay)) @@ -4681,7 +4824,8 @@ - Missing setting to control when to send the ReplyTo field in email notifications ([#20744](https://github.com/RocketChat/Rocket.Chat/pull/20744)) - - Add a new setting ("Add Reply-To header") in the Email settings' page to control when the Reply-To header is used in e-mail notifications; + - Add a new setting ("Add Reply-To header") in the Email settings' page to control when the Reply-To header is used in e-mail notifications; + - The new setting is turned off (`false` value) by default. - New Integration page was not being displayed ([#20670](https://github.com/RocketChat/Rocket.Chat/pull/20670) by [@yash-rajpal](https://github.com/yash-rajpal)) @@ -4714,15 +4858,15 @@ - Remove duplicate getCommonRoomEvents() event binding for starredMessages ([#20185](https://github.com/RocketChat/Rocket.Chat/pull/20185) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) - The getCommonRoomEvents() returned functions were bound to the starredMessages template twice. This was causing some bugs, as detailed in the Issue mentioned below. + The getCommonRoomEvents() returned functions were bound to the starredMessages template twice. This was causing some bugs, as detailed in the Issue mentioned below. I removed the top events call that only bound the getCommonRoomEvents(). Therefore, only one call for the same is left, which is at the end of the file. Having the events bound just once removes the bugs mentioned. - Remove warning problems from console ([#20800](https://github.com/RocketChat/Rocket.Chat/pull/20800)) - Removed tooltip in kebab menu options. ([#20498](https://github.com/RocketChat/Rocket.Chat/pull/20498) by [@Darshilp326](https://github.com/Darshilp326)) - Removed tooltip as it was not needed. - + Removed tooltip as it was not needed. + https://user-images.githubusercontent.com/55157259/106246146-a53ca000-6233-11eb-9874-cbd1b4331bc0.mp4 - Retry icon comes out of the div ([#20390](https://github.com/RocketChat/Rocket.Chat/pull/20390) by [@im-adithya](https://github.com/im-adithya)) @@ -4737,8 +4881,8 @@ - Room's last message's update date format on IE ([#20680](https://github.com/RocketChat/Rocket.Chat/pull/20680)) - The proposed change fixes a bug when updates the cached records on Internet Explorer and it breaks the sidebar as shown on the screenshot below: - + The proposed change fixes a bug when updates the cached records on Internet Explorer and it breaks the sidebar as shown on the screenshot below: + ![image](https://user-images.githubusercontent.com/27704687/107578007-f2285b00-6bd1-11eb-9250-1e76ae67f9c9.png) - Save user password and email from My Account ([#20737](https://github.com/RocketChat/Rocket.Chat/pull/20737)) @@ -4747,8 +4891,8 @@ - Selected hide system messages would now be viewed in vertical bar. ([#20358](https://github.com/RocketChat/Rocket.Chat/pull/20358) by [@Darshilp326](https://github.com/Darshilp326)) - All selected hide system messages are now in vertical Bar. - + All selected hide system messages are now in vertical Bar. + https://user-images.githubusercontent.com/55157259/105642624-d5411780-5eb0-11eb-8848-93e4b02629cb.mp4 - Selected messages don't get unselected ([#20408](https://github.com/RocketChat/Rocket.Chat/pull/20408) by [@im-adithya](https://github.com/im-adithya)) @@ -4763,14 +4907,22 @@ - Several Slack Importer issues ([#20216](https://github.com/RocketChat/Rocket.Chat/pull/20216)) - - Fix: Slack Importer crashes when importing a large users.json file - - Fix: Slack importer crashes when messages have invalid mentions - - Skip listing all users on the preparation screen when the user count is too large. - - Split avatar download into a separate process. - - Update room's last message when the import is complete. - - Prevent invalid or duplicated channel names - - Improve message error handling. - - Reduce max allowed BSON size to avoid possible issues in some servers. + - Fix: Slack Importer crashes when importing a large users.json file + + - Fix: Slack importer crashes when messages have invalid mentions + + - Skip listing all users on the preparation screen when the user count is too large. + + - Split avatar download into a separate process. + + - Update room's last message when the import is complete. + + - Prevent invalid or duplicated channel names + + - Improve message error handling. + + - Reduce max allowed BSON size to avoid possible issues in some servers. + - Improve handling of very large channel files. - star icon was visible after unstarring a message ([#19645](https://github.com/RocketChat/Rocket.Chat/pull/19645) by [@bhavayAnand9](https://github.com/bhavayAnand9)) @@ -4789,15 +4941,15 @@ - User statuses in admin user info panel ([#20341](https://github.com/RocketChat/Rocket.Chat/pull/20341) by [@RonLek](https://github.com/RonLek)) - Modifies user statuses in admin info panel based on their actual status instead of their `statusConnection`. This enables correct and consistent change in user statuses. - Also, bot users having status as online were classified as offline, with this change they are now correctly classified based on their corresponding statuses. - + Modifies user statuses in admin info panel based on their actual status instead of their `statusConnection`. This enables correct and consistent change in user statuses. + Also, bot users having status as online were classified as offline, with this change they are now correctly classified based on their corresponding statuses. + https://user-images.githubusercontent.com/28918901/105624438-b8bcc500-5e47-11eb-8d1e-3a4180da1304.mp4 - Users autocomplete showing duplicated results ([#20481](https://github.com/RocketChat/Rocket.Chat/pull/20481) by [@Darshilp326](https://github.com/Darshilp326)) - Added new query for outside room users so that room members are not shown twice. - + Added new query for outside room users so that room members are not shown twice. + https://user-images.githubusercontent.com/55157259/106174582-33c10b00-61bb-11eb-9716-377ef7bba34e.mp4
@@ -4818,7 +4970,7 @@ - Chore: Disable Sessions Aggregates tests locally ([#20607](https://github.com/RocketChat/Rocket.Chat/pull/20607)) - Disable Session aggregates tests in local environments + Disable Session aggregates tests in local environments For context, refer to: #20161 - Chore: Improve performance of messagesโ€™ watcher ([#20519](https://github.com/RocketChat/Rocket.Chat/pull/20519)) @@ -5027,18 +5179,20 @@ - **ENTERPRISE:** Omnichannel Contact Manager as preferred agent for routing ([#20244](https://github.com/RocketChat/Rocket.Chat/pull/20244)) - If the `Contact-Manager` is assigned to a Visitor, the chat will automatically get transferred to the respective Contact-Manager, provided the Contact-Manager is online. In-case the Contact-Manager is offline, the chat will be transferred to any other online agent. - We have provided a setting to control this auto-assignment feature - ![image](https://user-images.githubusercontent.com/34130764/104880961-8104d780-5986-11eb-9d87-82b99814b028.png) - - Behavior based-on Routing method - - 1. Auto-selection, Load-Balancing, or External Service (`autoAssignAgent = true`) - This is straightforward, - - if the Contact-manager is online, the chat will be transferred to the Contact-Manger only - - if the Contact-manager is offline, the chat will be transferred to any other online-agent based on the Routing system - 2. Manual-selection (`autoAssignAgent = false`) - - If the Contact-Manager is online, the chat will appear in the Queue of Contact-Manager **ONLY** + If the `Contact-Manager` is assigned to a Visitor, the chat will automatically get transferred to the respective Contact-Manager, provided the Contact-Manager is online. In-case the Contact-Manager is offline, the chat will be transferred to any other online agent. + We have provided a setting to control this auto-assignment feature + ![image](https://user-images.githubusercontent.com/34130764/104880961-8104d780-5986-11eb-9d87-82b99814b028.png) + + Behavior based-on Routing method + + + 1. Auto-selection, Load-Balancing, or External Service (`autoAssignAgent = true`) + This is straightforward, + - if the Contact-manager is online, the chat will be transferred to the Contact-Manger only + - if the Contact-manager is offline, the chat will be transferred to any other online-agent based on the Routing system + + 2. Manual-selection (`autoAssignAgent = false`) + - If the Contact-Manager is online, the chat will appear in the Queue of Contact-Manager **ONLY** - If the Contact-Manager is offline, the chat will appear in the Queue of all related Agents/Manager ( like it's done right now ) - Banner system and NPS ([#20221](https://github.com/RocketChat/Rocket.Chat/pull/20221)) @@ -5047,34 +5201,34 @@ - Email Inboxes for Omnichannel ([#20101](https://github.com/RocketChat/Rocket.Chat/pull/20101) by [@rafaelblink](https://github.com/rafaelblink)) - With this new feature, email accounts will receive email messages(threads) which will be transformed into Omnichannel chats. It'll be possible to set up multiple email accounts, test the connection with email server(email provider) and define the behaviour of each account. - - https://user-images.githubusercontent.com/2493803/105430398-242d4980-5c32-11eb-835a-450c94837d23.mp4 - - ### New item on admin menu - - ![image](https://user-images.githubusercontent.com/2493803/105428723-bc293400-5c2e-11eb-8c02-e8d36ea82726.png) - - - ### Send test email tooltip - - ![image](https://user-images.githubusercontent.com/2493803/104366986-eaa16380-54f8-11eb-9ba7-831cfde2319c.png) - - - ### Inbox Info - - ![image](https://user-images.githubusercontent.com/2493803/104366796-ab731280-54f8-11eb-9941-a3cc8eb610e1.png) - - ### SMTP Info - - ![image](https://user-images.githubusercontent.com/2493803/104366868-c47bc380-54f8-11eb-969e-ccc29070957c.png) - - ### IMAP Info - - ![image](https://user-images.githubusercontent.com/2493803/104366897-cd6c9500-54f8-11eb-80c4-97d5b0c002d5.png) - - ### Messages - + With this new feature, email accounts will receive email messages(threads) which will be transformed into Omnichannel chats. It'll be possible to set up multiple email accounts, test the connection with email server(email provider) and define the behaviour of each account. + + https://user-images.githubusercontent.com/2493803/105430398-242d4980-5c32-11eb-835a-450c94837d23.mp4 + + ### New item on admin menu + + ![image](https://user-images.githubusercontent.com/2493803/105428723-bc293400-5c2e-11eb-8c02-e8d36ea82726.png) + + + ### Send test email tooltip + + ![image](https://user-images.githubusercontent.com/2493803/104366986-eaa16380-54f8-11eb-9ba7-831cfde2319c.png) + + + ### Inbox Info + + ![image](https://user-images.githubusercontent.com/2493803/104366796-ab731280-54f8-11eb-9941-a3cc8eb610e1.png) + + ### SMTP Info + + ![image](https://user-images.githubusercontent.com/2493803/104366868-c47bc380-54f8-11eb-969e-ccc29070957c.png) + + ### IMAP Info + + ![image](https://user-images.githubusercontent.com/2493803/104366897-cd6c9500-54f8-11eb-80c4-97d5b0c002d5.png) + + ### Messages + ![image](https://user-images.githubusercontent.com/2493803/105428971-45d90180-5c2f-11eb-992a-022a3df94471.png) - Encrypted Discussions and new Encryption Permissions ([#20201](https://github.com/RocketChat/Rocket.Chat/pull/20201)) @@ -5086,7 +5240,7 @@ - Add extra SAML settings to update room subs and add private room subs. ([#19489](https://github.com/RocketChat/Rocket.Chat/pull/19489) by [@tlskinneriv](https://github.com/tlskinneriv)) - Added a SAML setting to support updating room subscriptions each time a user logs in via SAML. + Added a SAML setting to support updating room subscriptions each time a user logs in via SAML. Added a SAML setting to support including private rooms in SAML updated subscriptions (whether initial or on each logon). - Autofocus on directory ([#20509](https://github.com/RocketChat/Rocket.Chat/pull/20509)) @@ -5113,7 +5267,7 @@ - Tooltip added for Kebab menu on chat header ([#20116](https://github.com/RocketChat/Rocket.Chat/pull/20116) by [@yash-rajpal](https://github.com/yash-rajpal)) - Added the missing Tooltip for kebab menu on chat header. + Added the missing Tooltip for kebab menu on chat header. ![tooltip after](https://user-images.githubusercontent.com/58601732/104031406-b07f4b80-51f2-11eb-87a4-1e8da78a254f.gif) ### ๐Ÿ› Bug fixes @@ -5135,7 +5289,7 @@ - Added context check for closing active tabbar for member-list ([#20228](https://github.com/RocketChat/Rocket.Chat/pull/20228) by [@yash-rajpal](https://github.com/yash-rajpal)) - When we click on a username and then click on see user's full profile, a tab gets active and shows us the user's profile, the problem occurs when the tab is still active and we try to see another user's profile. In this case, tabbar gets closed. + When we click on a username and then click on see user's full profile, a tab gets active and shows us the user's profile, the problem occurs when the tab is still active and we try to see another user's profile. In this case, tabbar gets closed. To resolve this, added context check for closing action of active tabbar. - Added Margin between status bullet and status label ([#20199](https://github.com/RocketChat/Rocket.Chat/pull/20199) by [@yash-rajpal](https://github.com/yash-rajpal)) @@ -5144,8 +5298,8 @@ - Added success message on saving notification preference. ([#20220](https://github.com/RocketChat/Rocket.Chat/pull/20220) by [@Darshilp326](https://github.com/Darshilp326)) - Added success message after saving notification preferences. - + Added success message after saving notification preferences. + https://user-images.githubusercontent.com/55157259/104774617-03ca3e80-579d-11eb-8fa4-990b108dd8d9.mp4 - Admin User Info email verified status ([#20110](https://github.com/RocketChat/Rocket.Chat/pull/20110) by [@bdelwood](https://github.com/bdelwood)) @@ -5154,10 +5308,10 @@ - Change header's favorite icon to filled star ([#20174](https://github.com/RocketChat/Rocket.Chat/pull/20174)) - ### Before: - ![image](https://user-images.githubusercontent.com/27704687/104351819-a60bcd00-54e4-11eb-8b43-7d281a6e5dcb.png) - - ### After: + ### Before: + ![image](https://user-images.githubusercontent.com/27704687/104351819-a60bcd00-54e4-11eb-8b43-7d281a6e5dcb.png) + + ### After: ![image](https://user-images.githubusercontent.com/27704687/104351632-67761280-54e4-11eb-87ba-25b940494bb5.png) - Changed success message for adding custom sound. ([#20272](https://github.com/RocketChat/Rocket.Chat/pull/20272) by [@Darshilp326](https://github.com/Darshilp326)) @@ -5166,24 +5320,24 @@ - Changed success message for ignoring member. ([#19996](https://github.com/RocketChat/Rocket.Chat/pull/19996) by [@Darshilp326](https://github.com/Darshilp326)) - Different messages for ignoring/unignoring will be displayed. - + Different messages for ignoring/unignoring will be displayed. + https://user-images.githubusercontent.com/55157259/103310307-4241c880-4a3d-11eb-8c6c-4c9b99d023db.mp4 - Creation of Omnichannel rooms not working correctly through the Apps when the agent parameter is set ([#19997](https://github.com/RocketChat/Rocket.Chat/pull/19997)) - Engagement dashboard graphs labels superposing each other ([#20267](https://github.com/RocketChat/Rocket.Chat/pull/20267)) - Now after a certain breakpoint, the graphs should stack vertically, and overlapping text rotated. - + Now after a certain breakpoint, the graphs should stack vertically, and overlapping text rotated. + ![image](https://user-images.githubusercontent.com/40830821/105098926-93b40500-5a89-11eb-9a56-2fc3b1552914.png) - Fields overflowing page ([#20287](https://github.com/RocketChat/Rocket.Chat/pull/20287)) - ### Before - ![image](https://user-images.githubusercontent.com/40830821/105246952-c1b14c00-5b52-11eb-8671-cff88edf242d.png) - - ### After + ### Before + ![image](https://user-images.githubusercontent.com/40830821/105246952-c1b14c00-5b52-11eb-8671-cff88edf242d.png) + + ### After ![image](https://user-images.githubusercontent.com/40830821/105247125-0a690500-5b53-11eb-9f3c-d6a68108e336.png) - Fix error that occurs on changing archive status of room ([#20098](https://github.com/RocketChat/Rocket.Chat/pull/20098) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) @@ -5200,7 +5354,7 @@ - Livechat.RegisterGuest method removing unset fields ([#20124](https://github.com/RocketChat/Rocket.Chat/pull/20124) by [@rafaelblink](https://github.com/rafaelblink)) - After changes made on https://github.com/RocketChat/Rocket.Chat/pull/19931, the `Livechat.RegisterGuest` method started removing properties from the visitor inappropriately. The properties that did not receive value were removed from the object. + After changes made on https://github.com/RocketChat/Rocket.Chat/pull/19931, the `Livechat.RegisterGuest` method started removing properties from the visitor inappropriately. The properties that did not receive value were removed from the object. Those changes were made to support the new Contact Form, but now the form has its own method to deal with Contact data so those changes are no longer necessary. - Markdown added for Header Room topic ([#20021](https://github.com/RocketChat/Rocket.Chat/pull/20021) by [@yash-rajpal](https://github.com/yash-rajpal)) @@ -5221,18 +5375,18 @@ - Omnichannel - Contact Center form is not validating custom fields properly ([#20196](https://github.com/RocketChat/Rocket.Chat/pull/20196) by [@rafaelblink](https://github.com/rafaelblink)) - The contact form is accepting undefined values in required custom fields when creating or editing contacts, and, the errror message isn't following Rocket.chat design system. - - ### Before - ![image](https://user-images.githubusercontent.com/2493803/104522668-31688980-55dd-11eb-92c5-83f96073edc4.png) - - ### After - - #### New - ![image](https://user-images.githubusercontent.com/2493803/104770494-68f74300-574f-11eb-94a3-c8fd73365308.png) - - - #### Edit + The contact form is accepting undefined values in required custom fields when creating or editing contacts, and, the errror message isn't following Rocket.chat design system. + + ### Before + ![image](https://user-images.githubusercontent.com/2493803/104522668-31688980-55dd-11eb-92c5-83f96073edc4.png) + + ### After + + #### New + ![image](https://user-images.githubusercontent.com/2493803/104770494-68f74300-574f-11eb-94a3-c8fd73365308.png) + + + #### Edit ![image](https://user-images.githubusercontent.com/2493803/104770538-7b717c80-574f-11eb-829f-1ae304103369.png) - Omnichannel Agents unable to take new chats in the queue ([#20022](https://github.com/RocketChat/Rocket.Chat/pull/20022) by [@rafaelblink](https://github.com/rafaelblink)) @@ -5253,15 +5407,15 @@ - Room special name in prompts ([#20277](https://github.com/RocketChat/Rocket.Chat/pull/20277) by [@aKn1ghtOut](https://github.com/aKn1ghtOut)) - The "Hide room" and "Leave Room" confirmation prompts use the "name" key from the room info. When the setting " - Allow Special Characters in Room Names" is enabled, the prompts show the normalized names instead of those that contain the special characters. - - Changed the value being used from name to fname, which always has the user-set name. - - Previous: - ![Screenshot from 2021-01-20 15-52-29](https://user-images.githubusercontent.com/38764067/105161642-9b31e780-5b37-11eb-8b0c-ec4b1414c948.png) - - Updated: + The "Hide room" and "Leave Room" confirmation prompts use the "name" key from the room info. When the setting " + Allow Special Characters in Room Names" is enabled, the prompts show the normalized names instead of those that contain the special characters. + + Changed the value being used from name to fname, which always has the user-set name. + + Previous: + ![Screenshot from 2021-01-20 15-52-29](https://user-images.githubusercontent.com/38764067/105161642-9b31e780-5b37-11eb-8b0c-ec4b1414c948.png) + + Updated: ![Screenshot from 2021-01-20 15-50-19](https://user-images.githubusercontent.com/38764067/105161627-966d3380-5b37-11eb-9812-3dd9352b4f95.png) - Room's list showing all rooms with same name ([#20176](https://github.com/RocketChat/Rocket.Chat/pull/20176)) @@ -5272,9 +5426,9 @@ - Saving with blank email in edit user ([#20259](https://github.com/RocketChat/Rocket.Chat/pull/20259) by [@RonLek](https://github.com/RonLek)) - Disallows showing a success popup when email field is made blank in Edit User and instead shows the relevant error popup. - - + Disallows showing a success popup when email field is made blank in Edit User and instead shows the relevant error popup. + + https://user-images.githubusercontent.com/28918901/104960749-dbd81680-59fa-11eb-9c7b-2b257936f894.mp4 - Search list filter ([#19937](https://github.com/RocketChat/Rocket.Chat/pull/19937)) @@ -5321,7 +5475,7 @@ - Add translation of Edit Status in all languages ([#19916](https://github.com/RocketChat/Rocket.Chat/pull/19916) by [@sushant52](https://github.com/sushant52)) - Closes [#19915](https://github.com/RocketChat/Rocket.Chat/issues/19915) + Closes [#19915](https://github.com/RocketChat/Rocket.Chat/issues/19915) The profile options menu is well translated in many languages. However, Edit Status is the only button which is not well translated. With this change, the whole profile options will be properly translated in a lot of languages. - Bump axios from 0.18.0 to 0.18.1 ([#20055](https://github.com/RocketChat/Rocket.Chat/pull/20055) by [@dependabot[bot]](https://github.com/dependabot[bot])) @@ -5356,10 +5510,10 @@ - Regression: Announcement bar not showing properly Markdown content ([#20290](https://github.com/RocketChat/Rocket.Chat/pull/20290)) - **Before**: - ![image](https://user-images.githubusercontent.com/27704687/105273746-a4907380-5b7a-11eb-8121-aff665251c44.png) - - **After**: + **Before**: + ![image](https://user-images.githubusercontent.com/27704687/105273746-a4907380-5b7a-11eb-8121-aff665251c44.png) + + **After**: ![image](https://user-images.githubusercontent.com/27704687/105274050-2e404100-5b7b-11eb-93b2-b6282a7bed95.png) - regression: Announcement link open in new tab ([#20435](https://github.com/RocketChat/Rocket.Chat/pull/20435)) @@ -5374,23 +5528,23 @@ - Regression: Change sort icon ([#20177](https://github.com/RocketChat/Rocket.Chat/pull/20177)) - ### Before - ![image](https://user-images.githubusercontent.com/40830821/104366414-1bcd6400-54f8-11eb-9fc7-c6f13f07a61e.png) - - ### After + ### Before + ![image](https://user-images.githubusercontent.com/40830821/104366414-1bcd6400-54f8-11eb-9fc7-c6f13f07a61e.png) + + ### After ![image](https://user-images.githubusercontent.com/40830821/104366542-4cad9900-54f8-11eb-83ca-acb99899515a.png) - Regression: Custom field labels are not displayed properly on Omnichannel Contact Profile form ([#20393](https://github.com/RocketChat/Rocket.Chat/pull/20393) by [@rafaelblink](https://github.com/rafaelblink)) - ### Before - ![image](https://user-images.githubusercontent.com/2493803/105780399-20116c80-5f4f-11eb-9620-0901472e453b.png) - - ![image](https://user-images.githubusercontent.com/2493803/105780420-2e5f8880-5f4f-11eb-8e93-8115ebc685be.png) - - ### After - - ![image](https://user-images.githubusercontent.com/2493803/105780832-1ccab080-5f50-11eb-8042-188dd0c41904.png) - + ### Before + ![image](https://user-images.githubusercontent.com/2493803/105780399-20116c80-5f4f-11eb-9620-0901472e453b.png) + + ![image](https://user-images.githubusercontent.com/2493803/105780420-2e5f8880-5f4f-11eb-8e93-8115ebc685be.png) + + ### After + + ![image](https://user-images.githubusercontent.com/2493803/105780832-1ccab080-5f50-11eb-8042-188dd0c41904.png) + ![image](https://user-images.githubusercontent.com/2493803/105780911-500d3f80-5f50-11eb-96e0-7df3f179dbd5.png) - Regression: ESLint Warning - explicit-function-return-type ([#20434](https://github.com/RocketChat/Rocket.Chat/pull/20434) by [@aditya-mitra](https://github.com/aditya-mitra)) @@ -5407,8 +5561,8 @@ - Regression: Fixed update room avatar issue. ([#20433](https://github.com/RocketChat/Rocket.Chat/pull/20433) by [@Darshilp326](https://github.com/Darshilp326)) - Users can now update their room avatar without any error. - + Users can now update their room avatar without any error. + https://user-images.githubusercontent.com/55157259/105951602-560d3880-6096-11eb-97a5-b5eb9a28b58d.mp4 - Regression: Info Page Icon style and usage graph breaking ([#20180](https://github.com/RocketChat/Rocket.Chat/pull/20180)) @@ -5425,11 +5579,11 @@ - Regression: Unread superposing announcement. ([#20306](https://github.com/RocketChat/Rocket.Chat/pull/20306)) - ### Before - ![image](https://user-images.githubusercontent.com/40830821/105412619-c2f67d80-5c13-11eb-8204-5932ea880c8a.png) - - - ### After + ### Before + ![image](https://user-images.githubusercontent.com/40830821/105412619-c2f67d80-5c13-11eb-8204-5932ea880c8a.png) + + + ### After ![image](https://user-images.githubusercontent.com/40830821/105411176-d1439a00-5c11-11eb-8d1b-ea27c8485214.png) - Regression: User Dropdown margin ([#20222](https://github.com/RocketChat/Rocket.Chat/pull/20222)) @@ -5717,8 +5871,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) by [@g-thome](https://github.com/g-thome)) @@ -5777,10 +5931,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)) @@ -5815,11 +5973,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)) @@ -5838,7 +5996,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) by [@g-thome](https://github.com/g-thome)) @@ -6037,8 +6195,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)) @@ -7119,8 +7277,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)) @@ -7138,7 +7298,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)) @@ -7488,13 +7648,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)) @@ -7836,10 +7999,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)) @@ -8239,11 +8402,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)) @@ -8348,9 +8511,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)) @@ -8638,14 +8804,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)) @@ -9008,7 +9179,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)) @@ -20547,4 +20718,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/api/server/v1/channels.js b/app/api/server/v1/channels.js index 8d360a5de505..832aca11ad53 100644 --- a/app/api/server/v1/channels.js +++ b/app/api/server/v1/channels.js @@ -285,9 +285,9 @@ API.v1.addRoute('channels.files', { authRequired: true }, { return file; }; - Meteor.runAsUser(this.userId, () => { - Meteor.call('canAccessRoom', findResult._id, this.userId); - }); + if (!canAccessRoom(findResult, { _id: this.userId })) { + return API.v1.unauthorized(); + } const { offset, count } = this.getPaginationItems(); const { sort, fields, query } = this.parseJsonQuery(); diff --git a/app/api/server/v1/chat.js b/app/api/server/v1/chat.js index db41290a16f3..eba0e4e3f668 100644 --- a/app/api/server/v1/chat.js +++ b/app/api/server/v1/chat.js @@ -3,7 +3,7 @@ import { Meteor } from 'meteor/meteor'; import { Match, check } from 'meteor/check'; import { Messages } from '../../../models'; -import { canAccessRoom, hasPermission } from '../../../authorization'; +import { canAccessRoom, hasPermission } from '../../../authorization/server'; import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser'; import { processWebhookMessage } from '../../../lib/server'; import { executeSendMessage } from '../../../lib/server/methods/sendMessage'; @@ -404,12 +404,12 @@ API.v1.addRoute('chat.getPinnedMessages', { authRequired: true }, { if (!roomId) { throw new Meteor.Error('error-roomId-param-not-provided', 'The required "roomId" query param is missing.'); } - const room = Meteor.call('canAccessRoom', roomId, this.userId); - if (!room) { + + if (!canAccessRoom({ _id: roomId }, { _id: this.userId })) { throw new Meteor.Error('error-not-allowed', 'Not allowed'); } - const cursor = Messages.findPinnedByRoom(room._id, { + const cursor = Messages.findPinnedByRoom(roomId, { skip: offset, limit: count, }); diff --git a/app/api/server/v1/commands.js b/app/api/server/v1/commands.js index 51059b11221e..a9f6c290d8dd 100644 --- a/app/api/server/v1/commands.js +++ b/app/api/server/v1/commands.js @@ -2,8 +2,9 @@ import { Meteor } from 'meteor/meteor'; import { Random } from 'meteor/random'; import objectPath from 'object-path'; -import { slashCommands } from '../../../utils'; -import { Messages } from '../../../models'; +import { slashCommands } from '../../../utils/server'; +import { Messages } from '../../../models/server'; +import { canAccessRoom } from '../../../authorization/server'; import { API } from '../api'; API.v1.addRoute('commands.get', { authRequired: true }, { @@ -189,8 +190,9 @@ API.v1.addRoute('commands.run', { authRequired: true }, { return API.v1.failure('The command provided does not exist (or is disabled).'); } - // This will throw an error if they can't or the room is invalid - Meteor.call('canAccessRoom', body.roomId, user._id); + if (!canAccessRoom({ _id: body.roomId }, user)) { + return API.v1.unauthorized(); + } const params = body.params ? body.params : ''; const message = { @@ -238,8 +240,9 @@ API.v1.addRoute('commands.preview', { authRequired: true }, { return API.v1.failure('The command provided does not exist (or is disabled).'); } - // This will throw an error if they can't or the room is invalid - Meteor.call('canAccessRoom', query.roomId, user._id); + if (!canAccessRoom({ _id: query.roomId }, user)) { + return API.v1.unauthorized(); + } const params = query.params ? query.params : ''; @@ -288,8 +291,9 @@ API.v1.addRoute('commands.preview', { authRequired: true }, { return API.v1.failure('The command provided does not exist (or is disabled).'); } - // This will throw an error if they can't or the room is invalid - Meteor.call('canAccessRoom', body.roomId, user._id); + if (!canAccessRoom({ _id: body.roomId }, user)) { + return API.v1.unauthorized(); + } const params = body.params ? body.params : ''; const message = { diff --git a/app/api/server/v1/im.js b/app/api/server/v1/im.js index 21d164ee862b..a0325298f3f2 100644 --- a/app/api/server/v1/im.js +++ b/app/api/server/v1/im.js @@ -2,7 +2,7 @@ import { Meteor } from 'meteor/meteor'; import { Match, check } from 'meteor/check'; import { Subscriptions, Uploads, Users, Messages, Rooms } from '../../../models/server'; -import { hasPermission } from '../../../authorization/server'; +import { canAccessRoom, hasPermission } from '../../../authorization/server'; import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser'; import { settings } from '../../../settings/server'; import { API } from '../api'; @@ -19,7 +19,7 @@ function findDirectMessageRoom(params, user, allowAdminOverride) { nameOrId: params.username || params.roomId, }); - const canAccess = Meteor.call('canAccessRoom', room._id, user._id) + const canAccess = canAccessRoom(room, user) || (allowAdminOverride && hasPermission(user._id, 'view-room-administration')); if (!canAccess || !room || room.t !== 'd') { throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "username" param provided does not match any direct message'); diff --git a/app/api/server/v1/rooms.js b/app/api/server/v1/rooms.js index eee7230a0bbf..9310ac8c7b22 100644 --- a/app/api/server/v1/rooms.js +++ b/app/api/server/v1/rooms.js @@ -65,9 +65,7 @@ API.v1.addRoute('rooms.get', { authRequired: true }, { API.v1.addRoute('rooms.upload/:rid', { authRequired: true }, { post() { - const room = Meteor.call('canAccessRoom', this.urlParams.rid, this.userId); - - if (!room) { + if (!canAccessRoom({ _id: this.urlParams.rid }, { _id: this.userId })) { return API.v1.unauthorized(); } @@ -191,9 +189,11 @@ API.v1.addRoute('rooms.info', { authRequired: true }, { get() { const room = findRoomByIdOrName({ params: this.requestParams() }); const { fields } = this.parseJsonQuery(); - if (!Meteor.call('canAccessRoom', room._id, this.userId, {})) { + + if (!room || !canAccessRoom(room, { _id: this.userId })) { return API.v1.failure('not-allowed', 'Not Allowed'); } + return API.v1.success({ room: Rooms.findOneByIdOrName(room._id, { fields }) }); }, }); @@ -244,9 +244,11 @@ API.v1.addRoute('rooms.getDiscussions', { authRequired: true }, { const room = findRoomByIdOrName({ params: this.requestParams() }); const { offset, count } = this.getPaginationItems(); const { sort, fields, query } = this.parseJsonQuery(); - if (!Meteor.call('canAccessRoom', room._id, this.userId, {})) { + + if (!room || !canAccessRoom(room, { _id: this.userId })) { return API.v1.failure('not-allowed', 'Not Allowed'); } + const ourQuery = Object.assign(query, { prid: room._id }); const discussions = Rooms.find(ourQuery, { diff --git a/app/e2e/server/methods/getUsersOfRoomWithoutKey.js b/app/e2e/server/methods/getUsersOfRoomWithoutKey.js index a686af5e88c4..2139ac8fde7e 100644 --- a/app/e2e/server/methods/getUsersOfRoomWithoutKey.js +++ b/app/e2e/server/methods/getUsersOfRoomWithoutKey.js @@ -1,16 +1,23 @@ import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; -import { Subscriptions, Users } from '../../../models'; +import { canAccessRoom } from '../../../authorization/server'; +import { Subscriptions, Users } from '../../../models/server'; Meteor.methods({ 'e2e.getUsersOfRoomWithoutKey'(rid) { + check(rid, String); + const userId = Meteor.userId(); if (!userId) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'e2e.getUsersOfRoomWithoutKey' }); } - const room = Meteor.call('canAccessRoom', rid, userId); - if (!room) { + if (!rid) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'e2e.getUsersOfRoomWithoutKey' }); + } + + if (!canAccessRoom({ _id: rid }, { _id: userId })) { throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'e2e.getUsersOfRoomWithoutKey' }); } diff --git a/app/e2e/server/methods/setRoomKeyID.js b/app/e2e/server/methods/setRoomKeyID.js index a273e803b934..e2f8aafa059b 100644 --- a/app/e2e/server/methods/setRoomKeyID.js +++ b/app/e2e/server/methods/setRoomKeyID.js @@ -1,19 +1,29 @@ import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; -import { Rooms } from '../../../models'; +import { canAccessRoom } from '../../../authorization/server'; +import { Rooms } from '../../../models/server'; Meteor.methods({ 'e2e.setRoomKeyID'(rid, keyID) { + check(rid, String); + check(keyID, String); + const userId = Meteor.userId(); if (!userId) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'e2e.setRoomKeyID' }); } - const room = Meteor.call('canAccessRoom', rid, userId); - if (!room) { + if (!rid) { throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'e2e.setRoomKeyID' }); } + if (!canAccessRoom({ _id: rid }, { _id: userId })) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'e2e.setRoomKeyID' }); + } + + const room = Rooms.findOneById(rid, { fields: { e2eKeyId: 1 } }); + if (room.e2eKeyId) { throw new Meteor.Error('error-room-e2e-key-already-exists', 'E2E Key ID already exists', { method: 'e2e.setRoomKeyID' }); } diff --git a/app/lib/server/lib/processDirectEmail.js b/app/lib/server/lib/processDirectEmail.js index 3b97938d4694..98313697028f 100644 --- a/app/lib/server/lib/processDirectEmail.js +++ b/app/lib/server/lib/processDirectEmail.js @@ -5,7 +5,7 @@ import moment from 'moment'; import { settings } from '../../../settings/server'; import { Rooms, Messages, Users, Subscriptions } from '../../../models/server'; import { metrics } from '../../../metrics/server'; -import { hasPermission } from '../../../authorization/server'; +import { canAccessRoom, hasPermission } from '../../../authorization/server'; import { SystemLogger } from '../../../../server/lib/logger/system'; import { sendMessage as _sendMessage } from '../functions'; @@ -55,29 +55,25 @@ export const processDirectEmail = function(email) { } message.rid = prevMessage.rid; - const room = Meteor.call('canAccessRoom', message.rid, user._id); - if (!room) { + const room = Rooms.findOneById(message.rid); + + if (!canAccessRoom(room, user)) { return false; } - const roomInfo = Rooms.findOneById(message.rid, { - t: 1, - name: 1, - }); - // check mention - if (message.msg.indexOf(`@${ prevMessage.u.username }`) === -1 && roomInfo.t !== 'd') { + if (message.msg.indexOf(`@${ prevMessage.u.username }`) === -1 && room.t !== 'd') { message.msg = `@${ prevMessage.u.username } ${ message.msg }`; } // reply message link let prevMessageLink = `[ ](${ Meteor.absoluteUrl().replace(/\/$/, '') }`; - if (roomInfo.t === 'c') { - prevMessageLink += `/channel/${ roomInfo.name }?msg=${ email.headers.mid }) `; - } else if (roomInfo.t === 'd') { + if (room.t === 'c') { + prevMessageLink += `/channel/${ room.name }?msg=${ email.headers.mid }) `; + } else if (room.t === 'd') { prevMessageLink += `/direct/${ prevMessage.u.username }?msg=${ email.headers.mid }) `; - } else if (roomInfo.t === 'p') { - prevMessageLink += `/group/${ roomInfo.name }?msg=${ email.headers.mid }) `; + } else if (room.t === 'p') { + prevMessageLink += `/group/${ room.name }?msg=${ email.headers.mid }) `; } // add reply message link message.msg = prevMessageLink + message.msg; diff --git a/app/lib/server/methods/getChannelHistory.js b/app/lib/server/methods/getChannelHistory.js index 25c645231038..80237842b118 100644 --- a/app/lib/server/methods/getChannelHistory.js +++ b/app/lib/server/methods/getChannelHistory.js @@ -2,8 +2,8 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; import _ from 'underscore'; -import { hasPermission } from '../../../authorization/server'; -import { Subscriptions, Messages } from '../../../models/server'; +import { canAccessRoom, hasPermission } from '../../../authorization/server'; +import { Subscriptions, Messages, Rooms } from '../../../models/server'; import { settings } from '../../../settings/server'; import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser'; import { getHiddenSystemMessages } from '../lib/getHiddenSystemMessages'; @@ -17,11 +17,15 @@ Meteor.methods({ } const fromUserId = Meteor.userId(); - const room = Meteor.call('canAccessRoom', rid, fromUserId); + const room = Rooms.findOneById(rid); if (!room) { return false; } + if (!canAccessRoom(room, { _id: fromUserId })) { + return false; + } + // Make sure they can access the room if (room.t === 'c' && !hasPermission(fromUserId, 'preview-c-room') && !Subscriptions.findOneByRoomIdAndUserId(rid, fromUserId, { fields: { _id: 1 } })) { return false; diff --git a/app/lib/server/methods/getMessages.js b/app/lib/server/methods/getMessages.js index d4b3ce4bd20a..f8ccbbbb6f74 100644 --- a/app/lib/server/methods/getMessages.js +++ b/app/lib/server/methods/getMessages.js @@ -1,28 +1,22 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Messages } from '../../../models'; +import { canAccessRoom } from '../../../authorization/server'; +import { Messages } from '../../../models/server'; Meteor.methods({ getMessages(messages) { check(messages, [String]); - const cache = {}; + const msgs = Messages.findVisibleByIds(messages).fetch(); - return messages.map((msgId) => { - const msg = Messages.findOneById(msgId); + const user = { _id: Meteor.userId() }; - if (!msg || !msg.rid) { - return undefined; - } + const rids = [...new Set(msgs.map((m) => m.rid))]; + if (!rids.every((_id) => canAccessRoom({ _id }, user))) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getSingleMessage' }); + } - cache[msg.rid] = cache[msg.rid] || Meteor.call('canAccessRoom', msg.rid, Meteor.userId()); - - if (!cache[msg.rid]) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getSingleMessage' }); - } - - return msg; - }); + return msgs; }, }); diff --git a/app/lib/server/methods/getSingleMessage.js b/app/lib/server/methods/getSingleMessage.js index 399aa335cab3..604ac2f1b4f7 100644 --- a/app/lib/server/methods/getSingleMessage.js +++ b/app/lib/server/methods/getSingleMessage.js @@ -1,7 +1,8 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Messages } from '../../../models'; +import { canAccessRoom } from '../../../authorization/server'; +import { Messages } from '../../../models/server'; Meteor.methods({ getSingleMessage(msgId) { @@ -13,7 +14,7 @@ Meteor.methods({ return undefined; } - if (!Meteor.call('canAccessRoom', msg.rid, Meteor.userId())) { + if (!canAccessRoom({ _id: msg.rid }, { _id: Meteor.userId() })) { throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getSingleMessage' }); } diff --git a/app/livechat/client/views/app/livechatReadOnly.js b/app/livechat/client/views/app/livechatReadOnly.js index c751c701e9ea..74dce229f25c 100644 --- a/app/livechat/client/views/app/livechatReadOnly.js +++ b/app/livechat/client/views/app/livechatReadOnly.js @@ -64,7 +64,7 @@ Template.livechatReadOnly.onCreated(function() { this.preparing = new ReactiveVar(true); this.updateInquiry = async ({ clientAction, ...inquiry }) => { - if (clientAction === 'removed' || !await callWithErrorHandling('canAccessRoom', inquiry.rid, Meteor.userId())) { + if (clientAction === 'removed') { // this will force to refresh the room // since the client wont get notified of room changes when chats are on queue (no one assigned) // a better approach should be performed when refactoring these templates to use react diff --git a/app/message-pin/server/pinMessage.js b/app/message-pin/server/pinMessage.js index 4543496ad2a0..545a350b7d6a 100644 --- a/app/message-pin/server/pinMessage.js +++ b/app/message-pin/server/pinMessage.js @@ -1,11 +1,11 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { settings } from '../../settings'; -import { callbacks } from '../../callbacks'; -import { isTheLastMessage } from '../../lib'; +import { settings } from '../../settings/server'; +import { callbacks } from '../../callbacks/server'; +import { isTheLastMessage } from '../../lib/server'; import { getUserAvatarURL } from '../../utils/lib/getUserAvatarURL'; -import { hasPermission } from '../../authorization'; +import { canAccessRoom, hasPermission } from '../../authorization/server'; import { Subscriptions, Messages, Users, Rooms } from '../../models'; const recursiveRemove = (msg, deep = 1) => { @@ -72,7 +72,11 @@ Meteor.methods({ if (settings.get('Message_KeepHistory')) { Messages.cloneAndSaveAsHistoryById(message._id, me); } - const room = Meteor.call('canAccessRoom', originalMessage.rid, Meteor.userId()); + + const room = Rooms.findOneById(originalMessage.rid); + if (!canAccessRoom(room, { _id: Meteor.userId() })) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'pinMessage' }); + } originalMessage.pinned = true; originalMessage.pinnedAt = pinnedAt || Date.now; @@ -166,7 +170,12 @@ Meteor.methods({ username: me.username, }; originalMessage = callbacks.run('beforeSaveMessage', originalMessage); - const room = Meteor.call('canAccessRoom', originalMessage.rid, Meteor.userId()); + + const room = Rooms.findOneById(originalMessage.rid, { fields: { lastMessage: 1 } }); + if (!canAccessRoom(room, { _id: Meteor.userId() })) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'unpinMessage' }); + } + if (isTheLastMessage(room, message)) { Rooms.setLastMessagePinned(room._id, originalMessage.pinnedBy, originalMessage.pinned); } diff --git a/app/message-star/server/starMessage.js b/app/message-star/server/starMessage.js index 4d22d6727835..097b640f31ef 100644 --- a/app/message-star/server/starMessage.js +++ b/app/message-star/server/starMessage.js @@ -1,8 +1,9 @@ import { Meteor } from 'meteor/meteor'; -import { settings } from '../../settings'; -import { isTheLastMessage } from '../../lib'; -import { Subscriptions, Rooms, Messages } from '../../models'; +import { settings } from '../../settings/server'; +import { isTheLastMessage } from '../../lib/server'; +import { canAccessRoom } from '../../authorization/server'; +import { Subscriptions, Rooms, Messages } from '../../models/server'; Meteor.methods({ starMessage(message) { @@ -26,7 +27,12 @@ Meteor.methods({ if (!Messages.findOneByRoomIdAndMessageId(message.rid, message._id)) { return false; } - const room = Meteor.call('canAccessRoom', message.rid, Meteor.userId()); + + const room = Rooms.findOneById(message.rid, { fields: { lastMessage: 1 } }); + if (!canAccessRoom(room, { _id: Meteor.userId() })) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'starMessage' }); + } + if (isTheLastMessage(room, message)) { Rooms.updateLastMessageStar(room._id, Meteor.userId(), message.starred); } diff --git a/app/models/server/models/Messages.js b/app/models/server/models/Messages.js index de09ad1c0b04..3bfff331c4ef 100644 --- a/app/models/server/models/Messages.js +++ b/app/models/server/models/Messages.js @@ -246,6 +246,17 @@ export class Messages extends Base { return this.find(query, options); } + findVisibleByIds(ids, options) { + const query = { + _id: { $in: ids }, + _hidden: { + $ne: true, + }, + }; + + return this.find(query, options); + } + findVisibleThreadByThreadId(tmid, options) { const query = { _hidden: { diff --git a/app/reactions/server/setReaction.js b/app/reactions/server/setReaction.js index 53de3fe70c1f..279e4e813d88 100644 --- a/app/reactions/server/setReaction.js +++ b/app/reactions/server/setReaction.js @@ -2,11 +2,11 @@ import { Meteor } from 'meteor/meteor'; import { TAPi18n } from 'meteor/rocketchat:tap-i18n'; import _ from 'underscore'; -import { Messages, EmojiCustom, Rooms } from '../../models'; -import { callbacks } from '../../callbacks'; -import { emoji } from '../../emoji'; -import { isTheLastMessage, msgStream } from '../../lib'; -import { hasPermission } from '../../authorization/server/functions/hasPermission'; +import { Messages, EmojiCustom, Rooms } from '../../models/server'; +import { callbacks } from '../../callbacks/server'; +import { emoji } from '../../emoji/server'; +import { isTheLastMessage, msgStream } from '../../lib/server'; +import { canAccessRoom, hasPermission } from '../../authorization/server'; import { api } from '../../../server/sdk/api'; const removeUserReaction = (message, reaction, username) => { @@ -91,17 +91,19 @@ export const executeSetReaction = async function(reaction, messageId, shouldReac } const message = Messages.findOneById(messageId); - if (!message) { throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'setReaction' }); } - const room = Meteor.call('canAccessRoom', message.rid, Meteor.userId()); - + const room = Rooms.findOneById(message.rid); if (!room) { throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'setReaction' }); } + if (!canAccessRoom(room, user)) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'setReaction' }); + } + return setReaction(room, user, message, reaction, shouldReact); }; diff --git a/app/search/server/service/validationService.js b/app/search/server/service/validationService.js index 633d88b7697e..120207bd0e97 100644 --- a/app/search/server/service/validationService.js +++ b/app/search/server/service/validationService.js @@ -1,42 +1,46 @@ import { Meteor } from 'meteor/meteor'; +import mem from 'mem'; import SearchLogger from '../logger/logger'; -import { Users } from '../../../models'; +import { canAccessRoom } from '../../../authorization/server'; +import { Users, Rooms } from '../../../models/server'; class ValidationService { validateSearchResult(result) { - const subscriptionCache = {}; + const getSubscription = mem((rid, uid) => { + if (!rid) { + return; + } - const getSubscription = (rid, uid) => { - if (!subscriptionCache.hasOwnProperty(rid)) { - subscriptionCache[rid] = Meteor.call('canAccessRoom', rid, uid); + const room = Rooms.findOneById(rid); + if (!room) { + return; } - return subscriptionCache[rid]; - }; + if (!canAccessRoom(room, { _id: uid })) { + return; + } - const userCache = {}; + return room; + }); - const getUsername = (uid) => { - if (!userCache.hasOwnProperty(uid)) { - try { - userCache[uid] = Users.findById(uid).fetch()[0].username; - } catch (e) { - userCache[uid] = undefined; - } + const getUser = mem((uid) => { + if (!uid) { + return; } - return userCache[uid]; - }; + return Users.findOneById(uid, { fields: { username: 1 } }); + }); const uid = Meteor.userId(); // get subscription for message if (result.message) { result.message.docs.forEach((msg) => { + const user = getUser(msg.user); const subscription = getSubscription(msg.rid, uid); if (subscription) { msg.r = { name: subscription.name, t: subscription.t }; - msg.username = getUsername(msg.user); + msg.username = user?.username; msg.valid = true; SearchLogger.debug(`user ${ uid } can access ${ msg.rid } ( ${ subscription.t === 'd' ? subscription.username : subscription.name } )`); } else { @@ -44,7 +48,7 @@ class ValidationService { } }); - result.message.docs.filter((msg) => msg.valid); + result.message.docs = result.message.docs.filter((msg) => msg.valid); } if (result.room) { @@ -60,7 +64,7 @@ class ValidationService { } }); - result.room.docs.filter((room) => room.valid); + result.room.docs = result.room.docs.filter((room) => room.valid); } return result; diff --git a/app/threads/server/methods/followMessage.js b/app/threads/server/methods/followMessage.js index 4ab2e59e2945..642c32e3b633 100644 --- a/app/threads/server/methods/followMessage.js +++ b/app/threads/server/methods/followMessage.js @@ -4,6 +4,7 @@ import { check } from 'meteor/check'; import { Messages } from '../../../models/server'; import { RateLimiter } from '../../../lib/server'; import { settings } from '../../../settings/server'; +import { canAccessRoom } from '../../../authorization/server'; import { follow } from '../functions'; Meteor.methods({ @@ -24,8 +25,7 @@ Meteor.methods({ throw new Meteor.Error('error-invalid-message', 'Invalid message', { method: 'followMessage' }); } - const room = Meteor.call('canAccessRoom', message.rid, uid); - if (!room) { + if (!canAccessRoom({ _id: message.rid }, { _id: uid })) { throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'followMessage' }); } diff --git a/app/threads/server/methods/unfollowMessage.js b/app/threads/server/methods/unfollowMessage.js index 743d9bd5e719..a5ed0fa50c6a 100644 --- a/app/threads/server/methods/unfollowMessage.js +++ b/app/threads/server/methods/unfollowMessage.js @@ -4,6 +4,7 @@ import { check } from 'meteor/check'; import { Messages } from '../../../models/server'; import { RateLimiter } from '../../../lib/server'; import { settings } from '../../../settings/server'; +import { canAccessRoom } from '../../../authorization/server'; import { unfollow } from '../functions'; Meteor.methods({ @@ -21,12 +22,11 @@ Meteor.methods({ const message = Messages.findOneById(mid, { fields: { rid: 1, tmid: 1 } }); if (!message) { - throw new Meteor.Error('error-invalid-message', 'Invalid message', { method: 'followMessage' }); + throw new Meteor.Error('error-invalid-message', 'Invalid message', { method: 'unfollowMessage' }); } - const room = Meteor.call('canAccessRoom', message.rid, uid); - if (!room) { - throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'followMessage' }); + if (!canAccessRoom({ _id: message.rid }, { _id: uid })) { + throw new Meteor.Error('error-not-allowed', 'not-allowed', { method: 'unfollowMessage' }); } return unfollow({ rid: message.rid, tmid: message.tmid || message._id, uid }); diff --git a/app/utils/rocketchat.info b/app/utils/rocketchat.info index b3e4de0fd745..e0d8e5906fd7 100644 --- a/app/utils/rocketchat.info +++ b/app/utils/rocketchat.info @@ -1,3 +1,3 @@ { - "version": "4.1.0" + "version": "4.1.1" } diff --git a/app/videobridge/server/methods/bbb.js b/app/videobridge/server/methods/bbb.js index 4721dc9842ce..d4c4db288e32 100644 --- a/app/videobridge/server/methods/bbb.js +++ b/app/videobridge/server/methods/bbb.js @@ -1,5 +1,6 @@ import { Meteor } from 'meteor/meteor'; import { HTTP } from 'meteor/http'; +import { check } from 'meteor/check'; import xml2js from 'xml2js'; import BigBlueButtonApi from '../../../bigbluebutton/server'; @@ -7,6 +8,7 @@ import { SystemLogger } from '../../../../server/lib/logger/system'; import { settings } from '../../../settings/server'; import { Rooms, Users } from '../../../models/server'; import { saveStreamingOptions } from '../../../channel-settings/server'; +import { canAccessRoom } from '../../../authorization/server'; import { API } from '../../../api/server'; const parser = new xml2js.Parser({ @@ -24,11 +26,27 @@ const getBBBAPI = () => { Meteor.methods({ bbbJoin({ rid }) { + check(rid, String); + if (!this.userId) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'bbbJoin' }); } - if (!Meteor.call('canAccessRoom', rid, this.userId)) { + if (!rid) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'bbbJoin' }); + } + + const user = Users.findOneById(this.userId); + if (!user) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'bbbJoin' }); + } + + const room = Rooms.findOneById(rid); + if (!room) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'bbbJoin' }); + } + + if (!canAccessRoom(room, user)) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'bbbJoin' }); } @@ -38,7 +56,6 @@ Meteor.methods({ const { api } = getBBBAPI(); const meetingID = settings.get('uniqueID') + rid; - const room = Rooms.findOneById(rid); const createUrl = api.urlFor('create', { name: room.t === 'd' ? 'Direct' : room.name, meetingID, @@ -56,8 +73,6 @@ Meteor.methods({ const doc = parseString(createResult.content); if (doc.response.returncode[0]) { - const user = Users.findOneById(this.userId); - const hookApi = api.urlFor('hooks/create', { meetingID, callbackURL: Meteor.absoluteUrl(`api/v1/videoconference.bbb.update/${ meetingID }`), @@ -90,11 +105,17 @@ Meteor.methods({ }, bbbEnd({ rid }) { + check(rid, String); + if (!this.userId) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'bbbEnd' }); } - if (!Meteor.call('canAccessRoom', rid, this.userId)) { + if (!rid) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'bbbEnd' }); + } + + if (!canAccessRoom({ _id: rid }, { _id: this.userId })) { throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'bbbEnd' }); } diff --git a/imports/message-read-receipt/server/api/methods/getReadReceipts.js b/imports/message-read-receipt/server/api/methods/getReadReceipts.js index f73448b92d3c..e13647249217 100644 --- a/imports/message-read-receipt/server/api/methods/getReadReceipts.js +++ b/imports/message-read-receipt/server/api/methods/getReadReceipts.js @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; -import { Messages } from '../../../../../app/models'; +import { Messages } from '../../../../../app/models/server'; +import { canAccessRoom } from '../../../../../app/authorization/server'; import { ReadReceipt } from '../../lib/ReadReceipt'; Meteor.methods({ @@ -19,8 +20,7 @@ Meteor.methods({ throw new Meteor.Error('error-invalid-message', 'Invalid message', { method: 'getReadReceipts' }); } - const room = Meteor.call('canAccessRoom', message.rid, Meteor.userId()); - if (!room) { + if (!canAccessRoom({ _id: message.rid }, { _id: Meteor.userId() })) { throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getReadReceipts' }); } diff --git a/package-lock.json b/package-lock.json index 53f2e0e0cd55..01bb93f30fec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "Rocket.Chat", - "version": "4.1.0", + "version": "4.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c15b83db3a55..d0240cf5e594 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Rocket.Chat", "description": "The Ultimate Open Source WebChat Platform", - "version": "4.1.0", + "version": "4.1.1", "author": { "name": "Rocket.Chat", "url": "https://rocket.chat/" diff --git a/server/methods/canAccessRoom.js b/server/methods/canAccessRoom.js index 7aa3e637a867..4b1f7b28098c 100644 --- a/server/methods/canAccessRoom.js +++ b/server/methods/canAccessRoom.js @@ -5,54 +5,57 @@ import { Users, Rooms } from '../../app/models/server'; import { canAccessRoom } from '../../app/authorization/server'; import { settings } from '../../app/settings/server'; -Meteor.methods({ - canAccessRoom(rid, userId, extraData) { - check(rid, String); - check(userId, Match.Maybe(String)); - - let user; +if (['yes', 'true'].includes(String(process.env.ALLOW_CANACCESSROOM_METHOD).toLowerCase())) { + console.warn('Method canAccessRoom is deprecated and will be removed after version 5.0'); + Meteor.methods({ + canAccessRoom(rid, userId, extraData) { + check(rid, String); + check(userId, Match.Maybe(String)); + + let user; + + if (userId) { + user = Users.findOneById(userId, { + fields: { + username: 1, + }, + }); - if (userId) { - user = Users.findOneById(userId, { - fields: { - username: 1, - }, - }); + if (!user || !user.username) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'canAccessRoom', + }); + } + } - if (!user || !user.username) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { + if (!rid) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'canAccessRoom', }); } - } - if (!rid) { - throw new Meteor.Error('error-invalid-room', 'Invalid room', { - method: 'canAccessRoom', - }); - } + const room = Rooms.findOneById(rid); - const room = Rooms.findOneById(rid); + if (!room) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { + method: 'canAccessRoom', + }); + } - if (!room) { - throw new Meteor.Error('error-invalid-room', 'Invalid room', { - method: 'canAccessRoom', - }); - } + if (canAccessRoom.call(this, room, user, extraData)) { + if (user) { + room.username = user.username; + } + return room; + } - if (canAccessRoom.call(this, room, user, extraData)) { - if (user) { - room.username = user.username; + if (!userId && settings.get('Accounts_AllowAnonymousRead') === false) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'canAccessRoom', + }); } - return room; - } - - if (!userId && settings.get('Accounts_AllowAnonymousRead') === false) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { - method: 'canAccessRoom', - }); - } - - return false; - }, -}); + + return false; + }, + }); +} diff --git a/server/methods/getUsersOfRoom.js b/server/methods/getUsersOfRoom.js index d17d91013cb6..7a97eb194ee3 100644 --- a/server/methods/getUsersOfRoom.js +++ b/server/methods/getUsersOfRoom.js @@ -1,7 +1,7 @@ import { Meteor } from 'meteor/meteor'; -import { Subscriptions } from '../../app/models/server'; -import { hasPermission } from '../../app/authorization/server'; +import { Subscriptions, Rooms } from '../../app/models/server'; +import { canAccessRoom, hasPermission } from '../../app/authorization/server'; import { findUsersOfRoom } from '../lib/findUsersOfRoom'; Meteor.methods({ @@ -11,11 +11,19 @@ Meteor.methods({ throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getUsersOfRoom' }); } - const room = Meteor.call('canAccessRoom', rid, userId); - if (!room) { + if (!rid) { throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getUsersOfRoom' }); } + const room = Rooms.findOneById(rid, { fields: { broadcast: 1 } }); + if (!room) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getUsersOfRoom' }); + } + + if (!canAccessRoom(room, { _id: userId })) { + throw new Meteor.Error('not-authorized', 'Not Authorized', { method: 'getUsersOfRoom' }); + } + if (room.broadcast && !hasPermission(userId, 'view-broadcast-member-list', rid)) { throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getUsersOfRoom' }); } diff --git a/server/methods/loadHistory.js b/server/methods/loadHistory.js index 9302a8209f22..55096be4df9f 100644 --- a/server/methods/loadHistory.js +++ b/server/methods/loadHistory.js @@ -1,9 +1,9 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Subscriptions } from '../../app/models'; -import { hasPermission } from '../../app/authorization'; -import { settings } from '../../app/settings'; +import { Subscriptions, Rooms } from '../../app/models/server'; +import { canAccessRoom, hasPermission } from '../../app/authorization/server'; +import { settings } from '../../app/settings/server'; import { loadMessageHistory } from '../../app/lib/server'; Meteor.methods({ @@ -17,7 +17,15 @@ Meteor.methods({ } const fromId = Meteor.userId(); - const room = Meteor.call('canAccessRoom', rid, fromId); + + const room = Rooms.findOneById(rid, { fields: { t: 1 } }); + if (!room) { + return false; + } + + if (!canAccessRoom(room, { _id: fromId })) { + return false; + } if (!room) { return false; diff --git a/server/methods/loadMissedMessages.js b/server/methods/loadMissedMessages.js index bad55e3f5bf3..1c94d33c3cad 100644 --- a/server/methods/loadMissedMessages.js +++ b/server/methods/loadMissedMessages.js @@ -1,8 +1,9 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Messages } from '../../app/models'; -import { settings } from '../../app/settings'; +import { canAccessRoom } from '../../app/authorization/server'; +import { Messages } from '../../app/models/server'; +import { settings } from '../../app/settings/server'; Meteor.methods({ loadMissedMessages(rid, start) { @@ -10,7 +11,12 @@ Meteor.methods({ check(start, Date); const fromId = Meteor.userId(); - if (!Meteor.call('canAccessRoom', rid, fromId)) { + + if (!rid) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getUsersOfRoom' }); + } + + if (!canAccessRoom({ _id: rid }, { _id: fromId })) { return false; } diff --git a/server/methods/loadNextMessages.js b/server/methods/loadNextMessages.js index 7136447873e4..bc7589eae118 100644 --- a/server/methods/loadNextMessages.js +++ b/server/methods/loadNextMessages.js @@ -1,8 +1,9 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Messages } from '../../app/models'; -import { settings } from '../../app/settings'; +import { canAccessRoom } from '../../app/authorization/server'; +import { Messages } from '../../app/models/server'; +import { settings } from '../../app/settings/server'; import { normalizeMessagesForUser } from '../../app/utils/server/lib/normalizeMessagesForUser'; Meteor.methods({ @@ -16,9 +17,13 @@ Meteor.methods({ }); } + if (!rid) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'loadNextMessages' }); + } + const fromId = Meteor.userId(); - if (!Meteor.call('canAccessRoom', rid, fromId)) { + if (!canAccessRoom({ _id: rid }, { _id: fromId })) { return false; } diff --git a/server/methods/loadSurroundingMessages.js b/server/methods/loadSurroundingMessages.js index 180f9f4b3e16..c784c8350909 100644 --- a/server/methods/loadSurroundingMessages.js +++ b/server/methods/loadSurroundingMessages.js @@ -1,8 +1,9 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Messages } from '../../app/models'; -import { settings } from '../../app/settings'; +import { canAccessRoom } from '../../app/authorization/server'; +import { Messages } from '../../app/models/server'; +import { settings } from '../../app/settings/server'; import { normalizeMessagesForUser } from '../../app/utils/server/lib/normalizeMessagesForUser'; Meteor.methods({ @@ -28,7 +29,7 @@ Meteor.methods({ return false; } - if (!Meteor.call('canAccessRoom', message.rid, fromId)) { + if (!canAccessRoom({ _id: message.rid }, { _id: fromId })) { return false; } diff --git a/server/methods/messageSearch.js b/server/methods/messageSearch.js index d03bf00cb8af..72ed6a304eea 100644 --- a/server/methods/messageSearch.js +++ b/server/methods/messageSearch.js @@ -2,9 +2,10 @@ import { Meteor } from 'meteor/meteor'; import { Match, check } from 'meteor/check'; import { escapeRegExp } from '@rocket.chat/string-helpers'; +import { canAccessRoom } from '../../app/authorization/server'; import { Subscriptions } from '../../app/models/server'; import { Messages } from '../../app/models/server/raw'; -import { settings } from '../../app/settings'; +import { settings } from '../../app/settings/server'; import { readSecondaryPreferred } from '../database/readSecondaryPreferred'; Meteor.methods({ @@ -30,8 +31,8 @@ Meteor.methods({ // Don't process anything else if the user can't access the room if (rid) { - if (!Meteor.call('canAccessRoom', rid, currentUserId)) { - return result; + if (!canAccessRoom({ _id: rid }, { _id: currentUserId })) { + return false; } } else if (settings.get('Search.defaultProvider.GlobalSearchEnabled') !== true) { return result; diff --git a/server/publications/messages.js b/server/publications/messages.js index 6b2f1af649c3..8ff0aa462211 100644 --- a/server/publications/messages.js +++ b/server/publications/messages.js @@ -1,7 +1,8 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Messages } from '../../app/models'; +import { canAccessRoom } from '../../app/authorization/server'; +import { Messages } from '../../app/models/server'; Meteor.methods({ 'messages/get'(rid, { lastUpdate, latestDate = new Date(), oldestDate, inclusive = false, count = 20, unreads = false }) { @@ -15,7 +16,11 @@ Meteor.methods({ }); } - if (!Meteor.call('canAccessRoom', rid, fromId)) { + if (!rid) { + throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'messages/get' }); + } + + if (!canAccessRoom({ _id: rid }, { _id: fromId })) { throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'messages/get', }); diff --git a/server/publications/room/index.js b/server/publications/room/index.js index b31c33610e26..1756623ba73f 100644 --- a/server/publications/room/index.js +++ b/server/publications/room/index.js @@ -1,10 +1,10 @@ import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; -import { roomTypes } from '../../../app/utils'; -import { hasPermission } from '../../../app/authorization'; -import { Rooms } from '../../../app/models'; -import { settings } from '../../../app/settings'; +import { roomTypes } from '../../../app/utils/server'; +import { canAccessRoom, hasPermission } from '../../../app/authorization/server'; +import { Rooms } from '../../../app/models/server'; +import { settings } from '../../../app/settings/server'; import { roomFields } from '../../modules/watchers/publishFields'; const roomMap = (record) => { @@ -51,7 +51,7 @@ Meteor.methods({ throw new Meteor.Error('error-invalid-room', 'Invalid room', { method: 'getRoomByTypeAndName' }); } - if (!Meteor.call('canAccessRoom', room._id, userId)) { + if (!canAccessRoom(room, { _id: userId })) { throw new Meteor.Error('error-no-permission', 'No permission', { method: 'getRoomByTypeAndName' }); } diff --git a/tests/end-to-end/api/05-chat.js b/tests/end-to-end/api/05-chat.js index d63bd228aa73..84941df7bae7 100644 --- a/tests/end-to-end/api/05-chat.js +++ b/tests/end-to-end/api/05-chat.js @@ -750,7 +750,7 @@ describe('[Chat]', function() { .to.have.string('