From 55aeb985be1eea875b8d853b972d5c42695eabcf Mon Sep 17 00:00:00 2001 From: Matheus Cardoso Date: Fri, 5 Sep 2025 11:05:20 -0300 Subject: [PATCH 1/5] chore: improve e2e encryption tests --- apps/meteor/tests/e2e/e2e-encryption.spec.ts | 226 +++++++++---------- 1 file changed, 105 insertions(+), 121 deletions(-) diff --git a/apps/meteor/tests/e2e/e2e-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption.spec.ts index b0d76a12cb530..393d2fd6be61a 100644 --- a/apps/meteor/tests/e2e/e2e-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption.spec.ts @@ -20,10 +20,32 @@ import { import { ExportMessagesTab } from './page-objects/fragments/export-messages-tab'; import { FileUploadModal } from './page-objects/fragments/file-upload-modal'; import { LoginPage } from './page-objects/login'; +import { getSettingValueById } from './utils'; import { test, expect } from './utils/test'; -test.beforeAll(async () => { +const settings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, + E2E_Enable_Encrypt_Files: false as unknown, + E2E_Enabled_Default_DirectRooms: false as unknown, + E2E_Enabled_Default_PrivateRooms: false as unknown, +}; + +test.beforeAll(async ({ api }) => { await injectInitialData(); + settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); + settings.E2E_Enable_Encrypt_Files = await getSettingValueById(api, 'E2E_Enable_Encrypt_Files'); + settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); + settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); +}); + +test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); }); test.describe('initial setup', () => { @@ -32,11 +54,13 @@ test.describe('initial setup', () => { test.beforeAll(async ({ api }) => { await api.post('/settings/E2E_Enable', { value: true }); await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); }); test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: false }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); }); test.beforeEach(async ({ api, page }) => { @@ -101,6 +125,7 @@ test.describe('initial setup', () => { const resetE2EEPasswordModal = new ResetE2EEPasswordModal(page); await sidenav.logout(); + await expect(loginPage.loginButton).toBeVisible(); await loginPage.loginByUserState(Users.admin); await enterE2EEPasswordBanner.click(); await enterE2EEPasswordModal.forgotPassword(); @@ -157,8 +182,8 @@ test.describe('basic features', () => { }); test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: false }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); }); test.beforeEach(async ({ api, page }) => { @@ -277,6 +302,8 @@ test.describe('basic features', () => { // Login again await loginPage.loginByUserState(Users.admin); + await expect(sidenav.btnCreateNew).toBeVisible(); + await sidenav.openChat(channelName); await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); @@ -333,7 +360,7 @@ test.describe('basic features', () => { }); }); -test.describe.serial('e2e-encryption', () => { +test.describe('e2e-encryption', () => { let poHomeChannel: HomeChannel; test.use({ storageState: Users.userE2EE.state }); @@ -341,11 +368,16 @@ test.describe.serial('e2e-encryption', () => { test.beforeAll(async ({ api }) => { await api.post('/settings/E2E_Enable', { value: true }); await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); }); test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: false }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); }); test.beforeEach(async ({ page }) => { @@ -463,9 +495,9 @@ test.describe.serial('e2e-encryption', () => { await poHomeChannel.dismissToast(); - await poHomeChannel.tabs.kebab.click({ force: true }); + await poHomeChannel.tabs.kebab.click(); await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); - await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); + await poHomeChannel.tabs.btnEnableE2E.click(); await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); await page.getByRole('button', { name: 'Enable encryption' }).click(); await page.waitForTimeout(1000); @@ -489,7 +521,7 @@ test.describe.serial('e2e-encryption', () => { await poHomeChannel.content.sendMessage('hello @user1'); - const userMention = await page.getByRole('button', { + const userMention = page.getByRole('button', { name: 'user1', }); @@ -507,7 +539,7 @@ test.describe.serial('e2e-encryption', () => { await poHomeChannel.content.sendMessage('Are you in the #general channel?'); - const channelMention = await page.getByRole('button', { + const channelMention = page.getByRole('button', { name: 'general', }); @@ -529,11 +561,11 @@ test.describe.serial('e2e-encryption', () => { await poHomeChannel.content.sendMessage('Are you in the #general channel, @user1 ?'); - const channelMention = await page.getByRole('button', { + const channelMention = page.getByRole('button', { name: 'general', }); - const userMention = await page.getByRole('button', { + const userMention = page.getByRole('button', { name: 'user1', }); @@ -572,6 +604,13 @@ test.describe.serial('e2e-encryption', () => { await expect(page).toHaveURL(`/direct/user2${Users.userE2EE.data.username}`); await poHomeChannel.tabs.kebab.click({ force: true }); + if (await poHomeChannel.tabs.btnDisableE2E.isVisible()) { + await poHomeChannel.tabs.btnDisableE2E.click({ force: true }); + await expect(page.getByRole('dialog', { name: 'Disable encryption' })).toBeVisible(); + await page.getByRole('button', { name: 'Disable encryption' }).click(); + await poHomeChannel.dismissToast(); + await poHomeChannel.tabs.kebab.click({ force: true }); + } await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); @@ -599,16 +638,10 @@ test.describe.serial('e2e-encryption', () => { await test.step('create an encrypted channel', async () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.advancedSettingsAccordion.click(); - await poHomeChannel.sidenav.checkboxEncryption.click(); - await poHomeChannel.sidenav.btnCreate.click(); + await poHomeChannel.sidenav.createEncryptedChannel(channelName); await expect(page).toHaveURL(`/group/${channelName}`); - await poHomeChannel.dismissToast(); - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); }); @@ -628,16 +661,10 @@ test.describe.serial('e2e-encryption', () => { await test.step('create an encrypted room', async () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.advancedSettingsAccordion.click(); - await poHomeChannel.sidenav.checkboxEncryption.click(); - await poHomeChannel.sidenav.btnCreate.click(); + await poHomeChannel.sidenav.createEncryptedChannel(channelName); await expect(page).toHaveURL(`/group/${channelName}`); - await poHomeChannel.dismissToast(); - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); }); @@ -690,7 +717,7 @@ test.describe.serial('e2e-encryption', () => { }); test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable_Encrypt_Files', { value: true }); + await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'image/svg+xml' }); }); @@ -698,16 +725,10 @@ test.describe.serial('e2e-encryption', () => { await test.step('create an encrypted channel', async () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.advancedSettingsAccordion.click(); - await poHomeChannel.sidenav.checkboxEncryption.click(); - await poHomeChannel.sidenav.btnCreate.click(); + await poHomeChannel.sidenav.createEncryptedChannel(channelName); await expect(page).toHaveURL(`/group/${channelName}`); - await poHomeChannel.dismissToast(); - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); }); @@ -771,7 +792,7 @@ test.describe.serial('e2e-encryption', () => { }); test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); }); test('expect slash commands to be disabled in an e2ee room', async ({ page }) => { @@ -835,7 +856,7 @@ test.describe.serial('e2e-encryption', () => { await page.locator('#modal-root .rcx-button-group--align-end .rcx-button--danger').click(); // Check last message in the sidebar - const sidebarChannel = await poHomeChannel.sidenav.getSidebarItemByName(channelName); + const sidebarChannel = poHomeChannel.sidenav.getSidebarItemByName(channelName); await expect(sidebarChannel).toBeVisible(); await expect(sidebarChannel.locator('span')).toContainText(encriptedMessage1); }); @@ -893,6 +914,47 @@ test.describe.serial('e2e-encryption', () => { await expect(page.locator('role=menuitem[name="Copy link"]')).toHaveClass(/disabled/); }); + test('legacy expect create a private channel encrypted and send an encrypted message', async ({ page, request }) => { + const channelName = faker.string.uuid(); + + await restoreState(page, Users.userE2EE, { except: ['private_key', 'public_key', 'e2e.randomPassword'] }); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(page.getByTitle('Encrypted')).toBeVisible(); + // TODO: Fix this flakiness + await expect(page.getByRole('button', { name: 'Send' })).toBeVisible(); + + const rid = await page.locator('[data-qa-rc-room]').getAttribute('data-qa-rc-room'); + + // send old format encrypted message via API + const msg = await page.evaluate(async (rid) => { + // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path + const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); + const e2eRoom = await e2e.getInstanceByRoomId(rid); + return e2eRoom.encrypt({ _id: 'id', msg: 'Old format message' }); + }, rid); + + await request.post(`${BASE_API_URL}/chat.sendMessage`, { + headers: { + 'X-Auth-Token': Users.userE2EE.data.loginToken, + 'X-User-Id': Users.userE2EE.data._id, + }, + data: { + message: { + rid, + msg, + t: 'e2e', + }, + }, + }); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('Old format message'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + }); + test.describe('reset keys', () => { let anotherClientPage: Page; @@ -936,8 +998,8 @@ test.describe.serial('e2ee room setup', () => { }); test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: false }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); }); test.afterEach(async ({ api }) => { @@ -962,16 +1024,10 @@ test.describe.serial('e2ee room setup', () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.advancedSettingsAccordion.click(); - await poHomeChannel.sidenav.checkboxEncryption.click(); - await poHomeChannel.sidenav.btnCreate.click(); + await poHomeChannel.sidenav.createEncryptedChannel(channelName); await expect(page).toHaveURL(`/group/${channelName}`); - await poHomeChannel.dismissToast(); - await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); await expect(poHomeChannel.btnRoomSaveE2EEPassword).toBeVisible(); @@ -1012,16 +1068,10 @@ test.describe.serial('e2ee room setup', () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.advancedSettingsAccordion.click(); - await poHomeChannel.sidenav.checkboxEncryption.click(); - await poHomeChannel.sidenav.btnCreate.click(); + await poHomeChannel.sidenav.createEncryptedChannel(channelName); await expect(page).toHaveURL(`/group/${channelName}`); - await poHomeChannel.dismissToast(); - await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); await poHomeChannel.btnRoomEnterE2EEPassword.waitFor(); @@ -1060,16 +1110,10 @@ test.describe.serial('e2ee room setup', () => { const channelName = faker.string.uuid(); - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.advancedSettingsAccordion.click(); - await poHomeChannel.sidenav.checkboxEncryption.click(); - await poHomeChannel.sidenav.btnCreate.click(); + await poHomeChannel.sidenav.createEncryptedChannel(channelName); await expect(page).toHaveURL(`/group/${channelName}`); - await poHomeChannel.dismissToast(); - await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); await poHomeChannel.content.sendMessage('hello world'); @@ -1110,63 +1154,3 @@ test.describe.serial('e2ee room setup', () => { await expect(poHomeChannel.tabs.btnRoomInfo).toBeVisible(); }); }); - -test.describe('e2ee support legacy formats', () => { - test.use({ storageState: Users.userE2EE.state }); - - let poHomeChannel: HomeChannel; - - test.beforeEach(async ({ page }) => { - poHomeChannel = new HomeChannel(page); - }); - - test.beforeAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: true }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); - }); - - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: false }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); - }); - - // ->>>>>>>>>>>Not testing upload since it was not implemented in the legacy format - test('expect create a private channel encrypted and send an encrypted message', async ({ page, request }) => { - await page.goto('/home'); - - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - const rid = await page.locator('[data-qa-rc-room]').getAttribute('data-qa-rc-room'); - - // send old format encrypted message via API - const msg = await page.evaluate(async (rid) => { - // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path - const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); - const e2eRoom = await e2e.getInstanceByRoomId(rid); - return e2eRoom.encrypt({ _id: 'id', msg: 'Old format message' }); - }, rid); - - await request.post(`${BASE_API_URL}/chat.sendMessage`, { - headers: { - 'X-Auth-Token': Users.userE2EE.data.loginToken, - 'X-User-Id': Users.userE2EE.data._id, - }, - data: { - message: { - rid, - msg, - t: 'e2e', - }, - }, - }); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('Old format message'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - }); -}); From f393c63c0ab690f64904b15ce214df228dfe613a Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Mon, 8 Sep 2025 17:04:18 -0300 Subject: [PATCH 2/5] test: break down e2e tests --- .../e2ee-encrypted-channels.spec.ts | 354 ++++++++++++++++++ .../e2ee-encryption-decryption.spec.ts | 165 ++++++++ .../e2ee-file-encryption.spec.ts | 172 +++++++++ .../e2e/e2e-encryption/e2ee-key-reset.spec.ts | 63 ++++ .../e2e-encryption/e2ee-legacy-format.spec.ts | 90 +++++ .../tests/e2e/e2e-encryption/e2ee-otr.spec.ts | 79 ++++ .../e2ee-passphrase-management.spec.ts | 328 ++++++++++++++++ .../e2e-encryption/e2ee-pdf-export.spec.ts | 74 ++++ .../e2ee-server-settings.spec.ts | 87 +++++ 9 files changed, 1412 insertions(+) create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts create mode 100644 apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts new file mode 100644 index 0000000000000..85722c343f8dd --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts @@ -0,0 +1,354 @@ +import { faker } from '@faker-js/faker'; + +import { Users } from '../fixtures/userStates'; +import { HomeChannel } from '../page-objects'; +import { getSettingValueById } from '../utils'; +import { test, expect } from '../utils/test'; + +const settings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, + E2E_Enabled_Default_DirectRooms: false as unknown, + E2E_Enabled_Default_PrivateRooms: false as unknown, +}; + +test.beforeAll(async ({ api }) => { + settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); + settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); + settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); +}); + +test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); +}); + +test.describe('E2EE Encrypted Channels', () => { + let poHomeChannel: HomeChannel; + + test.use({ storageState: Users.userE2EE.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + }); + + test.beforeEach(async ({ page }) => { + poHomeChannel = new HomeChannel(page); + await page.goto('/home'); + }); + + test('expect create a private channel encrypted and send an encrypted message', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('hello world'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await poHomeChannel.tabs.kebab.click({ force: true }); + + await expect(poHomeChannel.tabs.btnDisableE2E).toBeVisible(); + await poHomeChannel.tabs.btnDisableE2E.click({ force: true }); + await expect(page.getByRole('dialog', { name: 'Disable encryption' })).toBeVisible(); + await page.getByRole('button', { name: 'Disable encryption' }).click(); + await poHomeChannel.dismissToast(); + await page.waitForTimeout(1000); + + await poHomeChannel.content.sendMessage('hello world not encrypted'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world not encrypted'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).not.toBeVisible(); + + await poHomeChannel.tabs.kebab.click({ force: true }); + await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); + await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); + await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); + await page.getByRole('button', { name: 'Enable encryption' }).click(); + await poHomeChannel.dismissToast(); + await page.waitForTimeout(1000); + + await poHomeChannel.content.sendMessage('hello world encrypted again'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world encrypted again'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + }); + + test('expect create a private encrypted channel and send a encrypted thread message', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('This is the thread main message.'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is the thread main message.'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await page.locator('[data-qa-type="message"]').last().hover(); + await page.locator('role=button[name="Reply in thread"]').click(); + + await expect(page).toHaveURL(/.*thread/); + + await expect(poHomeChannel.content.mainThreadMessageText).toContainText('This is the thread main message.'); + await expect(poHomeChannel.content.mainThreadMessageText.locator('.rcx-icon--name-key')).toBeVisible(); + + await poHomeChannel.content.toggleAlsoSendThreadToChannel(true); + await page.getByRole('dialog').locator('[name="msg"]').last().fill('This is an encrypted thread message also sent in channel'); + await page.keyboard.press('Enter'); + await expect(poHomeChannel.content.lastThreadMessageText).toContainText('This is an encrypted thread message also sent in channel'); + await expect(poHomeChannel.content.lastThreadMessageText.locator('.rcx-icon--name-key')).toBeVisible(); + await expect(poHomeChannel.content.lastUserMessage).toContainText('This is an encrypted thread message also sent in channel'); + await expect(poHomeChannel.content.mainThreadMessageText).toContainText('This is the thread main message.'); + await expect(poHomeChannel.content.mainThreadMessageText.locator('.rcx-icon--name-key')).toBeVisible(); + }); + + test('expect create a private encrypted channel and check disabled message menu actions on an encrypted message', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('This is an encrypted message.'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await page.locator('[data-qa-type="message"]').last().hover(); + await expect(page.locator('role=button[name="Forward message not available on encrypted content"]')).toBeDisabled(); + + await poHomeChannel.content.openLastMessageMenu(); + + await expect(page.locator('role=menuitem[name="Reply in direct message"]')).toHaveClass(/disabled/); + await expect(page.locator('role=menuitem[name="Copy link"]')).toHaveClass(/disabled/); + }); + + test('expect create a private channel, encrypt it and send an encrypted message', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.openNewByLabel('Channel'); + await poHomeChannel.sidenav.inputChannelName.fill(channelName); + await poHomeChannel.sidenav.btnCreate.click(); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.toastSuccess).toBeVisible(); + + await poHomeChannel.dismissToast(); + + await poHomeChannel.tabs.kebab.click(); + await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); + await poHomeChannel.tabs.btnEnableE2E.click(); + await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); + await page.getByRole('button', { name: 'Enable encryption' }).click(); + await page.waitForTimeout(1000); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('hello world'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + }); + + test('expect create a encrypted private channel and mention user', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('hello @user1'); + + const userMention = page.getByRole('button', { + name: 'user1', + }); + + await expect(userMention).toBeVisible(); + }); + + test('expect create a encrypted private channel, mention a channel and navigate to it', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('Are you in the #general channel?'); + + const channelMention = page.getByRole('button', { + name: 'general', + }); + + await expect(channelMention).toBeVisible(); + + await channelMention.click(); + + await expect(page).toHaveURL(`/channel/general`); + }); + + test('expect create a encrypted private channel, mention a channel and user', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('Are you in the #general channel, @user1 ?'); + + const channelMention = page.getByRole('button', { + name: 'general', + }); + + const userMention = page.getByRole('button', { + name: 'user1', + }); + + await expect(userMention).toBeVisible(); + await expect(channelMention).toBeVisible(); + }); + + test('should encrypted field be available on edit room', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.openNewByLabel('Channel'); + await poHomeChannel.sidenav.inputChannelName.fill(channelName); + await poHomeChannel.sidenav.btnCreate.click(); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.toastSuccess).toBeVisible(); + + await poHomeChannel.dismissToast(); + + await poHomeChannel.tabs.btnRoomInfo.click(); + await poHomeChannel.tabs.room.btnEdit.click(); + await poHomeChannel.tabs.room.advancedSettingsAccordion.click(); + + await expect(poHomeChannel.tabs.room.checkboxEncrypted).toBeVisible(); + }); + + test('expect create a private channel, send unecrypted messages, encrypt the channel and delete the last message and check the last message in the sidebar', async ({ + page, + }) => { + const channelName = faker.string.uuid(); + + // Enable Sidebar Extended display mode + await poHomeChannel.sidenav.setDisplayMode('Extended'); + + // Create private channel + await poHomeChannel.sidenav.openNewByLabel('Channel'); + await poHomeChannel.sidenav.inputChannelName.fill(channelName); + await poHomeChannel.sidenav.btnCreate.click(); + await expect(page).toHaveURL(`/group/${channelName}`); + await expect(poHomeChannel.toastSuccess).toBeVisible(); + await poHomeChannel.dismissToast(); + + // Send Unencrypted Messages + await poHomeChannel.content.sendMessage('first unencrypted message'); + await poHomeChannel.content.sendMessage('second unencrypted message'); + + // Encrypt channel + await poHomeChannel.tabs.kebab.click({ force: true }); + await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); + await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); + await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); + await page.getByRole('button', { name: 'Enable encryption' }).click(); + await page.waitForTimeout(1000); + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + // Send Encrypted Messages + const encriptedMessage1 = 'first ENCRYPTED message'; + const encriptedMessage2 = 'second ENCRYPTED message'; + await poHomeChannel.content.sendMessage(encriptedMessage1); + await poHomeChannel.content.sendMessage(encriptedMessage2); + + // Delete last message + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText(encriptedMessage2); + await poHomeChannel.content.openLastMessageMenu(); + await page.locator('role=menuitem[name="Delete"]').click(); + await page.locator('#modal-root .rcx-button-group--align-end .rcx-button--danger').click(); + + // Check last message in the sidebar + const sidebarChannel = poHomeChannel.sidenav.getSidebarItemByName(channelName); + await expect(sidebarChannel).toBeVisible(); + await expect(sidebarChannel.locator('span')).toContainText(encriptedMessage1); + }); + + test('expect create a private encrypted channel and pin/star an encrypted message', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('This message should be pinned and stared.'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This message should be pinned and stared.'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await poHomeChannel.content.openLastMessageMenu(); + await page.locator('role=menuitem[name="Star"]').click(); + + await expect(poHomeChannel.toastSuccess).toBeVisible(); + await poHomeChannel.dismissToast(); + + await poHomeChannel.content.openLastMessageMenu(); + await page.locator('role=menuitem[name="Pin"]').click(); + await page.locator('#modal-root >> button:has-text("Yes, pin message")').click(); + + await expect(poHomeChannel.toastSuccess).toBeVisible(); + await poHomeChannel.dismissToast(); + + await poHomeChannel.tabs.kebab.click(); + await poHomeChannel.tabs.btnPinnedMessagesList.click(); + + await expect(page.getByRole('dialog', { name: 'Pinned Messages' })).toBeVisible(); + + const lastPinnedMessage = page.getByRole('dialog', { name: 'Pinned Messages' }).locator('[data-qa-type="message"]').last(); + await expect(lastPinnedMessage).toContainText('This message should be pinned and stared.'); + await lastPinnedMessage.hover(); + await lastPinnedMessage.locator('role=button[name="More"]').waitFor(); + await lastPinnedMessage.locator('role=button[name="More"]').click(); + await expect(page.locator('role=menuitem[name="Copy link"]')).toHaveClass(/disabled/); + + await poHomeChannel.btnContextualbarClose.click(); + + await poHomeChannel.tabs.kebab.click(); + await poHomeChannel.tabs.btnStarredMessageList.click(); + + const lastStarredMessage = page.getByRole('dialog', { name: 'Starred Messages' }).locator('[data-qa-type="message"]').last(); + await expect(page.getByRole('dialog', { name: 'Starred Messages' })).toBeVisible(); + await expect(lastStarredMessage).toContainText('This message should be pinned and stared.'); + await lastStarredMessage.hover(); + await lastStarredMessage.locator('role=button[name="More"]').waitFor(); + await lastStarredMessage.locator('role=button[name="More"]').click(); + await expect(page.locator('role=menuitem[name="Copy link"]')).toHaveClass(/disabled/); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts new file mode 100644 index 0000000000000..b4afd8d5cd014 --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts @@ -0,0 +1,165 @@ +import { faker } from '@faker-js/faker'; + +import { Users } from '../fixtures/userStates'; +import { EncryptedRoomPage } from '../page-objects/encrypted-room'; +import { HomeSidenav } from '../page-objects/fragments'; +import { SaveE2EEPasswordBanner, SaveE2EEPasswordModal } from '../page-objects/fragments/e2ee'; +import { FileUploadModal } from '../page-objects/fragments/file-upload-modal'; +import { LoginPage } from '../page-objects/login'; +import { getSettingValueById } from '../utils'; +import { test, expect } from '../utils/test'; + +const settings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, +}; + +test.beforeAll(async ({ api }) => { + settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); +}); + +test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); +}); + +test.describe('E2EE Encryption and Decryption - Basic Features', () => { + test.use({ storageState: Users.admin.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + }); + + test.beforeEach(async ({ api, page }) => { + const loginPage = new LoginPage(page); + + await api.post('/method.call/e2e.resetOwnE2EKey', { + message: JSON.stringify({ msg: 'method', id: '1', method: 'e2e.resetOwnE2EKey', params: [] }), + }); + + await page.goto('/home'); + await loginPage.waitForIt(); + await loginPage.loginByUserState(Users.admin); + }); + + test('expect placeholder text in place of encrypted message', async ({ page }) => { + const loginPage = new LoginPage(page); + const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); + const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); + const encryptedRoomPage = new EncryptedRoomPage(page); + const sidenav = new HomeSidenav(page); + + const channelName = faker.string.uuid(); + const messageText = 'This is an encrypted message.'; + + await saveE2EEPasswordBanner.click(); + await saveE2EEPasswordModal.confirm(); + await saveE2EEPasswordBanner.waitForDisappearance(); + + await sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); + await expect(encryptedRoomPage.encryptionNotReadyIndicator).not.toBeVisible(); + + await encryptedRoomPage.sendMessage(messageText); + await expect(encryptedRoomPage.lastMessage.encryptedIcon).toBeVisible(); + await expect(encryptedRoomPage.lastMessage.body).toHaveText(messageText); + + await sidenav.logout(); + + await loginPage.loginByUserState(Users.admin); + + // Navigate to the encrypted channel WITHOUT entering the password + + await sidenav.openChat(channelName); + await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); + await expect(encryptedRoomPage.encryptionNotReadyIndicator).toBeVisible(); + + await expect(encryptedRoomPage.lastMessage.encryptedIcon).toBeVisible(); + await expect(encryptedRoomPage.lastMessage.body).toHaveText( + 'This message is end-to-end encrypted. To view it, you must enter your encryption key in your account settings.', + ); + }); + + test('expect placeholder text in place of encrypted file upload description', async ({ page }) => { + const encryptedRoomPage = new EncryptedRoomPage(page); + const loginPage = new LoginPage(page); + const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); + const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); + const fileUploadModal = new FileUploadModal(page); + const sidenav = new HomeSidenav(page); + + const channelName = faker.string.uuid(); + const fileName = faker.system.commonFileName('txt'); + const fileDescription = faker.lorem.sentence(); + + // Click the banner to open the dialog to save the generated password + await saveE2EEPasswordBanner.click(); + await saveE2EEPasswordModal.confirm(); + await saveE2EEPasswordBanner.waitForDisappearance(); + + // Create an encrypted channel + await sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); + await expect(encryptedRoomPage.encryptionNotReadyIndicator).not.toBeVisible(); + + await test.step('upload the file with encryption', async () => { + // Upload a file + await encryptedRoomPage.dragAndDropTxtFile(); + await fileUploadModal.setName(fileName); + await fileUploadModal.setDescription(fileDescription); + await fileUploadModal.send(); + + // Check the file upload + await expect(encryptedRoomPage.lastMessage.encryptedIcon).toBeVisible(); + await expect(encryptedRoomPage.lastMessage.fileUploadName).toContainText(fileName); + await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription); + }); + + await test.step('disable encryption in the room', async () => { + await encryptedRoomPage.disableEncryption(); + await expect(encryptedRoomPage.encryptedIcon).not.toBeVisible(); + }); + + await test.step('upload the file without encryption', async () => { + await encryptedRoomPage.dragAndDropTxtFile(); + await fileUploadModal.setName(fileName); + await fileUploadModal.setDescription(fileDescription); + await fileUploadModal.send(); + + await expect(encryptedRoomPage.lastMessage.encryptedIcon).not.toBeVisible(); + await expect(encryptedRoomPage.lastMessage.fileUploadName).toContainText(fileName); + await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription); + }); + + await test.step('enable encryption in the room', async () => { + await encryptedRoomPage.enableEncryption(); + await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); + }); + + // Log out + await sidenav.logout(); + + // Login again + await loginPage.loginByUserState(Users.admin); + + await expect(sidenav.btnCreateNew).toBeVisible(); + + await sidenav.openChat(channelName); + await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); + + await expect(encryptedRoomPage.lastNthMessage(1).body).toHaveText( + 'This message is end-to-end encrypted. To view it, you must enter your encryption key in your account settings.', + ); + await expect(encryptedRoomPage.lastNthMessage(1).encryptedIcon).toBeVisible(); + + await expect(encryptedRoomPage.lastMessage.encryptedIcon).not.toBeVisible(); + await expect(encryptedRoomPage.lastMessage.fileUploadName).toContainText(fileName); + await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts new file mode 100644 index 0000000000000..db6ef9bd07f6f --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts @@ -0,0 +1,172 @@ +import { faker } from '@faker-js/faker'; + +import { Users } from '../fixtures/userStates'; +import { HomeChannel } from '../page-objects'; +import { getSettingValueById } from '../utils'; +import { test, expect } from '../utils/test'; + +const settings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, + E2E_Enable_Encrypt_Files: false as unknown, + E2E_Enabled_Default_DirectRooms: false as unknown, + E2E_Enabled_Default_PrivateRooms: false as unknown, +}; + +test.beforeAll(async ({ api }) => { + settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); + settings.E2E_Enable_Encrypt_Files = await getSettingValueById(api, 'E2E_Enable_Encrypt_Files'); + settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); + settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); +}); + +test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); +}); + +test.describe('E2EE File Encryption', () => { + let poHomeChannel: HomeChannel; + + test.use({ storageState: Users.userE2EE.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + }); + + test.afterAll(async ({ api }) => { + await api.post('/settings/FileUpload_MediaTypeWhiteList', { value: '' }); + await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'image/svg+xml' }); + }); + + test.beforeEach(async ({ page }) => { + poHomeChannel = new HomeChannel(page); + await page.goto('/home'); + }); + + test('File and description encryption', async ({ page }) => { + await test.step('create an encrypted channel', async () => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + }); + + await test.step('send a file in channel', async () => { + await poHomeChannel.content.dragAndDropTxtFile(); + await poHomeChannel.content.descriptionInput.fill('any_description'); + await poHomeChannel.content.fileNameInput.fill('any_file1.txt'); + await poHomeChannel.content.btnModalConfirm.click(); + + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + await expect(poHomeChannel.content.getFileDescription).toHaveText('any_description'); + await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file1.txt'); + }); + }); + + test('File encryption with whitelisted and blacklisted media types', async ({ page, api }) => { + await test.step('create an encrypted room', async () => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + }); + + await test.step('send a text file in channel', async () => { + await poHomeChannel.content.dragAndDropTxtFile(); + await poHomeChannel.content.descriptionInput.fill('message 1'); + await poHomeChannel.content.fileNameInput.fill('any_file1.txt'); + await poHomeChannel.content.btnModalConfirm.click(); + + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + await expect(poHomeChannel.content.getFileDescription).toHaveText('message 1'); + await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file1.txt'); + }); + + await test.step('set whitelisted media type setting', async () => { + await api.post('/settings/FileUpload_MediaTypeWhiteList', { value: 'text/plain' }); + }); + + await test.step('send text file again with whitelist setting set', async () => { + await poHomeChannel.content.dragAndDropTxtFile(); + await poHomeChannel.content.descriptionInput.fill('message 2'); + await poHomeChannel.content.fileNameInput.fill('any_file2.txt'); + await poHomeChannel.content.btnModalConfirm.click(); + + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + await expect(poHomeChannel.content.getFileDescription).toHaveText('message 2'); + await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file2.txt'); + }); + + await test.step('set blacklisted media type setting to not accept application/octet-stream media type', async () => { + await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'application/octet-stream' }); + }); + + await test.step('send text file again with blacklisted setting set, file upload should fail', async () => { + await poHomeChannel.content.dragAndDropTxtFile(); + await poHomeChannel.content.descriptionInput.fill('message 3'); + await poHomeChannel.content.fileNameInput.fill('any_file3.txt'); + await poHomeChannel.content.btnModalConfirm.click(); + + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + await expect(poHomeChannel.content.getFileDescription).toHaveText('message 2'); + await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file2.txt'); + }); + }); + + test.describe('File encryption setting disabled', () => { + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable_Encrypt_Files', { value: false }); + await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'application/octet-stream' }); + }); + + test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); + await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'image/svg+xml' }); + }); + + test('Upload file without encryption in e2ee room', async ({ page }) => { + await test.step('create an encrypted channel', async () => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + }); + + await test.step('send a test encrypted message to check e2ee is working', async () => { + await poHomeChannel.content.sendMessage('This is an encrypted message.'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + }); + + await test.step('send a text file in channel, file should not be encrypted', async () => { + await poHomeChannel.content.dragAndDropTxtFile(); + await poHomeChannel.content.descriptionInput.fill('any_description'); + await poHomeChannel.content.fileNameInput.fill('any_file1.txt'); + await poHomeChannel.content.btnModalConfirm.click(); + + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).not.toBeVisible(); + await expect(poHomeChannel.content.getFileDescription).toHaveText('any_description'); + await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file1.txt'); + }); + }); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts new file mode 100644 index 0000000000000..26bd0a49de0a3 --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts @@ -0,0 +1,63 @@ +import type { Page } from '@playwright/test'; + +import { createAuxContext } from '../fixtures/createAuxContext'; +import { Users } from '../fixtures/userStates'; +import { AccountProfile } from '../page-objects'; +import { getSettingValueById } from '../utils'; +import { test, expect } from '../utils/test'; + +const settings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, + E2E_Enabled_Default_DirectRooms: false as unknown, + E2E_Enabled_Default_PrivateRooms: false as unknown, +}; + +test.beforeAll(async ({ api }) => { + settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); + settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); + settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); +}); + +test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); +}); + +test.describe('E2EE Key Reset', () => { + let anotherClientPage: Page; + + test.use({ storageState: Users.userE2EE.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + }); + + test.beforeEach(async ({ browser, page }) => { + anotherClientPage = (await createAuxContext(browser, Users.userE2EE)).page; + await page.goto('/home'); + }); + + test.afterEach(async () => { + await anotherClientPage.close(); + }); + + test('expect force logout on e2e keys reset', async ({ page }) => { + const poAccountProfile = new AccountProfile(page); + + await page.goto('/account/security'); + + await poAccountProfile.securityE2EEncryptionSection.click(); + await poAccountProfile.securityE2EEncryptionResetKeyButton.click(); + + await expect(page.locator('role=button[name="Login"]')).toBeVisible(); + await expect(anotherClientPage.locator('role=button[name="Login"]')).toBeVisible(); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts new file mode 100644 index 0000000000000..07f7da4b9fe8c --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts @@ -0,0 +1,90 @@ +import { faker } from '@faker-js/faker'; + +import { BASE_API_URL } from '../config/constants'; +import injectInitialData from '../fixtures/inject-initial-data'; +import { Users, restoreState } from '../fixtures/userStates'; +import { HomeChannel } from '../page-objects'; +import { getSettingValueById } from '../utils'; +import { test, expect } from '../utils/test'; + +const settings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, + E2E_Enabled_Default_DirectRooms: false as unknown, + E2E_Enabled_Default_PrivateRooms: false as unknown, +}; + +test.beforeAll(async ({ api }) => { + settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); + settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); + settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); +}); + +test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); +}); + +test.describe('E2EE Legacy Format', () => { + let poHomeChannel: HomeChannel; + + test.use({ storageState: Users.userE2EE.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + }); + + test.beforeEach(async ({ page }) => { + poHomeChannel = new HomeChannel(page); + await page.goto('/home'); + }); + + test('legacy expect create a private channel encrypted and send an encrypted message', async ({ page, request }) => { + const channelName = faker.string.uuid(); + + await injectInitialData(); + await restoreState(page, Users.userE2EE, { except: ['private_key', 'public_key', 'e2e.randomPassword'] }); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(page.getByTitle('Encrypted')).toBeVisible(); + // TODO: Fix this flakiness + await expect(page.getByRole('button', { name: 'Send' })).toBeVisible(); + + const rid = await page.locator('[data-qa-rc-room]').getAttribute('data-qa-rc-room'); + + // send old format encrypted message via API + const msg = await page.evaluate(async (rid) => { + // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path + const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); + const e2eRoom = await e2e.getInstanceByRoomId(rid); + return e2eRoom.encrypt({ _id: 'id', msg: 'Old format message' }); + }, rid); + + await request.post(`${BASE_API_URL}/chat.sendMessage`, { + headers: { + 'X-Auth-Token': Users.userE2EE.data.loginToken, + 'X-User-Id': Users.userE2EE.data._id, + }, + data: { + message: { + rid, + msg, + t: 'e2e', + }, + }, + }); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('Old format message'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts new file mode 100644 index 0000000000000..ef443ae44fc76 --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts @@ -0,0 +1,79 @@ +import { Users } from '../fixtures/userStates'; +import { HomeChannel } from '../page-objects'; +import { getSettingValueById } from '../utils'; +import { test, expect } from '../utils/test'; + +const settings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, + E2E_Enabled_Default_DirectRooms: false as unknown, + E2E_Enabled_Default_PrivateRooms: false as unknown, +}; + +test.beforeAll(async ({ api }) => { + settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); + settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); + settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); +}); + +test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); +}); + +test.describe('E2EE OTR (Off-The-Record)', () => { + let poHomeChannel: HomeChannel; + + test.use({ storageState: Users.userE2EE.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + }); + + test.beforeEach(async ({ page }) => { + poHomeChannel = new HomeChannel(page); + await page.goto('/home'); + }); + + test('expect create a Direct message, encrypt it and attempt to enable OTR', async ({ page }) => { + await poHomeChannel.sidenav.openNewByLabel('Direct message'); + await poHomeChannel.sidenav.inputDirectUsername.click(); + await page.keyboard.type('user2'); + await page.waitForTimeout(1000); + await page.keyboard.press('Enter'); + await poHomeChannel.sidenav.btnCreate.click(); + + await expect(page).toHaveURL(`/direct/user2${Users.userE2EE.data.username}`); + + await poHomeChannel.tabs.kebab.click({ force: true }); + if (await poHomeChannel.tabs.btnDisableE2E.isVisible()) { + await poHomeChannel.tabs.btnDisableE2E.click({ force: true }); + await expect(page.getByRole('dialog', { name: 'Disable encryption' })).toBeVisible(); + await page.getByRole('button', { name: 'Disable encryption' }).click(); + await poHomeChannel.dismissToast(); + await poHomeChannel.tabs.kebab.click({ force: true }); + } + await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); + await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); + await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); + await page.getByRole('button', { name: 'Enable encryption' }).click(); + await page.waitForTimeout(1000); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.dismissToast(); + + await poHomeChannel.tabs.kebab.click({ force: true }); + await expect(poHomeChannel.tabs.btnEnableOTR).toBeVisible(); + await poHomeChannel.tabs.btnEnableOTR.click({ force: true }); + + await expect(page.getByText('OTR not available')).toBeVisible(); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts new file mode 100644 index 0000000000000..ee9883009f393 --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts @@ -0,0 +1,328 @@ +import { faker } from '@faker-js/faker'; + +import injectInitialData from '../fixtures/inject-initial-data'; +import { Users, storeState, restoreState } from '../fixtures/userStates'; +import { AccountProfile, HomeChannel } from '../page-objects'; +import { AccountSecurityPage } from '../page-objects/account-security'; +import { HomeSidenav } from '../page-objects/fragments'; +import { + E2EEKeyDecodeFailureBanner, + EnterE2EEPasswordBanner, + EnterE2EEPasswordModal, + ResetE2EEPasswordModal, + SaveE2EEPasswordBanner, + SaveE2EEPasswordModal, +} from '../page-objects/fragments/e2ee'; +import { LoginPage } from '../page-objects/login'; +import { getSettingValueById } from '../utils'; +import { test, expect } from '../utils/test'; + +test.describe('E2EE Passphrase Management - Initial Setup', () => { + test.use({ storageState: Users.admin.state }); + + test.beforeAll(async ({ api }) => { + // Set settings for this describe block only + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + }); + + test.afterAll(async ({ api }) => { + // Restore original settings + await api.post('/settings/E2E_Enable', { value: false }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + }); + + test.beforeEach(async ({ api, page }) => { + const loginPage = new LoginPage(page); + + await api.post('/method.call/e2e.resetOwnE2EKey', { + message: JSON.stringify({ msg: 'method', id: '1', method: 'e2e.resetOwnE2EKey', params: [] }), + }); + + await page.goto('/home'); + await loginPage.waitForIt(); + await loginPage.loginByUserState(Users.admin); + }); + + test('expect the randomly generated password to work', async ({ page }) => { + const loginPage = new LoginPage(page); + const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); + const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); + const enterE2EEPasswordBanner = new EnterE2EEPasswordBanner(page); + const enterE2EEPasswordModal = new EnterE2EEPasswordModal(page); + const e2EEKeyDecodeFailureBanner = new E2EEKeyDecodeFailureBanner(page); + const sidenav = new HomeSidenav(page); + + // Click the banner to open the dialog to save the generated password + await saveE2EEPasswordBanner.click(); + const password = await saveE2EEPasswordModal.getPassword(); + await saveE2EEPasswordModal.confirm(); + await saveE2EEPasswordBanner.waitForDisappearance(); + + // Log out + await sidenav.logout(); + + await expect(loginPage.loginButton).toBeVisible(); + + // Login again + await loginPage.loginByUserState(Users.admin); + + // Enter the saved password + await enterE2EEPasswordBanner.click(); + await enterE2EEPasswordModal.enterPassword(password); + + // No error banner + await e2EEKeyDecodeFailureBanner.expectToNotBeVisible(); + }); + + test('expect to manually reset the password', async ({ page }) => { + const accountSecurityPage = new AccountSecurityPage(page); + const loginPage = new LoginPage(page); + + // Reset the E2EE key to start the flow from the beginning + await accountSecurityPage.goto(); + await accountSecurityPage.resetE2EEPassword(); + + await loginPage.loginByUserState(Users.admin); + }); + + test('should reset e2e password from the modal', async ({ page }) => { + const sidenav = new HomeSidenav(page); + const loginPage = new LoginPage(page); + const enterE2EEPasswordBanner = new EnterE2EEPasswordBanner(page); + const enterE2EEPasswordModal = new EnterE2EEPasswordModal(page); + const resetE2EEPasswordModal = new ResetE2EEPasswordModal(page); + + await sidenav.logout(); + await expect(loginPage.loginButton).toBeVisible(); + await loginPage.loginByUserState(Users.admin); + await enterE2EEPasswordBanner.click(); + await enterE2EEPasswordModal.forgotPassword(); + await resetE2EEPasswordModal.confirmReset(); + + await loginPage.loginByUserState(Users.admin); + }); + + test('expect to manually set a new password', async ({ page }) => { + const accountSecurityPage = new AccountSecurityPage(page); + const loginPage = new LoginPage(page); + const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); + const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); + const enterE2EEPasswordBanner = new EnterE2EEPasswordBanner(page); + const enterE2EEPasswordModal = new EnterE2EEPasswordModal(page); + const e2EEKeyDecodeFailureBanner = new E2EEKeyDecodeFailureBanner(page); + const sidenav = new HomeSidenav(page); + + const newPassword = faker.string.uuid(); + + // Click the banner to open the dialog to save the generated password + await saveE2EEPasswordBanner.click(); + await saveE2EEPasswordModal.confirm(); + await saveE2EEPasswordBanner.waitForDisappearance(); + + // Set a new password + await accountSecurityPage.goto(); + await accountSecurityPage.setE2EEPassword(newPassword); + await accountSecurityPage.close(); + + // Log out + await sidenav.logout(); + + // Login again + await expect(loginPage.loginButton).toBeVisible(); + + await loginPage.loginByUserState(Users.admin); + + // Enter the saved password + await enterE2EEPasswordBanner.click(); + await enterE2EEPasswordModal.enterPassword(newPassword); + + // No error banner + await e2EEKeyDecodeFailureBanner.expectToNotBeVisible(); + }); +}); + +test.use({ storageState: Users.admin.state }); + +const roomSetupSettings = { + E2E_Enable: false as unknown, + E2E_Allow_Unencrypted_Messages: false as unknown, +}; + +test.describe.serial('E2EE Passphrase Management - Room Setup States', () => { + let poAccountProfile: AccountProfile; + let poHomeChannel: HomeChannel; + let e2eePassword: string; + + test.beforeEach(async ({ page }) => { + poAccountProfile = new AccountProfile(page); + poHomeChannel = new HomeChannel(page); + }); + + test.beforeAll(async ({ api }) => { + roomSetupSettings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); + roomSetupSettings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); + }); + + test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: roomSetupSettings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: roomSetupSettings.E2E_Allow_Unencrypted_Messages }); + }); + + test.afterEach(async ({ api }) => { + await api.recreateContext(); + }); + + test('expect save password state on encrypted room', async ({ page }) => { + await page.goto('/account/security'); + await poAccountProfile.securityE2EEncryptionSection.click(); + await poAccountProfile.securityE2EEncryptionResetKeyButton.click(); + + await page.locator('role=button[name="Login"]').waitFor(); + + await injectInitialData(); + await restoreState(page, Users.admin); + + await page.goto('/home'); + await page.waitForSelector('#main-content'); + + await expect(poHomeChannel.bannerSaveEncryptionPassword).toBeVisible(); + + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); + await expect(poHomeChannel.btnRoomSaveE2EEPassword).toBeVisible(); + + await poHomeChannel.tabs.btnE2EERoomSetupDisableE2E.waitFor(); + await expect(poHomeChannel.tabs.btnE2EERoomSetupDisableE2E).toBeVisible(); + await expect(poHomeChannel.tabs.btnTabMembers).toBeVisible(); + await expect(poHomeChannel.tabs.btnRoomInfo).toBeVisible(); + + await expect(poHomeChannel.content.inputMessage).not.toBeVisible(); + + await poHomeChannel.btnRoomSaveE2EEPassword.click(); + + e2eePassword = (await page.evaluate(() => localStorage.getItem('e2e.randomPassword'))) || 'undefined'; + + await expect(poHomeChannel.dialogSaveE2EEPassword).toBeVisible(); + await expect(poHomeChannel.dialogSaveE2EEPassword).toContainText(e2eePassword); + + await poHomeChannel.btnSavedMyPassword.click(); + + await poHomeChannel.content.inputMessage.waitFor(); + + await poHomeChannel.content.sendMessage('hello world'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + }); + + test('expect enter password state on encrypted room', async ({ page }) => { + await page.goto('/home'); + + // Logout to remove e2ee keys + await poHomeChannel.sidenav.logout(); + + await page.locator('role=button[name="Login"]').waitFor(); + + await injectInitialData(); + await restoreState(page, Users.admin, { except: ['private_key', 'public_key'] }); + + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); + + await poHomeChannel.btnRoomEnterE2EEPassword.waitFor(); + + await expect(poHomeChannel.btnRoomEnterE2EEPassword).toBeVisible(); + + await poHomeChannel.tabs.btnE2EERoomSetupDisableE2E.waitFor(); + await expect(poHomeChannel.tabs.btnE2EERoomSetupDisableE2E).toBeVisible(); + await expect(poHomeChannel.tabs.btnTabMembers).toBeVisible(); + await expect(poHomeChannel.tabs.btnRoomInfo).toBeVisible(); + + await expect(poHomeChannel.content.inputMessage).not.toBeVisible(); + + await poHomeChannel.btnRoomEnterE2EEPassword.click(); + + await page.locator('#modal-root input').fill(e2eePassword); + + await page.locator('#modal-root .rcx-button--primary').click(); + + await expect(poHomeChannel.bannerEnterE2EEPassword).not.toBeVisible(); + + await poHomeChannel.content.inputMessage.waitFor(); + // For E2EE to complete init setup + await page.waitForTimeout(300); + + await poHomeChannel.content.sendMessage('hello world'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await storeState(page, Users.admin); + }); + + test('expect waiting for room keys state', async ({ page }) => { + await page.goto('/home'); + + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); + + await poHomeChannel.content.sendMessage('hello world'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await poHomeChannel.sidenav.btnUserProfileMenu.click(); + await poHomeChannel.sidenav.accountProfileOption.click(); + + await page.locator('role=navigation >> a:has-text("Security")').click(); + + await poAccountProfile.securityE2EEncryptionSection.click(); + await poAccountProfile.securityE2EEncryptionResetKeyButton.click(); + + await page.locator('role=button[name="Login"]').waitFor(); + + await page.reload(); + + await page.locator('role=button[name="Login"]').waitFor(); + + await injectInitialData(); + await restoreState(page, Users.admin); + + await page.locator('role=navigation >> role=button[name=Search]').click(); + await page.locator('role=search >> role=searchbox').fill(channelName); + await page.locator(`role=search >> role=listbox >> role=link >> text="${channelName}"`).click(); + + await poHomeChannel.btnRoomSaveE2EEPassword.click(); + await poHomeChannel.btnSavedMyPassword.click(); + + await expect(poHomeChannel.content.inputMessage).not.toBeVisible(); + await expect(page.locator('.rcx-states__title')).toContainText('Check back later'); + + await poHomeChannel.tabs.btnE2EERoomSetupDisableE2E.waitFor(); + await expect(poHomeChannel.tabs.btnE2EERoomSetupDisableE2E).toBeVisible(); + await expect(poHomeChannel.tabs.btnTabMembers).toBeVisible(); + await expect(poHomeChannel.tabs.btnRoomInfo).toBeVisible(); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts new file mode 100644 index 0000000000000..b3e2ee71260bc --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts @@ -0,0 +1,74 @@ +import { faker } from '@faker-js/faker'; + +import { Users } from '../fixtures/userStates'; +import { EncryptedRoomPage } from '../page-objects/encrypted-room'; +import { HomeSidenav } from '../page-objects/fragments'; +import { ExportMessagesTab } from '../page-objects/fragments/export-messages-tab'; +import { LoginPage } from '../page-objects/login'; +import { test, expect } from '../utils/test'; + +test.describe('E2EE PDF Export', () => { + test.use({ storageState: Users.admin.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + // Note: Using admin user, so no need for userE2EE cleanup + }); + + test.beforeEach(async ({ api, page }) => { + const loginPage = new LoginPage(page); + + await api.post('/method.call/e2e.resetOwnE2EKey', { + message: JSON.stringify({ msg: 'method', id: '1', method: 'e2e.resetOwnE2EKey', params: [] }), + }); + + await page.goto('/home'); + await loginPage.waitForIt(); + await loginPage.loginByUserState(Users.admin); + }); + + test('should display only the download file method when exporting messages in an e2ee room', async ({ page }) => { + const sidenav = new HomeSidenav(page); + const encryptedRoomPage = new EncryptedRoomPage(page); + const exportMessagesTab = new ExportMessagesTab(page); + + const channelName = faker.string.uuid(); + + await sidenav.createEncryptedChannel(channelName); + await expect(page).toHaveURL(`/group/${channelName}`); + await expect(encryptedRoomPage.encryptedRoomHeaderIcon).toBeVisible(); + + await encryptedRoomPage.showExportMessagesTab(); + await expect(exportMessagesTab.method).toContainClass('disabled'); // FIXME: looks like the component have an a11y issue + await expect(exportMessagesTab.method).toHaveAccessibleName('Download file'); + }); + + test('should allow exporting messages as PDF in an encrypted room', async ({ page }) => { + const sidenav = new HomeSidenav(page); + const encryptedRoomPage = new EncryptedRoomPage(page); + const exportMessagesTab = new ExportMessagesTab(page); + + const channelName = faker.string.uuid(); + + await sidenav.createEncryptedChannel(channelName); + await expect(page).toHaveURL(`/group/${channelName}`); + await expect(encryptedRoomPage.encryptedRoomHeaderIcon).toBeVisible(); + + await encryptedRoomPage.sendMessage('This is a message to export as PDF.'); + await encryptedRoomPage.showExportMessagesTab(); + await expect(exportMessagesTab.method).toHaveAccessibleName('Download file'); + + // Select Output format as PDF + await exportMessagesTab.setOutputFormat('PDF'); + + // select messages to be exported + await exportMessagesTab.selectAllMessages(); + + // Wait for download event and match format + const download = await exportMessagesTab.downloadMessages(); + expect(download.suggestedFilename()).toMatch(/\.pdf$/); + }); +}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts new file mode 100644 index 0000000000000..7196bdd2e7a71 --- /dev/null +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts @@ -0,0 +1,87 @@ +import { faker } from '@faker-js/faker'; + +import { IS_EE } from '../config/constants'; +import { Users } from '../fixtures/userStates'; +import { HomeChannel } from '../page-objects'; +import { test, expect } from '../utils/test'; + +test.describe('E2EE Server Settings', () => { + let poHomeChannel: HomeChannel; + + test.use({ storageState: Users.userE2EE.state }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Enable', { value: true }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + }); + + test.beforeEach(async ({ page }) => { + poHomeChannel = new HomeChannel(page); + await page.goto('/home'); + }); + + test('expect slash commands to be enabled in an e2ee room', async ({ page }) => { + test.skip(!IS_EE, 'Premium Only'); + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('This is an encrypted message.'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await page.locator('[name="msg"]').type('/'); + await expect(page.locator('#popup-item-contextualbar')).not.toHaveClass(/disabled/); + await page.locator('[name="msg"]').clear(); + + await poHomeChannel.content.dispatchSlashCommand('/contextualbar'); + await expect(poHomeChannel.btnContextualbarClose).toBeVisible(); + + await poHomeChannel.btnContextualbarClose.click(); + await expect(poHomeChannel.btnContextualbarClose).toBeHidden(); + }); + + test.describe('un-encrypted messages not allowed in e2ee rooms', () => { + test.skip(!IS_EE, 'Premium Only'); + let poHomeChannel: HomeChannel; + + test.beforeEach(async ({ page }) => { + poHomeChannel = new HomeChannel(page); + await page.goto('/home'); + }); + + test.beforeAll(async ({ api }) => { + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); + }); + + test.afterAll(async ({ api }) => { + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); + }); + + test('expect slash commands to be disabled in an e2ee room', async ({ page }) => { + const channelName = faker.string.uuid(); + + await poHomeChannel.sidenav.createEncryptedChannel(channelName); + + await expect(page).toHaveURL(`/group/${channelName}`); + + await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); + + await poHomeChannel.content.sendMessage('This is an encrypted message.'); + + await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); + await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); + + await page.locator('[name="msg"]').pressSequentially('/'); + await expect(page.locator('#popup-item-contextualbar')).toHaveClass(/disabled/); + }); + }); +}); From 05f6b174f708223b9ebe99195a8b033c0178ca84 Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Mon, 8 Sep 2025 18:12:21 -0300 Subject: [PATCH 3/5] test: improve preserve settings --- apps/meteor/tests/e2e/e2e-encryption.spec.ts | 1156 ----------------- .../e2ee-encrypted-channels.spec.ts | 28 +- .../e2ee-encryption-decryption.spec.ts | 17 +- .../e2ee-file-encryption.spec.ts | 34 +- .../e2e/e2e-encryption/e2ee-key-reset.spec.ts | 28 +- .../e2e-encryption/e2ee-legacy-format.spec.ts | 28 +- .../tests/e2e/e2e-encryption/e2ee-otr.spec.ts | 28 +- .../e2ee-passphrase-management.spec.ts | 35 +- .../e2e-encryption/e2ee-pdf-export.spec.ts | 10 + .../e2ee-server-settings.spec.ts | 10 + .../tests/e2e/utils/preserveSettings.ts | 19 + 11 files changed, 101 insertions(+), 1292 deletions(-) delete mode 100644 apps/meteor/tests/e2e/e2e-encryption.spec.ts create mode 100644 apps/meteor/tests/e2e/utils/preserveSettings.ts diff --git a/apps/meteor/tests/e2e/e2e-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption.spec.ts deleted file mode 100644 index 393d2fd6be61a..0000000000000 --- a/apps/meteor/tests/e2e/e2e-encryption.spec.ts +++ /dev/null @@ -1,1156 +0,0 @@ -import { faker } from '@faker-js/faker'; -import type { Page } from '@playwright/test'; - -import { BASE_API_URL, IS_EE } from './config/constants'; -import { createAuxContext } from './fixtures/createAuxContext'; -import injectInitialData from './fixtures/inject-initial-data'; -import { Users, storeState, restoreState } from './fixtures/userStates'; -import { AccountProfile, HomeChannel } from './page-objects'; -import { AccountSecurityPage } from './page-objects/account-security'; -import { EncryptedRoomPage } from './page-objects/encrypted-room'; -import { HomeSidenav } from './page-objects/fragments'; -import { - E2EEKeyDecodeFailureBanner, - EnterE2EEPasswordBanner, - EnterE2EEPasswordModal, - ResetE2EEPasswordModal, - SaveE2EEPasswordBanner, - SaveE2EEPasswordModal, -} from './page-objects/fragments/e2ee'; -import { ExportMessagesTab } from './page-objects/fragments/export-messages-tab'; -import { FileUploadModal } from './page-objects/fragments/file-upload-modal'; -import { LoginPage } from './page-objects/login'; -import { getSettingValueById } from './utils'; -import { test, expect } from './utils/test'; - -const settings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, - E2E_Enable_Encrypt_Files: false as unknown, - E2E_Enabled_Default_DirectRooms: false as unknown, - E2E_Enabled_Default_PrivateRooms: false as unknown, -}; - -test.beforeAll(async ({ api }) => { - await injectInitialData(); - settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); - settings.E2E_Enable_Encrypt_Files = await getSettingValueById(api, 'E2E_Enable_Encrypt_Files'); - settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); - settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); -}); - -test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); -}); - -test.describe('initial setup', () => { - test.use({ storageState: Users.admin.state }); - - test.beforeAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: true }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - }); - - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - }); - - test.beforeEach(async ({ api, page }) => { - const loginPage = new LoginPage(page); - - await api.post('/method.call/e2e.resetOwnE2EKey', { - message: JSON.stringify({ msg: 'method', id: '1', method: 'e2e.resetOwnE2EKey', params: [] }), - }); - - await page.goto('/home'); - await loginPage.waitForIt(); - await loginPage.loginByUserState(Users.admin); - }); - - test('expect the randomly generated password to work', async ({ page }) => { - const loginPage = new LoginPage(page); - const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); - const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); - const enterE2EEPasswordBanner = new EnterE2EEPasswordBanner(page); - const enterE2EEPasswordModal = new EnterE2EEPasswordModal(page); - const e2EEKeyDecodeFailureBanner = new E2EEKeyDecodeFailureBanner(page); - const sidenav = new HomeSidenav(page); - - // Click the banner to open the dialog to save the generated password - await saveE2EEPasswordBanner.click(); - const password = await saveE2EEPasswordModal.getPassword(); - await saveE2EEPasswordModal.confirm(); - await saveE2EEPasswordBanner.waitForDisappearance(); - - // Log out - await sidenav.logout(); - - await expect(loginPage.loginButton).toBeVisible(); - - // Login again - await loginPage.loginByUserState(Users.admin); - - // Enter the saved password - await enterE2EEPasswordBanner.click(); - await enterE2EEPasswordModal.enterPassword(password); - - // No error banner - await e2EEKeyDecodeFailureBanner.expectToNotBeVisible(); - }); - - test('expect to manually reset the password', async ({ page }) => { - const accountSecurityPage = new AccountSecurityPage(page); - const loginPage = new LoginPage(page); - - // Reset the E2EE key to start the flow from the beginning - await accountSecurityPage.goto(); - await accountSecurityPage.resetE2EEPassword(); - - await loginPage.loginByUserState(Users.admin); - }); - - test('should reset e2e password from the modal', async ({ page }) => { - const sidenav = new HomeSidenav(page); - const loginPage = new LoginPage(page); - const enterE2EEPasswordBanner = new EnterE2EEPasswordBanner(page); - const enterE2EEPasswordModal = new EnterE2EEPasswordModal(page); - const resetE2EEPasswordModal = new ResetE2EEPasswordModal(page); - - await sidenav.logout(); - await expect(loginPage.loginButton).toBeVisible(); - await loginPage.loginByUserState(Users.admin); - await enterE2EEPasswordBanner.click(); - await enterE2EEPasswordModal.forgotPassword(); - await resetE2EEPasswordModal.confirmReset(); - - await loginPage.loginByUserState(Users.admin); - }); - - test('expect to manually set a new password', async ({ page }) => { - const accountSecurityPage = new AccountSecurityPage(page); - const loginPage = new LoginPage(page); - const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); - const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); - const enterE2EEPasswordBanner = new EnterE2EEPasswordBanner(page); - const enterE2EEPasswordModal = new EnterE2EEPasswordModal(page); - const e2EEKeyDecodeFailureBanner = new E2EEKeyDecodeFailureBanner(page); - const sidenav = new HomeSidenav(page); - - const newPassword = faker.string.uuid(); - - // Click the banner to open the dialog to save the generated password - await saveE2EEPasswordBanner.click(); - await saveE2EEPasswordModal.confirm(); - await saveE2EEPasswordBanner.waitForDisappearance(); - - // Set a new password - await accountSecurityPage.goto(); - await accountSecurityPage.setE2EEPassword(newPassword); - await accountSecurityPage.close(); - - // Log out - await sidenav.logout(); - - // Login again - await expect(loginPage.loginButton).toBeVisible(); - - await loginPage.loginByUserState(Users.admin); - - // Enter the saved password - await enterE2EEPasswordBanner.click(); - await enterE2EEPasswordModal.enterPassword(newPassword); - - // No error banner - await e2EEKeyDecodeFailureBanner.expectToNotBeVisible(); - }); -}); - -test.describe('basic features', () => { - test.use({ storageState: Users.admin.state }); - - test.beforeAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: true }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); - }); - - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - }); - - test.beforeEach(async ({ api, page }) => { - const loginPage = new LoginPage(page); - - await api.post('/method.call/e2e.resetOwnE2EKey', { - message: JSON.stringify({ msg: 'method', id: '1', method: 'e2e.resetOwnE2EKey', params: [] }), - }); - - await page.goto('/home'); - await loginPage.waitForIt(); - await loginPage.loginByUserState(Users.admin); - }); - - test('expect placeholder text in place of encrypted message', async ({ page }) => { - const loginPage = new LoginPage(page); - const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); - const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); - const encryptedRoomPage = new EncryptedRoomPage(page); - const sidenav = new HomeSidenav(page); - - const channelName = faker.string.uuid(); - const messageText = 'This is an encrypted message.'; - - await saveE2EEPasswordBanner.click(); - await saveE2EEPasswordModal.confirm(); - await saveE2EEPasswordBanner.waitForDisappearance(); - - await sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); - await expect(encryptedRoomPage.encryptionNotReadyIndicator).not.toBeVisible(); - - await encryptedRoomPage.sendMessage(messageText); - await expect(encryptedRoomPage.lastMessage.encryptedIcon).toBeVisible(); - await expect(encryptedRoomPage.lastMessage.body).toHaveText(messageText); - - await sidenav.logout(); - - await loginPage.loginByUserState(Users.admin); - - // Navigate to the encrypted channel WITHOUT entering the password - - await sidenav.openChat(channelName); - await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); - await expect(encryptedRoomPage.encryptionNotReadyIndicator).toBeVisible(); - - await expect(encryptedRoomPage.lastMessage.encryptedIcon).toBeVisible(); - await expect(encryptedRoomPage.lastMessage.body).toHaveText( - 'This message is end-to-end encrypted. To view it, you must enter your encryption key in your account settings.', - ); - }); - - test('expect placeholder text in place of encrypted file upload description', async ({ page }) => { - const encryptedRoomPage = new EncryptedRoomPage(page); - const loginPage = new LoginPage(page); - const saveE2EEPasswordBanner = new SaveE2EEPasswordBanner(page); - const saveE2EEPasswordModal = new SaveE2EEPasswordModal(page); - const fileUploadModal = new FileUploadModal(page); - const sidenav = new HomeSidenav(page); - - const channelName = faker.string.uuid(); - const fileName = faker.system.commonFileName('txt'); - const fileDescription = faker.lorem.sentence(); - - // Click the banner to open the dialog to save the generated password - await saveE2EEPasswordBanner.click(); - await saveE2EEPasswordModal.confirm(); - await saveE2EEPasswordBanner.waitForDisappearance(); - - // Create an encrypted channel - await sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); - await expect(encryptedRoomPage.encryptionNotReadyIndicator).not.toBeVisible(); - - await test.step('upload the file with encryption', async () => { - // Upload a file - await encryptedRoomPage.dragAndDropTxtFile(); - await fileUploadModal.setName(fileName); - await fileUploadModal.setDescription(fileDescription); - await fileUploadModal.send(); - - // Check the file upload - await expect(encryptedRoomPage.lastMessage.encryptedIcon).toBeVisible(); - await expect(encryptedRoomPage.lastMessage.fileUploadName).toContainText(fileName); - await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription); - }); - - await test.step('disable encryption in the room', async () => { - await encryptedRoomPage.disableEncryption(); - await expect(encryptedRoomPage.encryptedIcon).not.toBeVisible(); - }); - - await test.step('upload the file without encryption', async () => { - await encryptedRoomPage.dragAndDropTxtFile(); - await fileUploadModal.setName(fileName); - await fileUploadModal.setDescription(fileDescription); - await fileUploadModal.send(); - - await expect(encryptedRoomPage.lastMessage.encryptedIcon).not.toBeVisible(); - await expect(encryptedRoomPage.lastMessage.fileUploadName).toContainText(fileName); - await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription); - }); - - await test.step('enable encryption in the room', async () => { - await encryptedRoomPage.enableEncryption(); - await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); - }); - - // Log out - await sidenav.logout(); - - // Login again - await loginPage.loginByUserState(Users.admin); - - await expect(sidenav.btnCreateNew).toBeVisible(); - - await sidenav.openChat(channelName); - await expect(encryptedRoomPage.encryptedIcon).toBeVisible(); - - await expect(encryptedRoomPage.lastNthMessage(1).body).toHaveText( - 'This message is end-to-end encrypted. To view it, you must enter your encryption key in your account settings.', - ); - await expect(encryptedRoomPage.lastNthMessage(1).encryptedIcon).toBeVisible(); - - await expect(encryptedRoomPage.lastMessage.encryptedIcon).not.toBeVisible(); - await expect(encryptedRoomPage.lastMessage.fileUploadName).toContainText(fileName); - await expect(encryptedRoomPage.lastMessage.body).toHaveText(fileDescription); - }); - - test('should display only the download file method when exporting messages in an e2ee room', async ({ page }) => { - const sidenav = new HomeSidenav(page); - const encryptedRoomPage = new EncryptedRoomPage(page); - const exportMessagesTab = new ExportMessagesTab(page); - - const channelName = faker.string.uuid(); - - await sidenav.createEncryptedChannel(channelName); - await expect(page).toHaveURL(`/group/${channelName}`); - await expect(encryptedRoomPage.encryptedRoomHeaderIcon).toBeVisible(); - - await encryptedRoomPage.showExportMessagesTab(); - await expect(exportMessagesTab.method).toContainClass('disabled'); // FIXME: looks like the component have an a11y issue - await expect(exportMessagesTab.method).toHaveAccessibleName('Download file'); - }); - - test('should allow exporting messages as PDF in an encrypted room', async ({ page }) => { - const sidenav = new HomeSidenav(page); - const encryptedRoomPage = new EncryptedRoomPage(page); - const exportMessagesTab = new ExportMessagesTab(page); - - const channelName = faker.string.uuid(); - - await sidenav.createEncryptedChannel(channelName); - await expect(page).toHaveURL(`/group/${channelName}`); - await expect(encryptedRoomPage.encryptedRoomHeaderIcon).toBeVisible(); - - await encryptedRoomPage.sendMessage('This is a message to export as PDF.'); - await encryptedRoomPage.showExportMessagesTab(); - await expect(exportMessagesTab.method).toHaveAccessibleName('Download file'); - - // Select Output format as PDF - await exportMessagesTab.setOutputFormat('PDF'); - - // select messages to be exported - await exportMessagesTab.selectAllMessages(); - - // Wait for download event and match format - const download = await exportMessagesTab.downloadMessages(); - expect(download.suggestedFilename()).toMatch(/\.pdf$/); - }); -}); - -test.describe('e2e-encryption', () => { - let poHomeChannel: HomeChannel; - - test.use({ storageState: Users.userE2EE.state }); - - test.beforeAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: true }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); - }); - - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); - }); - - test.beforeEach(async ({ page }) => { - poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - }); - - test('expect create a private channel encrypted and send an encrypted message', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('hello world'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await poHomeChannel.tabs.kebab.click({ force: true }); - - await expect(poHomeChannel.tabs.btnDisableE2E).toBeVisible(); - await poHomeChannel.tabs.btnDisableE2E.click({ force: true }); - await expect(page.getByRole('dialog', { name: 'Disable encryption' })).toBeVisible(); - await page.getByRole('button', { name: 'Disable encryption' }).click(); - await poHomeChannel.dismissToast(); - await page.waitForTimeout(1000); - - await poHomeChannel.content.sendMessage('hello world not encrypted'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world not encrypted'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).not.toBeVisible(); - - await poHomeChannel.tabs.kebab.click({ force: true }); - await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); - await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); - await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); - await page.getByRole('button', { name: 'Enable encryption' }).click(); - await poHomeChannel.dismissToast(); - await page.waitForTimeout(1000); - - await poHomeChannel.content.sendMessage('hello world encrypted again'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world encrypted again'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - }); - - test('expect create a private encrypted channel and send a encrypted thread message', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('This is the thread main message.'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is the thread main message.'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await page.locator('[data-qa-type="message"]').last().hover(); - await page.locator('role=button[name="Reply in thread"]').click(); - - await expect(page).toHaveURL(/.*thread/); - - await expect(poHomeChannel.content.mainThreadMessageText).toContainText('This is the thread main message.'); - await expect(poHomeChannel.content.mainThreadMessageText.locator('.rcx-icon--name-key')).toBeVisible(); - - await poHomeChannel.content.toggleAlsoSendThreadToChannel(true); - await page.getByRole('dialog').locator('[name="msg"]').last().fill('This is an encrypted thread message also sent in channel'); - await page.keyboard.press('Enter'); - await expect(poHomeChannel.content.lastThreadMessageText).toContainText('This is an encrypted thread message also sent in channel'); - await expect(poHomeChannel.content.lastThreadMessageText.locator('.rcx-icon--name-key')).toBeVisible(); - await expect(poHomeChannel.content.lastUserMessage).toContainText('This is an encrypted thread message also sent in channel'); - await expect(poHomeChannel.content.mainThreadMessageText).toContainText('This is the thread main message.'); - await expect(poHomeChannel.content.mainThreadMessageText.locator('.rcx-icon--name-key')).toBeVisible(); - }); - - test('expect create a private encrypted channel and check disabled message menu actions on an encrypted message', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('This is an encrypted message.'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await page.locator('[data-qa-type="message"]').last().hover(); - await expect(page.locator('role=button[name="Forward message not available on encrypted content"]')).toBeDisabled(); - - await poHomeChannel.content.openLastMessageMenu(); - - await expect(page.locator('role=menuitem[name="Reply in direct message"]')).toHaveClass(/disabled/); - await expect(page.locator('role=menuitem[name="Copy link"]')).toHaveClass(/disabled/); - }); - - test('expect create a private channel, encrypt it and send an encrypted message', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.btnCreate.click(); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.toastSuccess).toBeVisible(); - - await poHomeChannel.dismissToast(); - - await poHomeChannel.tabs.kebab.click(); - await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); - await poHomeChannel.tabs.btnEnableE2E.click(); - await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); - await page.getByRole('button', { name: 'Enable encryption' }).click(); - await page.waitForTimeout(1000); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('hello world'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - }); - - test('expect create a encrypted private channel and mention user', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('hello @user1'); - - const userMention = page.getByRole('button', { - name: 'user1', - }); - - await expect(userMention).toBeVisible(); - }); - - test('expect create a encrypted private channel, mention a channel and navigate to it', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('Are you in the #general channel?'); - - const channelMention = page.getByRole('button', { - name: 'general', - }); - - await expect(channelMention).toBeVisible(); - - await channelMention.click(); - - await expect(page).toHaveURL(`/channel/general`); - }); - - test('expect create a encrypted private channel, mention a channel and user', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('Are you in the #general channel, @user1 ?'); - - const channelMention = page.getByRole('button', { - name: 'general', - }); - - const userMention = page.getByRole('button', { - name: 'user1', - }); - - await expect(userMention).toBeVisible(); - await expect(channelMention).toBeVisible(); - }); - - test('should encrypted field be available on edit room', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.btnCreate.click(); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.toastSuccess).toBeVisible(); - - await poHomeChannel.dismissToast(); - - await poHomeChannel.tabs.btnRoomInfo.click(); - await poHomeChannel.tabs.room.btnEdit.click(); - await poHomeChannel.tabs.room.advancedSettingsAccordion.click(); - - await expect(poHomeChannel.tabs.room.checkboxEncrypted).toBeVisible(); - }); - - test('expect create a Direct message, encrypt it and attempt to enable OTR', async ({ page }) => { - await poHomeChannel.sidenav.openNewByLabel('Direct message'); - await poHomeChannel.sidenav.inputDirectUsername.click(); - await page.keyboard.type('user2'); - await page.waitForTimeout(1000); - await page.keyboard.press('Enter'); - await poHomeChannel.sidenav.btnCreate.click(); - - await expect(page).toHaveURL(`/direct/user2${Users.userE2EE.data.username}`); - - await poHomeChannel.tabs.kebab.click({ force: true }); - if (await poHomeChannel.tabs.btnDisableE2E.isVisible()) { - await poHomeChannel.tabs.btnDisableE2E.click({ force: true }); - await expect(page.getByRole('dialog', { name: 'Disable encryption' })).toBeVisible(); - await page.getByRole('button', { name: 'Disable encryption' }).click(); - await poHomeChannel.dismissToast(); - await poHomeChannel.tabs.kebab.click({ force: true }); - } - await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); - await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); - await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); - await page.getByRole('button', { name: 'Enable encryption' }).click(); - await page.waitForTimeout(1000); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.dismissToast(); - - await poHomeChannel.tabs.kebab.click({ force: true }); - await expect(poHomeChannel.tabs.btnEnableOTR).toBeVisible(); - await poHomeChannel.tabs.btnEnableOTR.click({ force: true }); - - await expect(page.getByText('OTR not available')).toBeVisible(); - }); - - test.describe('File Encryption', async () => { - test.afterAll(async ({ api }) => { - await api.post('/settings/FileUpload_MediaTypeWhiteList', { value: '' }); - await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'image/svg+xml' }); - }); - - test('File and description encryption', async ({ page }) => { - await test.step('create an encrypted channel', async () => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - }); - - await test.step('send a file in channel', async () => { - await poHomeChannel.content.dragAndDropTxtFile(); - await poHomeChannel.content.descriptionInput.fill('any_description'); - await poHomeChannel.content.fileNameInput.fill('any_file1.txt'); - await poHomeChannel.content.btnModalConfirm.click(); - - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - await expect(poHomeChannel.content.getFileDescription).toHaveText('any_description'); - await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file1.txt'); - }); - }); - - test('File encryption with whitelisted and blacklisted media types', async ({ page, api }) => { - await test.step('create an encrypted room', async () => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - }); - - await test.step('send a text file in channel', async () => { - await poHomeChannel.content.dragAndDropTxtFile(); - await poHomeChannel.content.descriptionInput.fill('message 1'); - await poHomeChannel.content.fileNameInput.fill('any_file1.txt'); - await poHomeChannel.content.btnModalConfirm.click(); - - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - await expect(poHomeChannel.content.getFileDescription).toHaveText('message 1'); - await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file1.txt'); - }); - - await test.step('set whitelisted media type setting', async () => { - await api.post('/settings/FileUpload_MediaTypeWhiteList', { value: 'text/plain' }); - }); - - await test.step('send text file again with whitelist setting set', async () => { - await poHomeChannel.content.dragAndDropTxtFile(); - await poHomeChannel.content.descriptionInput.fill('message 2'); - await poHomeChannel.content.fileNameInput.fill('any_file2.txt'); - await poHomeChannel.content.btnModalConfirm.click(); - - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - await expect(poHomeChannel.content.getFileDescription).toHaveText('message 2'); - await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file2.txt'); - }); - - await test.step('set blacklisted media type setting to not accept application/octet-stream media type', async () => { - await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'application/octet-stream' }); - }); - - await test.step('send text file again with blacklisted setting set, file upload should fail', async () => { - await poHomeChannel.content.dragAndDropTxtFile(); - await poHomeChannel.content.descriptionInput.fill('message 3'); - await poHomeChannel.content.fileNameInput.fill('any_file3.txt'); - await poHomeChannel.content.btnModalConfirm.click(); - - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - await expect(poHomeChannel.content.getFileDescription).toHaveText('message 2'); - await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file2.txt'); - }); - }); - - test.describe('File encryption setting disabled', async () => { - test.beforeAll(async ({ api }) => { - await api.post('/settings/E2E_Enable_Encrypt_Files', { value: false }); - await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'application/octet-stream' }); - }); - - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); - await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'image/svg+xml' }); - }); - - test('Upload file without encryption in e2ee room', async ({ page }) => { - await test.step('create an encrypted channel', async () => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - }); - - await test.step('send a test encrypted message to check e2ee is working', async () => { - await poHomeChannel.content.sendMessage('This is an encrypted message.'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - }); - - await test.step('send a text file in channel, file should not be encrypted', async () => { - await poHomeChannel.content.dragAndDropTxtFile(); - await poHomeChannel.content.descriptionInput.fill('any_description'); - await poHomeChannel.content.fileNameInput.fill('any_file1.txt'); - await poHomeChannel.content.btnModalConfirm.click(); - - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).not.toBeVisible(); - await expect(poHomeChannel.content.getFileDescription).toHaveText('any_description'); - await expect(poHomeChannel.content.lastMessageFileName).toContainText('any_file1.txt'); - }); - }); - }); - }); - - test('expect slash commands to be enabled in an e2ee room', async ({ page }) => { - test.skip(!IS_EE, 'Premium Only'); - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('This is an encrypted message.'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await page.locator('[name="msg"]').type('/'); - await expect(page.locator('#popup-item-contextualbar')).not.toHaveClass(/disabled/); - await page.locator('[name="msg"]').clear(); - - await poHomeChannel.content.dispatchSlashCommand('/contextualbar'); - await expect(poHomeChannel.btnContextualbarClose).toBeVisible(); - - await poHomeChannel.btnContextualbarClose.click(); - await expect(poHomeChannel.btnContextualbarClose).toBeHidden(); - }); - - test.describe('un-encrypted messages not allowed in e2ee rooms', () => { - test.skip(!IS_EE, 'Premium Only'); - let poHomeChannel: HomeChannel; - - test.beforeEach(async ({ page }) => { - poHomeChannel = new HomeChannel(page); - await page.goto('/home'); - }); - test.beforeAll(async ({ api }) => { - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); - }); - - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - }); - - test('expect slash commands to be disabled in an e2ee room', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('This is an encrypted message.'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This is an encrypted message.'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await page.locator('[name="msg"]').pressSequentially('/'); - await expect(page.locator('#popup-item-contextualbar')).toHaveClass(/disabled/); - }); - }); - - test('expect create a private channel, send unecrypted messages, encrypt the channel and delete the last message and check the last message in the sidebar', async ({ - page, - }) => { - const channelName = faker.string.uuid(); - - // Enable Sidebar Extended display mode - await poHomeChannel.sidenav.setDisplayMode('Extended'); - - // Create private channel - await poHomeChannel.sidenav.openNewByLabel('Channel'); - await poHomeChannel.sidenav.inputChannelName.fill(channelName); - await poHomeChannel.sidenav.btnCreate.click(); - await expect(page).toHaveURL(`/group/${channelName}`); - await expect(poHomeChannel.toastSuccess).toBeVisible(); - await poHomeChannel.dismissToast(); - - // Send Unencrypted Messages - await poHomeChannel.content.sendMessage('first unencrypted message'); - await poHomeChannel.content.sendMessage('second unencrypted message'); - - // Encrypt channel - await poHomeChannel.tabs.kebab.click({ force: true }); - await expect(poHomeChannel.tabs.btnEnableE2E).toBeVisible(); - await poHomeChannel.tabs.btnEnableE2E.click({ force: true }); - await expect(page.getByRole('dialog', { name: 'Enable encryption' })).toBeVisible(); - await page.getByRole('button', { name: 'Enable encryption' }).click(); - await page.waitForTimeout(1000); - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - // Send Encrypted Messages - const encriptedMessage1 = 'first ENCRYPTED message'; - const encriptedMessage2 = 'second ENCRYPTED message'; - await poHomeChannel.content.sendMessage(encriptedMessage1); - await poHomeChannel.content.sendMessage(encriptedMessage2); - - // Delete last message - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText(encriptedMessage2); - await poHomeChannel.content.openLastMessageMenu(); - await page.locator('role=menuitem[name="Delete"]').click(); - await page.locator('#modal-root .rcx-button-group--align-end .rcx-button--danger').click(); - - // Check last message in the sidebar - const sidebarChannel = poHomeChannel.sidenav.getSidebarItemByName(channelName); - await expect(sidebarChannel).toBeVisible(); - await expect(sidebarChannel.locator('span')).toContainText(encriptedMessage1); - }); - - test('expect create a private encrypted channel and pin/star an encrypted message', async ({ page }) => { - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible(); - - await poHomeChannel.content.sendMessage('This message should be pinned and stared.'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('This message should be pinned and stared.'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await poHomeChannel.content.openLastMessageMenu(); - await page.locator('role=menuitem[name="Star"]').click(); - - await expect(poHomeChannel.toastSuccess).toBeVisible(); - await poHomeChannel.dismissToast(); - - await poHomeChannel.content.openLastMessageMenu(); - await page.locator('role=menuitem[name="Pin"]').click(); - await page.locator('#modal-root >> button:has-text("Yes, pin message")').click(); - - await expect(poHomeChannel.toastSuccess).toBeVisible(); - await poHomeChannel.dismissToast(); - - await poHomeChannel.tabs.kebab.click(); - await poHomeChannel.tabs.btnPinnedMessagesList.click(); - - await expect(page.getByRole('dialog', { name: 'Pinned Messages' })).toBeVisible(); - - const lastPinnedMessage = page.getByRole('dialog', { name: 'Pinned Messages' }).locator('[data-qa-type="message"]').last(); - await expect(lastPinnedMessage).toContainText('This message should be pinned and stared.'); - await lastPinnedMessage.hover(); - await lastPinnedMessage.locator('role=button[name="More"]').waitFor(); - await lastPinnedMessage.locator('role=button[name="More"]').click(); - await expect(page.locator('role=menuitem[name="Copy link"]')).toHaveClass(/disabled/); - - await poHomeChannel.btnContextualbarClose.click(); - - await poHomeChannel.tabs.kebab.click(); - await poHomeChannel.tabs.btnStarredMessageList.click(); - - const lastStarredMessage = page.getByRole('dialog', { name: 'Starred Messages' }).locator('[data-qa-type="message"]').last(); - await expect(page.getByRole('dialog', { name: 'Starred Messages' })).toBeVisible(); - await expect(lastStarredMessage).toContainText('This message should be pinned and stared.'); - await lastStarredMessage.hover(); - await lastStarredMessage.locator('role=button[name="More"]').waitFor(); - await lastStarredMessage.locator('role=button[name="More"]').click(); - await expect(page.locator('role=menuitem[name="Copy link"]')).toHaveClass(/disabled/); - }); - - test('legacy expect create a private channel encrypted and send an encrypted message', async ({ page, request }) => { - const channelName = faker.string.uuid(); - - await restoreState(page, Users.userE2EE, { except: ['private_key', 'public_key', 'e2e.randomPassword'] }); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(page.getByTitle('Encrypted')).toBeVisible(); - // TODO: Fix this flakiness - await expect(page.getByRole('button', { name: 'Send' })).toBeVisible(); - - const rid = await page.locator('[data-qa-rc-room]').getAttribute('data-qa-rc-room'); - - // send old format encrypted message via API - const msg = await page.evaluate(async (rid) => { - // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path - const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); - const e2eRoom = await e2e.getInstanceByRoomId(rid); - return e2eRoom.encrypt({ _id: 'id', msg: 'Old format message' }); - }, rid); - - await request.post(`${BASE_API_URL}/chat.sendMessage`, { - headers: { - 'X-Auth-Token': Users.userE2EE.data.loginToken, - 'X-User-Id': Users.userE2EE.data._id, - }, - data: { - message: { - rid, - msg, - t: 'e2e', - }, - }, - }); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('Old format message'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - }); - - test.describe('reset keys', () => { - let anotherClientPage: Page; - - test.beforeEach(async ({ browser }) => { - anotherClientPage = (await createAuxContext(browser, Users.userE2EE)).page; - }); - - test.afterEach(async () => { - await anotherClientPage.close(); - }); - - test('expect force logout on e2e keys reset', async ({ page }) => { - const poAccountProfile = new AccountProfile(page); - - await page.goto('/account/security'); - - await poAccountProfile.securityE2EEncryptionSection.click(); - await poAccountProfile.securityE2EEncryptionResetKeyButton.click(); - - await expect(page.locator('role=button[name="Login"]')).toBeVisible(); - await expect(anotherClientPage.locator('role=button[name="Login"]')).toBeVisible(); - }); - }); -}); - -test.use({ storageState: Users.admin.state }); - -test.describe.serial('e2ee room setup', () => { - let poAccountProfile: AccountProfile; - let poHomeChannel: HomeChannel; - let e2eePassword: string; - - test.beforeEach(async ({ page }) => { - poAccountProfile = new AccountProfile(page); - poHomeChannel = new HomeChannel(page); - }); - - test.beforeAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: true }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); - }); - - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - }); - - test.afterEach(async ({ api }) => { - await api.recreateContext(); - }); - - test('expect save password state on encrypted room', async ({ page }) => { - await page.goto('/account/security'); - await poAccountProfile.securityE2EEncryptionSection.click(); - await poAccountProfile.securityE2EEncryptionResetKeyButton.click(); - - await page.locator('role=button[name="Login"]').waitFor(); - - await injectInitialData(); - await restoreState(page, Users.admin); - - await page.goto('/home'); - - await page.waitForSelector('#main-content'); - - await expect(poHomeChannel.bannerSaveEncryptionPassword).toBeVisible(); - - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); - await expect(poHomeChannel.btnRoomSaveE2EEPassword).toBeVisible(); - - await poHomeChannel.tabs.btnE2EERoomSetupDisableE2E.waitFor(); - await expect(poHomeChannel.tabs.btnE2EERoomSetupDisableE2E).toBeVisible(); - await expect(poHomeChannel.tabs.btnTabMembers).toBeVisible(); - await expect(poHomeChannel.tabs.btnRoomInfo).toBeVisible(); - - await expect(poHomeChannel.content.inputMessage).not.toBeVisible(); - - await poHomeChannel.btnRoomSaveE2EEPassword.click(); - - e2eePassword = (await page.evaluate(() => localStorage.getItem('e2e.randomPassword'))) || 'undefined'; - - await expect(poHomeChannel.dialogSaveE2EEPassword).toBeVisible(); - await expect(poHomeChannel.dialogSaveE2EEPassword).toContainText(e2eePassword); - - await poHomeChannel.btnSavedMyPassword.click(); - - await poHomeChannel.content.inputMessage.waitFor(); - - await poHomeChannel.content.sendMessage('hello world'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - }); - - test('expect enter password state on encrypted room', async ({ page }) => { - await page.goto('/home'); - - // Logout to remove e2ee keys - await poHomeChannel.sidenav.logout(); - - await page.locator('role=button[name="Login"]').waitFor(); - - await injectInitialData(); - await restoreState(page, Users.admin, { except: ['private_key', 'public_key'] }); - - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); - - await poHomeChannel.btnRoomEnterE2EEPassword.waitFor(); - - await expect(poHomeChannel.btnRoomEnterE2EEPassword).toBeVisible(); - - await poHomeChannel.tabs.btnE2EERoomSetupDisableE2E.waitFor(); - await expect(poHomeChannel.tabs.btnE2EERoomSetupDisableE2E).toBeVisible(); - await expect(poHomeChannel.tabs.btnTabMembers).toBeVisible(); - await expect(poHomeChannel.tabs.btnRoomInfo).toBeVisible(); - - await expect(poHomeChannel.content.inputMessage).not.toBeVisible(); - - await poHomeChannel.btnRoomEnterE2EEPassword.click(); - - await page.locator('#modal-root input').fill(e2eePassword); - - await page.locator('#modal-root .rcx-button--primary').click(); - - await expect(poHomeChannel.bannerEnterE2EEPassword).not.toBeVisible(); - - await poHomeChannel.content.inputMessage.waitFor(); - // For E2EE to complete init setup - await page.waitForTimeout(300); - - await poHomeChannel.content.sendMessage('hello world'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await storeState(page, Users.admin); - }); - - test('expect waiting for room keys state', async ({ page }) => { - await page.goto('/home'); - - const channelName = faker.string.uuid(); - - await poHomeChannel.sidenav.createEncryptedChannel(channelName); - - await expect(page).toHaveURL(`/group/${channelName}`); - - await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible(); - - await poHomeChannel.content.sendMessage('hello world'); - - await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('hello world'); - await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); - - await poHomeChannel.sidenav.btnUserProfileMenu.click(); - await poHomeChannel.sidenav.accountProfileOption.click(); - - await page.locator('role=navigation >> a:has-text("Security")').click(); - - await poAccountProfile.securityE2EEncryptionSection.click(); - await poAccountProfile.securityE2EEncryptionResetKeyButton.click(); - - await page.locator('role=button[name="Login"]').waitFor(); - - await page.reload(); - - await page.locator('role=button[name="Login"]').waitFor(); - - await injectInitialData(); - await restoreState(page, Users.admin); - - await page.locator('role=navigation >> role=button[name=Search]').click(); - await page.locator('role=search >> role=searchbox').fill(channelName); - await page.locator(`role=search >> role=listbox >> role=link >> text="${channelName}"`).click(); - - await poHomeChannel.btnRoomSaveE2EEPassword.click(); - await poHomeChannel.btnSavedMyPassword.click(); - - await expect(poHomeChannel.content.inputMessage).not.toBeVisible(); - await expect(page.locator('.rcx-states__title')).toContainText('Check back later'); - - await poHomeChannel.tabs.btnE2EERoomSetupDisableE2E.waitFor(); - await expect(poHomeChannel.tabs.btnE2EERoomSetupDisableE2E).toBeVisible(); - await expect(poHomeChannel.tabs.btnTabMembers).toBeVisible(); - await expect(poHomeChannel.tabs.btnRoomInfo).toBeVisible(); - }); -}); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts index 85722c343f8dd..d74ed7fe85865 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts @@ -2,29 +2,17 @@ import { faker } from '@faker-js/faker'; import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; -import { getSettingValueById } from '../utils'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; -const settings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, - E2E_Enabled_Default_DirectRooms: false as unknown, - E2E_Enabled_Default_PrivateRooms: false as unknown, -}; - -test.beforeAll(async ({ api }) => { - settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); - settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); - settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); -}); +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; -test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); -}); +preserveSettings(settingsList); test.describe('E2EE Encrypted Channels', () => { let poHomeChannel: HomeChannel; diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts index b4afd8d5cd014..cbd7f822599e8 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encryption-decryption.spec.ts @@ -6,23 +6,12 @@ import { HomeSidenav } from '../page-objects/fragments'; import { SaveE2EEPasswordBanner, SaveE2EEPasswordModal } from '../page-objects/fragments/e2ee'; import { FileUploadModal } from '../page-objects/fragments/file-upload-modal'; import { LoginPage } from '../page-objects/login'; -import { getSettingValueById } from '../utils'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; -const settings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, -}; +const settingsList = ['E2E_Enable', 'E2E_Allow_Unencrypted_Messages']; -test.beforeAll(async ({ api }) => { - settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); -}); - -test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); -}); +preserveSettings(settingsList); test.describe('E2EE Encryption and Decryption - Basic Features', () => { test.use({ storageState: Users.admin.state }); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts index db6ef9bd07f6f..0fbd35e57fb7d 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts @@ -2,32 +2,18 @@ import { faker } from '@faker-js/faker'; import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; -import { getSettingValueById } from '../utils'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; -const settings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, - E2E_Enable_Encrypt_Files: false as unknown, - E2E_Enabled_Default_DirectRooms: false as unknown, - E2E_Enabled_Default_PrivateRooms: false as unknown, -}; - -test.beforeAll(async ({ api }) => { - settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); - settings.E2E_Enable_Encrypt_Files = await getSettingValueById(api, 'E2E_Enable_Encrypt_Files'); - settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); - settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); -}); +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enable_Encrypt_Files', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; -test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); -}); +const originalSettings = preserveSettings(settingsList); test.describe('E2EE File Encryption', () => { let poHomeChannel: HomeChannel; @@ -135,7 +121,7 @@ test.describe('E2EE File Encryption', () => { }); test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable_Encrypt_Files', { value: settings.E2E_Enable_Encrypt_Files }); + await api.post('/settings/E2E_Enable_Encrypt_Files', { value: originalSettings.E2E_Enable_Encrypt_Files }); await api.post('/settings/FileUpload_MediaTypeBlackList', { value: 'image/svg+xml' }); }); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts index 26bd0a49de0a3..494da56855688 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts @@ -3,29 +3,17 @@ import type { Page } from '@playwright/test'; import { createAuxContext } from '../fixtures/createAuxContext'; import { Users } from '../fixtures/userStates'; import { AccountProfile } from '../page-objects'; -import { getSettingValueById } from '../utils'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; -const settings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, - E2E_Enabled_Default_DirectRooms: false as unknown, - E2E_Enabled_Default_PrivateRooms: false as unknown, -}; - -test.beforeAll(async ({ api }) => { - settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); - settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); - settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); -}); +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; -test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); -}); +preserveSettings(settingsList); test.describe('E2EE Key Reset', () => { let anotherClientPage: Page; diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts index 07f7da4b9fe8c..c8f23623919b0 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts @@ -4,29 +4,17 @@ import { BASE_API_URL } from '../config/constants'; import injectInitialData from '../fixtures/inject-initial-data'; import { Users, restoreState } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; -import { getSettingValueById } from '../utils'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; -const settings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, - E2E_Enabled_Default_DirectRooms: false as unknown, - E2E_Enabled_Default_PrivateRooms: false as unknown, -}; - -test.beforeAll(async ({ api }) => { - settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); - settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); - settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); -}); +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; -test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); -}); +preserveSettings(settingsList); test.describe('E2EE Legacy Format', () => { let poHomeChannel: HomeChannel; diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts index ef443ae44fc76..4c9b16ce21199 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts @@ -1,28 +1,16 @@ import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; -import { getSettingValueById } from '../utils'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; -const settings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, - E2E_Enabled_Default_DirectRooms: false as unknown, - E2E_Enabled_Default_PrivateRooms: false as unknown, -}; +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; -test.beforeAll(async ({ api }) => { - settings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - settings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); - settings.E2E_Enabled_Default_DirectRooms = await getSettingValueById(api, 'E2E_Enabled_Default_DirectRooms'); - settings.E2E_Enabled_Default_PrivateRooms = await getSettingValueById(api, 'E2E_Enabled_Default_PrivateRooms'); -}); - -test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: settings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: settings.E2E_Allow_Unencrypted_Messages }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: settings.E2E_Enabled_Default_DirectRooms }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: settings.E2E_Enabled_Default_PrivateRooms }); -}); +preserveSettings(settingsList); test.describe('E2EE OTR (Off-The-Record)', () => { let poHomeChannel: HomeChannel; diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts index ee9883009f393..5acd23049c6ca 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-passphrase-management.spec.ts @@ -14,14 +14,22 @@ import { SaveE2EEPasswordModal, } from '../page-objects/fragments/e2ee'; import { LoginPage } from '../page-objects/login'; -import { getSettingValueById } from '../utils'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; + +const originalSettings = preserveSettings(settingsList); + test.describe('E2EE Passphrase Management - Initial Setup', () => { test.use({ storageState: Users.admin.state }); test.beforeAll(async ({ api }) => { - // Set settings for this describe block only await api.post('/settings/E2E_Enable', { value: true }); await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); @@ -29,11 +37,10 @@ test.describe('E2EE Passphrase Management - Initial Setup', () => { }); test.afterAll(async ({ api }) => { - // Restore original settings - await api.post('/settings/E2E_Enable', { value: false }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); - await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); - await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); + await api.post('/settings/E2E_Enable', { value: originalSettings.E2E_Enable }); + await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: originalSettings.E2E_Allow_Unencrypted_Messages }); + await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: originalSettings.E2E_Enabled_Default_DirectRooms }); + await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: originalSettings.E2E_Enabled_Default_PrivateRooms }); }); test.beforeEach(async ({ api, page }) => { @@ -148,33 +155,25 @@ test.describe('E2EE Passphrase Management - Initial Setup', () => { test.use({ storageState: Users.admin.state }); -const roomSetupSettings = { - E2E_Enable: false as unknown, - E2E_Allow_Unencrypted_Messages: false as unknown, -}; +const roomSetupSettingsList = ['E2E_Enable', 'E2E_Allow_Unencrypted_Messages']; test.describe.serial('E2EE Passphrase Management - Room Setup States', () => { let poAccountProfile: AccountProfile; let poHomeChannel: HomeChannel; let e2eePassword: string; + preserveSettings(roomSetupSettingsList); + test.beforeEach(async ({ page }) => { poAccountProfile = new AccountProfile(page); poHomeChannel = new HomeChannel(page); }); test.beforeAll(async ({ api }) => { - roomSetupSettings.E2E_Enable = await getSettingValueById(api, 'E2E_Enable'); - roomSetupSettings.E2E_Allow_Unencrypted_Messages = await getSettingValueById(api, 'E2E_Allow_Unencrypted_Messages'); await api.post('/settings/E2E_Enable', { value: true }); await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: false }); }); - test.afterAll(async ({ api }) => { - await api.post('/settings/E2E_Enable', { value: roomSetupSettings.E2E_Enable }); - await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: roomSetupSettings.E2E_Allow_Unencrypted_Messages }); - }); - test.afterEach(async ({ api }) => { await api.recreateContext(); }); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts index b3e2ee71260bc..610ce150d86d2 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-pdf-export.spec.ts @@ -5,8 +5,18 @@ import { EncryptedRoomPage } from '../page-objects/encrypted-room'; import { HomeSidenav } from '../page-objects/fragments'; import { ExportMessagesTab } from '../page-objects/fragments/export-messages-tab'; import { LoginPage } from '../page-objects/login'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; + +preserveSettings(settingsList); + test.describe('E2EE PDF Export', () => { test.use({ storageState: Users.admin.state }); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts index 7196bdd2e7a71..8556331f5eca3 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts @@ -3,8 +3,18 @@ import { faker } from '@faker-js/faker'; import { IS_EE } from '../config/constants'; import { Users } from '../fixtures/userStates'; import { HomeChannel } from '../page-objects'; +import { preserveSettings } from '../utils/preserveSettings'; import { test, expect } from '../utils/test'; +const settingsList = [ + 'E2E_Enable', + 'E2E_Allow_Unencrypted_Messages', + 'E2E_Enabled_Default_DirectRooms', + 'E2E_Enabled_Default_PrivateRooms', +]; + +preserveSettings(settingsList); + test.describe('E2EE Server Settings', () => { let poHomeChannel: HomeChannel; diff --git a/apps/meteor/tests/e2e/utils/preserveSettings.ts b/apps/meteor/tests/e2e/utils/preserveSettings.ts new file mode 100644 index 0000000000000..8521fcb5e69e3 --- /dev/null +++ b/apps/meteor/tests/e2e/utils/preserveSettings.ts @@ -0,0 +1,19 @@ +import { getSettingValueById } from './getSettingValueById'; +import { test } from './test'; + +export function preserveSettings(settingsList: string[]) { + const originalSettings: Record = {}; + + test.beforeAll(async ({ api }) => { + const settingValues = await Promise.all(settingsList.map((setting) => getSettingValueById(api, setting))); + settingsList.forEach((setting, index) => { + originalSettings[setting] = settingValues[index]; + }); + }); + + test.afterAll(async ({ api }) => { + await Promise.all(settingsList.map((setting) => api.post(`/settings/${setting}`, { value: originalSettings[setting] }))); + }); + + return originalSettings; +} From c47e86bfdfb525ef698e28c73711c95d8d203b72 Mon Sep 17 00:00:00 2001 From: Jessica Schelly Souza Date: Wed, 17 Sep 2025 12:18:52 -0300 Subject: [PATCH 4/5] review --- .../e2ee-encrypted-channels.spec.ts | 2 +- .../e2ee-file-encryption.spec.ts | 2 +- .../e2e/e2e-encryption/e2ee-key-reset.spec.ts | 2 +- .../e2e-encryption/e2ee-legacy-format.spec.ts | 54 +++++++++++-------- .../tests/e2e/e2e-encryption/e2ee-otr.spec.ts | 2 +- .../e2ee-server-settings.spec.ts | 2 +- 6 files changed, 38 insertions(+), 26 deletions(-) diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts index 2a4127e42aa54..56ab640f9ff3a 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-encrypted-channels.spec.ts @@ -24,7 +24,7 @@ test.describe('E2EE Encrypted Channels', () => { await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + await api.post('/im.delete', { username: 'user2' }); }); test.beforeEach(async ({ page }) => { diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts index 0fbd35e57fb7d..7b009c7723db8 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-file-encryption.spec.ts @@ -25,7 +25,7 @@ test.describe('E2EE File Encryption', () => { await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + await api.post('/im.delete', { username: 'user2' }); }); test.afterAll(async ({ api }) => { diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts index 494da56855688..fab641ba6021c 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-key-reset.spec.ts @@ -25,7 +25,7 @@ test.describe('E2EE Key Reset', () => { await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + await api.post('/im.delete', { username: 'user2' }); }); test.beforeEach(async ({ browser, page }) => { diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts index c8f23623919b0..06ea90159019f 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts @@ -1,4 +1,5 @@ import { faker } from '@faker-js/faker'; +import type { APIRequestContext, Page } from '@playwright/test'; import { BASE_API_URL } from '../config/constants'; import injectInitialData from '../fixtures/inject-initial-data'; @@ -26,7 +27,7 @@ test.describe('E2EE Legacy Format', () => { await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + await api.post('/im.delete', { username: 'user2' }); }); test.beforeEach(async ({ page }) => { @@ -34,6 +35,34 @@ test.describe('E2EE Legacy Format', () => { await page.goto('/home'); }); + const encryptLegacyMessage = async (page: Page, rid: string, messageText: string) => { + return page.evaluate( + async ({ rid, msg }: { rid: string; msg: string }) => { + // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path + const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); + const e2eRoom = await e2e.getInstanceByRoomId(rid); + return e2eRoom.encrypt({ _id: 'id', msg }); + }, + { rid, msg: messageText }, + ); + }; + + const sendEncryptedMessage = async (request: APIRequestContext, rid: string, encryptedMsg: string) => { + return request.post(`${BASE_API_URL}/chat.sendMessage`, { + headers: { + 'X-Auth-Token': Users.userE2EE.data.loginToken, + 'X-User-Id': Users.userE2EE.data._id, + }, + data: { + message: { + rid, + msg: encryptedMsg, + t: 'e2e', + }, + }, + }); + }; + test('legacy expect create a private channel encrypted and send an encrypted message', async ({ page, request }) => { const channelName = faker.string.uuid(); @@ -49,28 +78,11 @@ test.describe('E2EE Legacy Format', () => { await expect(page.getByRole('button', { name: 'Send' })).toBeVisible(); const rid = await page.locator('[data-qa-rc-room]').getAttribute('data-qa-rc-room'); + expect(rid).toBeTruthy(); - // send old format encrypted message via API - const msg = await page.evaluate(async (rid) => { - // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path - const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); - const e2eRoom = await e2e.getInstanceByRoomId(rid); - return e2eRoom.encrypt({ _id: 'id', msg: 'Old format message' }); - }, rid); + const encryptedMessage = await encryptLegacyMessage(page, rid as string, 'Old format message'); - await request.post(`${BASE_API_URL}/chat.sendMessage`, { - headers: { - 'X-Auth-Token': Users.userE2EE.data.loginToken, - 'X-User-Id': Users.userE2EE.data._id, - }, - data: { - message: { - rid, - msg, - t: 'e2e', - }, - }, - }); + await sendEncryptedMessage(request, rid as string, encryptedMessage); await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('Old format message'); await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible(); diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts index 4c9b16ce21199..b2c1e427dc974 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts @@ -22,7 +22,7 @@ test.describe('E2EE OTR (Off-The-Record)', () => { await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + await api.post('/im.delete', { username: 'user2' }); }); test.beforeEach(async ({ page }) => { diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts index 8556331f5eca3..9a6fd5de8576d 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-server-settings.spec.ts @@ -25,7 +25,7 @@ test.describe('E2EE Server Settings', () => { await api.post('/settings/E2E_Allow_Unencrypted_Messages', { value: true }); await api.post('/settings/E2E_Enabled_Default_DirectRooms', { value: false }); await api.post('/settings/E2E_Enabled_Default_PrivateRooms', { value: false }); - await api.post('/im.delete', { roomId: `user2${Users.userE2EE.data.username}` }); + await api.post('/im.delete', { username: 'user2' }); }); test.beforeEach(async ({ page }) => { From 4b6d2a168312558b8c4109c17473f3194933d364 Mon Sep 17 00:00:00 2001 From: dougfabris Date: Wed, 17 Sep 2025 15:32:44 -0300 Subject: [PATCH 5/5] fix: review --- .../e2e-encryption/e2ee-legacy-format.spec.ts | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts index 06ea90159019f..f82f7ba8a836a 100644 --- a/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts +++ b/apps/meteor/tests/e2e/e2e-encryption/e2ee-legacy-format.spec.ts @@ -17,6 +17,34 @@ const settingsList = [ preserveSettings(settingsList); +const encryptLegacyMessage = async (page: Page, rid: string, messageText: string) => { + return page.evaluate( + async ({ rid, msg }: { rid: string; msg: string }) => { + // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path + const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); + const e2eRoom = await e2e.getInstanceByRoomId(rid); + return e2eRoom.encrypt({ _id: 'id', msg }); + }, + { rid, msg: messageText }, + ); +}; + +const sendEncryptedMessage = async (request: APIRequestContext, rid: string, encryptedMsg: string) => { + return request.post(`${BASE_API_URL}/chat.sendMessage`, { + headers: { + 'X-Auth-Token': Users.userE2EE.data.loginToken, + 'X-User-Id': Users.userE2EE.data._id, + }, + data: { + message: { + rid, + msg: encryptedMsg, + t: 'e2e', + }, + }, + }); +}; + test.describe('E2EE Legacy Format', () => { let poHomeChannel: HomeChannel; @@ -35,34 +63,6 @@ test.describe('E2EE Legacy Format', () => { await page.goto('/home'); }); - const encryptLegacyMessage = async (page: Page, rid: string, messageText: string) => { - return page.evaluate( - async ({ rid, msg }: { rid: string; msg: string }) => { - // eslint-disable-next-line import/no-unresolved, @typescript-eslint/no-var-requires, import/no-absolute-path - const { e2e } = require('/client/lib/e2ee/rocketchat.e2e.ts'); - const e2eRoom = await e2e.getInstanceByRoomId(rid); - return e2eRoom.encrypt({ _id: 'id', msg }); - }, - { rid, msg: messageText }, - ); - }; - - const sendEncryptedMessage = async (request: APIRequestContext, rid: string, encryptedMsg: string) => { - return request.post(`${BASE_API_URL}/chat.sendMessage`, { - headers: { - 'X-Auth-Token': Users.userE2EE.data.loginToken, - 'X-User-Id': Users.userE2EE.data._id, - }, - data: { - message: { - rid, - msg: encryptedMsg, - t: 'e2e', - }, - }, - }); - }; - test('legacy expect create a private channel encrypted and send an encrypted message', async ({ page, request }) => { const channelName = faker.string.uuid(); @@ -77,12 +77,12 @@ test.describe('E2EE Legacy Format', () => { // TODO: Fix this flakiness await expect(page.getByRole('button', { name: 'Send' })).toBeVisible(); - const rid = await page.locator('[data-qa-rc-room]').getAttribute('data-qa-rc-room'); + const rid = (await page.locator('[data-qa-rc-room]').getAttribute('data-qa-rc-room')) || ''; expect(rid).toBeTruthy(); - const encryptedMessage = await encryptLegacyMessage(page, rid as string, 'Old format message'); + const encryptedMessage = await encryptLegacyMessage(page, rid, 'Old format message'); - await sendEncryptedMessage(request, rid as string, encryptedMessage); + await sendEncryptedMessage(request, rid, encryptedMessage); await expect(poHomeChannel.content.lastUserMessageBody).toHaveText('Old format message'); await expect(poHomeChannel.content.lastUserMessage.locator('.rcx-icon--name-key')).toBeVisible();