From 1b5d191e9b134a60aedce1280533a4f1a5cc079d Mon Sep 17 00:00:00 2001 From: dougfabris Date: Wed, 18 Dec 2024 18:29:29 -0300 Subject: [PATCH 1/7] feat: hide export messages in OTR session --- .../client/hooks/roomActions/useExportMessagesRoomAction.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts b/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts index 21d1da3a6843..2f1db342a6cd 100644 --- a/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts +++ b/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts @@ -11,7 +11,7 @@ export const useExportMessagesRoomAction = () => { const permitted = usePermission('mail-messages', room._id); return useMemo((): RoomToolboxActionConfig | undefined => { - if (!permitted) { + if (!permitted || room.createdOTR) { return undefined; } @@ -26,5 +26,5 @@ export const useExportMessagesRoomAction = () => { order: 12, type: 'communication', }; - }, [permitted]); + }, [permitted, room.createdOTR]); }; From 3b8295d085a9bc7f343ae5a8822e2c6f7ac06eb7 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Thu, 19 Dec 2024 10:14:56 -0300 Subject: [PATCH 2/7] chore: changeset --- .changeset/pretty-islands-wink.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pretty-islands-wink.md diff --git a/.changeset/pretty-islands-wink.md b/.changeset/pretty-islands-wink.md new file mode 100644 index 000000000000..cb90eb381f3d --- /dev/null +++ b/.changeset/pretty-islands-wink.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +--- + +It hides the export feature for rooms running OTR session From 011afe44280bbf2a1a1349f8f4d026ce34aea255 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Thu, 19 Dec 2024 11:30:50 -0300 Subject: [PATCH 3/7] test: add e2e test --- apps/meteor/tests/e2e/otr.spec.ts | 43 +++++++++++++++++++ .../fragments/home-flextab-otr.ts | 21 +++++++++ .../page-objects/fragments/home-flextab.ts | 8 ++++ 3 files changed, 72 insertions(+) create mode 100644 apps/meteor/tests/e2e/otr.spec.ts create mode 100644 apps/meteor/tests/e2e/page-objects/fragments/home-flextab-otr.ts diff --git a/apps/meteor/tests/e2e/otr.spec.ts b/apps/meteor/tests/e2e/otr.spec.ts new file mode 100644 index 000000000000..e57adb5f7a62 --- /dev/null +++ b/apps/meteor/tests/e2e/otr.spec.ts @@ -0,0 +1,43 @@ +import { Users } from './fixtures/userStates'; +import { HomeChannel } from './page-objects'; +import { createDirectMessage } from './utils'; +import { test, expect } from './utils/test'; + +test.use({ storageState: Users.admin.state }); + +test.describe.serial('OTR', () => { + let poHomeChannel: HomeChannel; + + test.beforeEach(async ({ page, api }) => { + await createDirectMessage(api); + poHomeChannel = new HomeChannel(page); + + await page.goto('/home'); + }); + + test('should hide export messages for rooms with OTR enabled', async ({ browser }) => { + const user1Page = await browser.newPage({ storageState: Users.user1.state }); + const user1Channel = new HomeChannel(user1Page); + + await test.step('log in user1', async () => { + await user1Page.goto(`/direct/${Users.admin.data.username}`); + await user1Channel.content.waitForChannel(); + }); + + await test.step('invite OTR with user1', async () => { + await poHomeChannel.sidenav.openChat(Users.user1.data.username); + await poHomeChannel.tabs.kebab.click({ force: true }); + await poHomeChannel.tabs.btnEnableOTR.click({ force: true }); + await poHomeChannel.tabs.otr.btnStartOTR.click(); + }); + + await test.step('accept handshake with user1', async () => { + await user1Channel.tabs.otr.btnAcceptOTR.click(); + }); + + await poHomeChannel.tabs.kebab.click({ force: true }); + await expect(poHomeChannel.tabs.btnExportMessages).not.toBeVisible(); + + await user1Page.close(); + }); +}); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-otr.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-otr.ts new file mode 100644 index 000000000000..1a310f76f2f4 --- /dev/null +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab-otr.ts @@ -0,0 +1,21 @@ +import type { Locator, Page } from '@playwright/test'; + +export class HomeFlextabOtr { + private readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + get otrDialog(): Locator { + return this.page.getByRole('dialog', { name: 'OTR' }); + } + + get btnStartOTR(): Locator { + return this.otrDialog.getByRole('button', { name: 'Start OTR' }); + } + + get btnAcceptOTR(): Locator { + return this.page.getByRole('dialog').getByRole('button', { name: 'Yes' }); + } +} diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts index 6e22bea99faf..36b96f8a2284 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-flextab.ts @@ -3,6 +3,7 @@ import type { Locator, Page } from '@playwright/test'; import { HomeFlextabChannels } from './home-flextab-channels'; import { HomeFlextabMembers } from './home-flextab-members'; import { HomeFlextabNotificationPreferences } from './home-flextab-notificationPreferences'; +import { HomeFlextabOtr } from './home-flextab-otr'; import { HomeFlextabRoom } from './home-flextab-room'; export class HomeFlextab { @@ -16,12 +17,15 @@ export class HomeFlextab { readonly notificationPreferences: HomeFlextabNotificationPreferences; + readonly otr: HomeFlextabOtr; + constructor(page: Page) { this.page = page; this.members = new HomeFlextabMembers(page); this.room = new HomeFlextabRoom(page); this.channels = new HomeFlextabChannels(page); this.notificationPreferences = new HomeFlextabNotificationPreferences(page); + this.otr = new HomeFlextabOtr(page); } get btnTabMembers(): Locator { @@ -64,6 +68,10 @@ export class HomeFlextab { return this.page.locator('role=menuitem[name="OTR"]'); } + get btnExportMessages(): Locator { + return this.page.locator('role=menuitem[name="Export Messages"]'); + } + get flexTabViewThreadMessage(): Locator { return this.page.locator('div.thread-list ul.thread [data-qa-type="message"]').last().locator('[data-qa-type="message-body"]'); } From 75da6bbac82907311b3203fae6eb7c4ff75cb43f Mon Sep 17 00:00:00 2001 From: gabriellsh <40830821+gabriellsh@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:08:07 -0300 Subject: [PATCH 4/7] Update pretty-islands-wink.md --- .changeset/pretty-islands-wink.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pretty-islands-wink.md b/.changeset/pretty-islands-wink.md index cb90eb381f3d..7e227dc6f0a6 100644 --- a/.changeset/pretty-islands-wink.md +++ b/.changeset/pretty-islands-wink.md @@ -2,4 +2,4 @@ '@rocket.chat/meteor': minor --- -It hides the export feature for rooms running OTR session +Disables export messages feature for rooms with an active OTR session From 967c57be73d464b399928f0ac5e16f24afb0e699 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 20 Dec 2024 15:05:19 -0300 Subject: [PATCH 5/7] fix: review --- .../client/components/message/variants/RoomMessage.tsx | 8 +++++--- .../message/variants/ThreadMessagePreview.tsx | 10 ++++++++-- .../hooks/roomActions/useExportMessagesRoomAction.ts | 4 ++-- .../MessageList/contexts/SelectedMessagesContext.tsx | 6 +++--- .../contextualBar/ExportMessages/ExportMessages.tsx | 7 +++++++ packages/i18n/src/locales/en.i18n.json | 1 + 6 files changed, 26 insertions(+), 10 deletions(-) diff --git a/apps/meteor/client/components/message/variants/RoomMessage.tsx b/apps/meteor/client/components/message/variants/RoomMessage.tsx index 90bc2236e837..54d3dcdea539 100644 --- a/apps/meteor/client/components/message/variants/RoomMessage.tsx +++ b/apps/meteor/client/components/message/variants/RoomMessage.tsx @@ -55,8 +55,10 @@ const RoomMessage = ({ const { openUserCard, triggerProps } = useUserCard(); const selecting = useIsSelecting(); + const isOTRMessage = message.t === 'otr' || message.t === 'otr-ack'; + const toggleSelected = useToggleSelect(message._id); - const selected = useIsSelectedMessage(message._id); + const selected = useIsSelectedMessage(message._id, isOTRMessage); useCountSelected(); @@ -70,7 +72,7 @@ const RoomMessage = ({ aria-roledescription={t('message')} tabIndex={0} aria-labelledby={`${message._id}-displayName ${message._id}-time ${message._id}-content ${message._id}-read-status`} - onClick={selecting ? toggleSelected : undefined} + onClick={selecting && !isOTRMessage ? toggleSelected : undefined} isSelected={selected} isEditing={editing} isPending={message.temp} @@ -99,7 +101,7 @@ const RoomMessage = ({ {...triggerProps} /> )} - {selecting && } + {selecting && } {sequential && } diff --git a/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx b/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx index f7fa072a7406..146bda990d52 100644 --- a/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx +++ b/apps/meteor/client/components/message/variants/ThreadMessagePreview.tsx @@ -45,8 +45,10 @@ const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }: const { t } = useTranslation(); const isSelecting = useIsSelecting(); + const isOTRMessage = message.t === 'otr' || message.t === 'otr-ack'; + const toggleSelected = useToggleSelect(message._id); - const isSelected = useIsSelectedMessage(message._id); + const isSelected = useIsSelectedMessage(message._id, isOTRMessage); useCountSelected(); const messageType = parentMessage.isSuccess ? MessageTypes.getType(parentMessage.data) : null; @@ -65,6 +67,10 @@ const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }: return goToThread({ rid: message.rid, tmid: message.tmid, msg: message._id }); } + if (isOTRMessage) { + return; + } + return toggleSelected(); }; @@ -117,7 +123,7 @@ const ThreadMessagePreview = ({ message, showUserAvatar, sequential, ...props }: size='x18' /> )} - {isSelecting && } + {isSelecting && } diff --git a/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts b/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts index 2f1db342a6cd..21d1da3a6843 100644 --- a/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts +++ b/apps/meteor/client/hooks/roomActions/useExportMessagesRoomAction.ts @@ -11,7 +11,7 @@ export const useExportMessagesRoomAction = () => { const permitted = usePermission('mail-messages', room._id); return useMemo((): RoomToolboxActionConfig | undefined => { - if (!permitted || room.createdOTR) { + if (!permitted) { return undefined; } @@ -26,5 +26,5 @@ export const useExportMessagesRoomAction = () => { order: 12, type: 'communication', }; - }, [permitted, room.createdOTR]); + }, [permitted]); }; diff --git a/apps/meteor/client/views/room/MessageList/contexts/SelectedMessagesContext.tsx b/apps/meteor/client/views/room/MessageList/contexts/SelectedMessagesContext.tsx index 800f7155082e..527ea332cc14 100644 --- a/apps/meteor/client/views/room/MessageList/contexts/SelectedMessagesContext.tsx +++ b/apps/meteor/client/views/room/MessageList/contexts/SelectedMessagesContext.tsx @@ -11,7 +11,7 @@ export const SelectedMessageContext = createContext({ selectedMessageStore, } as SelectMessageContextValue); -export const useIsSelectedMessage = (mid: string): boolean => { +export const useIsSelectedMessage = (mid: string, omit?: boolean): boolean => { const { selectedMessageStore } = useContext(SelectedMessageContext); const subscribe = useCallback( @@ -24,14 +24,14 @@ export const useIsSelectedMessage = (mid: string): boolean => { const isSelected = useSyncExternalStore(subscribe, getSnapshot); useEffect(() => { - if (isSelected) { + if (isSelected || omit) { return; } selectedMessageStore.addAvailableMessage(mid); return () => selectedMessageStore.removeAvailableMessage(mid); - }, [mid, selectedMessageStore, isSelected]); + }, [mid, selectedMessageStore, isSelected, omit]); return isSelected; }; diff --git a/apps/meteor/client/views/room/contextualBar/ExportMessages/ExportMessages.tsx b/apps/meteor/client/views/room/contextualBar/ExportMessages/ExportMessages.tsx index 8736c8a1bec3..c05faece42e1 100644 --- a/apps/meteor/client/views/room/contextualBar/ExportMessages/ExportMessages.tsx +++ b/apps/meteor/client/views/room/contextualBar/ExportMessages/ExportMessages.tsx @@ -176,6 +176,13 @@ const ExportMessages = () => {
+ {room.createdOTR && ( + + + {t('OTR_messages_cannot_be_exported')} + + + )} {t('Method')} diff --git a/packages/i18n/src/locales/en.i18n.json b/packages/i18n/src/locales/en.i18n.json index e9c452eaa45c..2b955fc6c327 100644 --- a/packages/i18n/src/locales/en.i18n.json +++ b/packages/i18n/src/locales/en.i18n.json @@ -4231,6 +4231,7 @@ "others": "others", "Others": "Others", "OTR": "OTR", + "OTR_messages_cannot_be_exported": "OTR messages cannot be exported", "OTR_unavailable_for_federation": "OTR is unavailable for federated rooms", "OTR_Description": "Off-the-record chats are secure, private and disappear once ended.", "OTR_Chat_Declined_Title": "OTR Chat invite Declined", From 4342030ecab6fd0ca0e694cb034f166e3caa5b9f Mon Sep 17 00:00:00 2001 From: dougfabris Date: Fri, 20 Dec 2024 15:05:30 -0300 Subject: [PATCH 6/7] fix: e2e test --- apps/meteor/tests/e2e/otr.spec.ts | 7 +++++-- .../tests/e2e/page-objects/fragments/home-content.ts | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/meteor/tests/e2e/otr.spec.ts b/apps/meteor/tests/e2e/otr.spec.ts index e57adb5f7a62..b6ff4789e0c2 100644 --- a/apps/meteor/tests/e2e/otr.spec.ts +++ b/apps/meteor/tests/e2e/otr.spec.ts @@ -15,7 +15,7 @@ test.describe.serial('OTR', () => { await page.goto('/home'); }); - test('should hide export messages for rooms with OTR enabled', async ({ browser }) => { + test('should not allow export OTR messages', async ({ browser }) => { const user1Page = await browser.newPage({ storageState: Users.user1.state }); const user1Channel = new HomeChannel(user1Page); @@ -35,8 +35,11 @@ test.describe.serial('OTR', () => { await user1Channel.tabs.otr.btnAcceptOTR.click(); }); + await poHomeChannel.content.sendMessage('hello OTR'); await poHomeChannel.tabs.kebab.click({ force: true }); - await expect(poHomeChannel.tabs.btnExportMessages).not.toBeVisible(); + await poHomeChannel.tabs.btnExportMessages.click(); + await poHomeChannel.content.getMessageByText('hello OTR').click(); + await expect(poHomeChannel.content.btnClearSelection).toBeDisabled(); await user1Page.close(); }); diff --git a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts index 088d8dd3d647..2a66a899f3ce 100644 --- a/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts +++ b/apps/meteor/tests/e2e/page-objects/fragments/home-content.ts @@ -417,4 +417,8 @@ export class HomeContent { await this.page.getByRole('dialog').getByRole('textbox', { name: 'Message' }).fill(text); await this.page.getByRole('dialog').getByRole('button', { name: 'Send', exact: true }).click(); } + + get btnClearSelection() { + return this.page.getByRole('button', { name: 'Clear selection' }); + } } From 6d19dbb8418f1ac4cac9290b52f95468e22b8263 Mon Sep 17 00:00:00 2001 From: Douglas Fabris Date: Fri, 20 Dec 2024 15:07:04 -0300 Subject: [PATCH 7/7] chore: changeset --- .changeset/pretty-islands-wink.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pretty-islands-wink.md b/.changeset/pretty-islands-wink.md index 7e227dc6f0a6..e9de264504b0 100644 --- a/.changeset/pretty-islands-wink.md +++ b/.changeset/pretty-islands-wink.md @@ -2,4 +2,4 @@ '@rocket.chat/meteor': minor --- -Disables export messages feature for rooms with an active OTR session +Disables OTR messages selection when exporting messages