Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: E2EE room setup header #32446

Merged
merged 64 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
7f34310
add new e2ee setting
yash-rajpal Mar 19, 2024
153dcfc
add e2ee hooks
yash-rajpal Mar 20, 2024
3eb2ea7
Warning UI
yash-rajpal Mar 20, 2024
7a4d783
integrating everything
yash-rajpal Mar 20, 2024
8d67812
add translations
yash-rajpal Mar 21, 2024
9555bab
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal Mar 26, 2024
cdc74a1
small refactor
yash-rajpal Mar 26, 2024
3eaa671
don't allow un-encrypted messages on server side
yash-rajpal Mar 26, 2024
c2b2c3a
introduce e2ee states
yash-rajpal Mar 27, 2024
8106158
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal Mar 27, 2024
f8c7072
fix TS and fix lint
yash-rajpal Mar 28, 2024
82f748c
refactor and remove unused code
yash-rajpal Mar 28, 2024
391d7b6
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal Apr 3, 2024
2f0d7e7
Merge branch 'develop' into e2e-unencrypted-setting
scuciatto Apr 5, 2024
dab85c3
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal Apr 15, 2024
8de4308
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal Apr 19, 2024
cb170dd
needle in haystack
yash-rajpal Apr 19, 2024
25737f4
fix conflicts
yash-rajpal Apr 19, 2024
0856ca2
remove memoizing
yash-rajpal May 2, 2024
77d17fd
room with e2ee setup routing
yash-rajpal May 2, 2024
4616c09
remove useIsE2EEReady hook
yash-rajpal May 2, 2024
b967e0c
update docs link to go.rocket.chat url
yash-rajpal May 2, 2024
2053ccf
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal May 2, 2024
cc3072b
avoid attaching listners multiple times
yash-rajpal May 2, 2024
4ab7f35
add e2e tests
yash-rajpal May 2, 2024
9ec6345
review (#32365)
gabriellsh May 7, 2024
8b1143b
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal May 7, 2024
e7950d3
fix review
yash-rajpal May 8, 2024
93a6b99
fix: removing commments, replacing deprecated type method with fill a…
hugocostadev May 8, 2024
788f486
Merge branch 'develop' into e2e-unencrypted-setting
hugocostadev May 8, 2024
fb40c6c
e2e tests reuse channel creation
yash-rajpal May 8, 2024
b796f6e
comment floky test
yash-rajpal May 8, 2024
bc90e28
add cs
yash-rajpal May 8, 2024
f4c0e7f
release the instance on changing the room encrypted property
yash-rajpal May 13, 2024
b3f7281
oops: TS
yash-rajpal May 13, 2024
1248e0b
fix conflicts
yash-rajpal May 13, 2024
c99e8e9
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal May 13, 2024
67e531d
fix flaky test
yash-rajpal May 14, 2024
9ed110a
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal May 14, 2024
11c3eec
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal May 15, 2024
ad46696
setting description
yash-rajpal May 15, 2024
65ca6dc
wip: e2e setup room header
yash-rajpal May 16, 2024
85bb0f9
default setting value
yash-rajpal May 16, 2024
34b8db5
add cs
yash-rajpal May 16, 2024
e9ecad0
api test cases
yash-rajpal May 16, 2024
b8698a6
e2e tests setting value
yash-rajpal May 16, 2024
d0b80ee
more api tests
yash-rajpal May 16, 2024
5095b35
oops
yash-rajpal May 16, 2024
a023fa0
toast messages
yash-rajpal May 16, 2024
338659c
refactor
yash-rajpal May 16, 2024
563c9ca
hmm
yash-rajpal May 16, 2024
26b69df
tests
yash-rajpal May 16, 2024
fb7b612
Merge branch 'e2e-unencrypted-setting' into e2e-room-setup-header
yash-rajpal May 16, 2024
6993ca2
fix tests
yash-rajpal May 16, 2024
153c68c
Merge branch 'develop' into e2e-unencrypted-setting
yash-rajpal May 16, 2024
aa81aab
handle E2EE disabled case
yash-rajpal May 17, 2024
e00dbd0
handle wrong password case
yash-rajpal May 20, 2024
bf89e1d
Merge branch 'e2e-unencrypted-setting' into e2e-room-setup-header
yash-rajpal May 20, 2024
d14904c
fix tests
yash-rajpal May 20, 2024
6f23315
fix confs
yash-rajpal Jun 11, 2024
22d4844
use helper functions
yash-rajpal Jun 12, 2024
49f7b63
better TS practise
yash-rajpal Jun 12, 2024
da517d5
update CS to minor
yash-rajpal Jun 12, 2024
0b5f8f6
Merge branch 'develop' into e2e-room-setup-header
kodiakhq[bot] Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/gold-flowers-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/i18n': patch
'@rocket.chat/meteor': patch
yash-rajpal marked this conversation as resolved.
Show resolved Hide resolved
---

Added E2EE room setup header, with just limited functionality and room actions.
2 changes: 2 additions & 0 deletions apps/meteor/client/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,5 @@ export const quickActionHooks = [
useCloseChatQuickAction,
useOnHoldChatQuickAction,
] satisfies (() => QuickActionsActionConfig | undefined)[];

export const roomActionHooksForE2EESetup = [useChannelSettingsRoomAction, useMembersListRoomAction, useE2EERoomAction];
22 changes: 15 additions & 7 deletions apps/meteor/client/views/room/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import type { IRoom } from '@rocket.chat/core-typings';
import { isVoipRoom } from '@rocket.chat/core-typings';
import { HeaderToolbar } from '@rocket.chat/ui-client';
import { useLayout } from '@rocket.chat/ui-contexts';
import { useLayout, useSetting } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React, { lazy, memo, useMemo } from 'react';

import SidebarToggler from '../../../components/SidebarToggler';

const DirectRoomHeader = lazy(() => import('./DirectRoomHeader'));
const OmnichannelRoomHeader = lazy(() => import('./Omnichannel/OmnichannelRoomHeader'));
const VoipRoomHeader = lazy(() => import('./Omnichannel/VoipRoomHeader'));
const RoomHeaderE2EESetup = lazy(() => import('./RoomHeaderE2EESetup'));
const DirectRoomHeader = lazy(() => import('./DirectRoomHeader'));
const RoomHeader = lazy(() => import('./RoomHeader'));

type HeaderProps<T> = {
Expand All @@ -18,6 +19,9 @@ type HeaderProps<T> = {

const Header = ({ room }: HeaderProps<IRoom>): ReactElement | null => {
const { isMobile, isEmbedded, showTopNavbarEmbeddedLayout } = useLayout();
const encrypted = Boolean(room.encrypted);
const unencryptedMessagesAllowed = useSetting('E2E_Allow_Unencrypted_Messages');
yash-rajpal marked this conversation as resolved.
Show resolved Hide resolved
const shouldDisplayE2EESetup = encrypted && !unencryptedMessagesAllowed;

const slots = useMemo(
() => ({
Expand All @@ -34,10 +38,6 @@ const Header = ({ room }: HeaderProps<IRoom>): ReactElement | null => {
return null;
}

if (room.t === 'd' && (room.uids?.length ?? 0) < 3) {
return <DirectRoomHeader slots={slots} room={room} />;
}

if (room.t === 'l') {
return <OmnichannelRoomHeader slots={slots} />;
}
Expand All @@ -46,7 +46,15 @@ const Header = ({ room }: HeaderProps<IRoom>): ReactElement | null => {
return <VoipRoomHeader slots={slots} room={room} />;
}

return <RoomHeader slots={slots} room={room} topic={room.topic} />;
if (shouldDisplayE2EESetup) {
return <RoomHeaderE2EESetup room={room} topic={room.topic} slots={slots} />;
}

if (room.t === 'd' && (room.uids?.length ?? 0) < 3) {
yash-rajpal marked this conversation as resolved.
Show resolved Hide resolved
return <DirectRoomHeader slots={slots} room={room} />;
}

return <RoomHeader room={room} topic={room.topic} slots={slots} />;
};

export default memo(Header);
5 changes: 3 additions & 2 deletions apps/meteor/client/views/room/Header/RoomHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ export type RoomHeaderProps = {
pos?: unknown;
};
};
roomToolbox?: JSX.Element;
};

const RoomHeader = ({ room, topic = '', slots = {} }: RoomHeaderProps) => {
const RoomHeader = ({ room, topic = '', slots = {}, roomToolbox }: RoomHeaderProps) => {
const t = useTranslation();

return (
Expand Down Expand Up @@ -65,7 +66,7 @@ const RoomHeader = ({ room, topic = '', slots = {} }: RoomHeaderProps) => {
<Suspense fallback={null}>
<HeaderToolbar aria-label={t('Toolbox_room_actions')}>
{slots?.toolbox?.pre}
{slots?.toolbox?.content || <RoomToolbox />}
{slots?.toolbox?.content || roomToolbox || <RoomToolbox />}
{slots?.toolbox?.pos}
</HeaderToolbar>
</Suspense>
Expand Down
28 changes: 28 additions & 0 deletions apps/meteor/client/views/room/Header/RoomHeaderE2EESetup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { lazy } from 'react';

import { E2EEState } from '../../../../app/e2e/client/E2EEState';
import { E2ERoomState } from '../../../../app/e2e/client/E2ERoomState';
import { useE2EERoomState } from '../hooks/useE2EERoomState';
import { useE2EEState } from '../hooks/useE2EEState';
import DirectRoomHeader from './DirectRoomHeader';
import RoomHeader from './RoomHeader';
import type { RoomHeaderProps } from './RoomHeader';

const RoomToolboxE2EESetup = lazy(() => import('./RoomToolbox/RoomToolboxE2EESetup'));

const RoomHeaderE2EESetup = ({ room, topic = '', slots = {} }: RoomHeaderProps) => {
const e2eeState = useE2EEState();
const e2eRoomState = useE2EERoomState(room._id);

if (e2eeState === E2EEState.SAVE_PASSWORD || e2eeState === E2EEState.ENTER_PASSWORD || e2eRoomState === E2ERoomState.WAITING_KEYS) {
return <RoomHeader room={room} topic={topic} slots={slots} roomToolbox={<RoomToolboxE2EESetup />} />;
}

if (room.t === 'd' && (room.uids?.length ?? 0) < 3) {
yash-rajpal marked this conversation as resolved.
Show resolved Hide resolved
return <DirectRoomHeader slots={slots} room={room} />;
}

return <RoomHeader room={room} topic={topic} slots={slots} />;
};

export default RoomHeaderE2EESetup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useStableArray } from '@rocket.chat/fuselage-hooks';
import { HeaderToolbarAction } from '@rocket.chat/ui-client';
import { useTranslation } from '@rocket.chat/ui-contexts';
import React from 'react';

import { roomActionHooksForE2EESetup } from '../../../../ui';
import type { RoomToolboxActionConfig } from '../../contexts/RoomToolboxContext';
import { useRoomToolbox } from '../../contexts/RoomToolboxContext';

const RoomToolboxE2EESetup = () => {
const t = useTranslation();
const toolbox = useRoomToolbox();

const { tab } = toolbox;

const actions = useStableArray(
roomActionHooksForE2EESetup
.map((roomActionHook) => roomActionHook())
.filter((roomAction): roomAction is RoomToolboxActionConfig => !!roomAction),
);

return (
<>
{actions.map(({ id, icon, title, action, disabled, tooltip }, index) => (
<HeaderToolbarAction
key={id}
index={index}
id={id}
icon={icon}
title={t(title)}
pressed={id === tab?.id}
action={action ?? (() => toolbox.openTab(id))}
disabled={disabled}
tooltip={tooltip}
/>
))}
</>
);
};

export default RoomToolboxE2EESetup;
23 changes: 20 additions & 3 deletions apps/meteor/tests/e2e/e2e-encryption.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,17 @@ test.describe.serial('e2ee room setup', () => {

await poHomeChannel.dismissToast();

await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible();
await poHomeChannel.content.encryptedRoomHeaderIcon.first().waitFor();
await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible();

await page.locator('role=button[name="Save E2EE password"]').waitFor();
await expect(page.locator('role=button[name="Save E2EE password"]')).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 page.locator('role=button[name="Save E2EE password"]').click();
Expand Down Expand Up @@ -372,11 +378,17 @@ test.describe.serial('e2ee room setup', () => {

await poHomeChannel.dismissToast();

await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible();
await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible();

await page.locator('role=button[name="Enter your E2E password"]').waitFor();

await expect(page.locator('role=banner >> text="Enter your E2E password"')).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 page.locator('role=button[name="Enter your E2E password"]').click();
Expand Down Expand Up @@ -413,7 +425,7 @@ test.describe.serial('e2ee room setup', () => {

await poHomeChannel.dismissToast();

await expect(poHomeChannel.content.encryptedRoomHeaderIcon).toBeVisible();
await expect(poHomeChannel.content.encryptedRoomHeaderIcon.first()).toBeVisible();

await poHomeChannel.content.sendMessage('hello world');

Expand Down Expand Up @@ -446,5 +458,10 @@ test.describe.serial('e2ee room setup', () => {

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();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export class HomeFlextab {
return this.page.locator('role=menuitem[name="Notifications Preferences"]');
}

get btnE2EERoomSetupDisableE2E(): Locator {
return this.page.locator('[data-qa-id=ToolBoxAction-key]');
}

get btnDisableE2E(): Locator {
return this.page.locator('role=menuitem[name="Disable E2E"]');
}
Expand Down
Loading