diff --git a/.changeset/tame-dolls-know.md b/.changeset/tame-dolls-know.md new file mode 100644 index 0000000000000..def199bd02af3 --- /dev/null +++ b/.changeset/tame-dolls-know.md @@ -0,0 +1,5 @@ +--- +"@rocket.chat/meteor": patch +--- + +Fixes message toolbar showing in End-to-end encrypted room when messages are not decrypted diff --git a/apps/meteor/app/api/server/v1/groups.ts b/apps/meteor/app/api/server/v1/groups.ts index f2339b0a79c3b..64ad8e41150d9 100644 --- a/apps/meteor/app/api/server/v1/groups.ts +++ b/apps/meteor/app/api/server/v1/groups.ts @@ -1,6 +1,7 @@ import { Team, isMeteorError } from '@rocket.chat/core-services'; import type { IIntegration, IUser, IRoom, RoomType } from '@rocket.chat/core-typings'; import { Integrations, Messages, Rooms, Subscriptions, Uploads, Users } from '@rocket.chat/models'; +import { isGroupsOnlineProps } from '@rocket.chat/rest-typings'; import { check, Match } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; import type { Filter } from 'mongodb'; @@ -779,23 +780,28 @@ API.v1.addRoute( // TODO: CACHE: same as channels.online API.v1.addRoute( 'groups.online', - { authRequired: true }, + { authRequired: true, validateParams: isGroupsOnlineProps }, { async get() { const { query } = await this.parseJsonQuery(); - if (!query || Object.keys(query).length === 0) { + const { _id } = this.queryParams; + + if ((!query || Object.keys(query).length === 0) && !_id) { return API.v1.failure('Invalid query'); } - const ourQuery = Object.assign({}, query, { t: 'p' }); - - const room = await Rooms.findOne(ourQuery as Record); + const filter = { + ...query, + ...(_id ? { _id } : {}), + t: 'p', + }; + const room = await Rooms.findOne(filter as Record); if (!room) { return API.v1.failure('Group does not exists'); } - const user = await getLoggedInUser(this.request); + const user = await getLoggedInUser(this.request); if (!user) { return API.v1.failure('User does not exists'); } diff --git a/apps/meteor/client/components/message/variants/RoomMessage.tsx b/apps/meteor/client/components/message/variants/RoomMessage.tsx index dd36dfa3eaff2..bf5c12a9a6dd2 100644 --- a/apps/meteor/client/components/message/variants/RoomMessage.tsx +++ b/apps/meteor/client/components/message/variants/RoomMessage.tsx @@ -110,7 +110,7 @@ const RoomMessage = ({ )} - {!message.private && } + {!message.private && message?.e2e !== 'pending' && } ); }; diff --git a/apps/meteor/tests/e2e/e2e-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption.spec.ts index d92ddad1d5f36..4446422d295a7 100644 --- a/apps/meteor/tests/e2e/e2e-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption.spec.ts @@ -420,6 +420,9 @@ test.describe.serial('e2e-encryption', () => { 'This message is end-to-end encrypted. To view it, you must enter your encryption key in your account settings.', ); await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await poHomeChannel.content.lastUserMessage.hover(); + await expect(page.locator('[role=toolbar][aria-label="Message actions"]')).not.toBeVisible(); }); test('expect placeholder text in place of encrypted file description, when E2EE is not setup and non-encrypted files upload in disabled e2ee room', async ({ diff --git a/apps/meteor/tests/end-to-end/api/groups.ts b/apps/meteor/tests/end-to-end/api/groups.ts index 3e4ed0d86c268..9e7630bc5a0e4 100644 --- a/apps/meteor/tests/end-to-end/api/groups.ts +++ b/apps/meteor/tests/end-to-end/api/groups.ts @@ -1119,7 +1119,9 @@ describe('[Groups]', () => { it('should return an array with online members', async () => { const { testUser, testUserCredentials, room } = await createUserAndChannel(); - const response = await request.get(api('groups.online')).set(testUserCredentials).query(`query={"_id": "${room._id}"}`); + const response = await request.get(api('groups.online')).set(testUserCredentials).query({ + _id: room._id, + }); const { body } = response; @@ -1134,7 +1136,9 @@ describe('[Groups]', () => { it('should return an empty array if members are offline', async () => { const { testUserCredentials, room } = await createUserAndChannel(false); - const response = await request.get(api('groups.online')).set(testUserCredentials).query(`query={"_id": "${room._id}"}`); + const response = await request.get(api('groups.online')).set(testUserCredentials).query({ + _id: room._id, + }); const { body } = response; @@ -1150,7 +1154,9 @@ describe('[Groups]', () => { await request .get(api('groups.online')) .set(outsiderCredentials) - .query(`query={"_id": "${room._id}"}`) + .query({ + _id: room._id, + }) .expect(400) .expect((res) => { expect(res.body).to.have.property('success', false); diff --git a/packages/rest-typings/src/v1/groups/GroupsOnlineProps.ts b/packages/rest-typings/src/v1/groups/GroupsOnlineProps.ts index 158840e35b36f..a3021330cc727 100644 --- a/packages/rest-typings/src/v1/groups/GroupsOnlineProps.ts +++ b/packages/rest-typings/src/v1/groups/GroupsOnlineProps.ts @@ -4,10 +4,15 @@ const ajv = new Ajv({ coerceTypes: true, }); -export type GroupsOnlineProps = { query?: Record }; -const groupsOnlyPropsSchema = { +export type GroupsOnlineProps = { _id?: string; query?: Record }; + +const groupsOnlinePropsSchema = { type: 'object', properties: { + _id: { + type: 'string', + nullable: true, + }, query: { type: 'string', nullable: true, @@ -16,4 +21,5 @@ const groupsOnlyPropsSchema = { required: [], additionalProperties: false, }; -export const isGroupsOnlineProps = ajv.compile(groupsOnlyPropsSchema); + +export const isGroupsOnlineProps = ajv.compile(groupsOnlinePropsSchema);