Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/cold-colts-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/i18n': minor
'@rocket.chat/meteor': minor
---

Replaces some texts in order to improve the E2E encryption communication on the UI
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export const useE2EERoomAction = () => {
return {
id: 'e2e',
groups: ['direct', 'direct_multiple', 'group', 'team'],
title: enabledOnRoom ? 'E2E_disable' : 'E2E_enable',
title: enabledOnRoom ? 'Disable_E2E_encryption' : 'Enable_E2E_encryption',
icon: 'key',
order: 13,
action,
Expand Down
10 changes: 5 additions & 5 deletions apps/meteor/client/lib/e2ee/rocketchat.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ class E2E extends Emitter {
onConfirm: () => {
Accounts.storageLocation.removeItem('e2e.randomPassword');
this.setState(E2EEState.READY);
dispatchToastMessage({ type: 'success', message: t('End_To_End_Encryption_Enabled') });
dispatchToastMessage({ type: 'success', message: t('E2E_encryption_enabled') });
this.closeAlert();
imperativeModal.close();
},
Expand Down Expand Up @@ -413,8 +413,8 @@ class E2E extends Emitter {
if (randomPassword) {
this.setState(E2EEState.SAVE_PASSWORD);
this.openAlert({
title: () => t('Save_your_encryption_password'),
html: () => t('Click_here_to_view_and_copy_your_password'),
title: () => t('Save_your_new_E2EE_password'),
html: () => t('Click_here_to_view_and_save_your_new_E2EE_password'),
modifiers: ['large'],
closable: false,
icon: 'key',
Expand Down Expand Up @@ -587,7 +587,7 @@ class E2E extends Emitter {
const showAlert = () => {
this.openAlert({
title: () => t('Enter_your_E2E_password'),
html: () => t('Click_here_to_enter_your_encryption_password'),
html: () => t('Click_here_to_enter_your_password'),
modifiers: ['large'],
closable: false,
icon: 'key',
Expand Down Expand Up @@ -633,7 +633,7 @@ class E2E extends Emitter {
await this.createAndLoadKeys();
this.setState(E2EEState.READY);
}
dispatchToastMessage({ type: 'success', message: t('End_To_End_Encryption_Enabled') });
dispatchToastMessage({ type: 'success', message: t('E2E_encryption_enabled') });
} catch (error) {
this.setState(E2EEState.ENTER_PASSWORD);
dispatchToastMessage({ type: 'error', message: t('Your_E2EE_password_is_incorrect') });
Expand Down
60 changes: 38 additions & 22 deletions apps/meteor/client/views/account/security/EndToEnd.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Box, PasswordInput, Field, FieldGroup, FieldLabel, FieldRow, FieldError, FieldHint, Button, Divider } from '@rocket.chat/fuselage';
import { useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts';
import { useToastMessageDispatch } from '@rocket.chat/ui-contexts';
import DOMPurify from 'dompurify';
import { Accounts } from 'meteor/accounts-base';
import type { ComponentProps, ReactElement } from 'react';
import { useId, useEffect } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';

import { e2e } from '../../../lib/e2ee/rocketchat.e2e';
import { useResetE2EPasswordMutation } from '../../hooks/useResetE2EPasswordMutation';

const EndToEnd = (props: ComponentProps<typeof Box>): ReactElement => {
const t = useTranslation();
const { t } = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();

const publicKey = Accounts.storageLocation.getItem('public_key');
Expand All @@ -29,11 +30,14 @@ const EndToEnd = (props: ComponentProps<typeof Box>): ReactElement => {
password: '',
passwordConfirm: '',
},
mode: 'all',
});

const { password } = watch();

/**
* TODO: We need to figure out a way to make this reactive,
* so the form will allow change password as soon the user enter the current E2EE password
*/
const keysExist = Boolean(publicKey && privateKey);

const hasTypedPassword = Boolean(password?.trim().length);
Expand Down Expand Up @@ -66,65 +70,77 @@ const EndToEnd = (props: ComponentProps<typeof Box>): ReactElement => {
id={e2ePasswordExplanationId}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('E2E_Encryption_Password_Explanation')) }}
/>

<Box mbs={36} w='full'>
<Box is='h4' fontScale='h4' mbe={12}>
{t('E2E_Encryption_Password_Change')}
{t('Change_E2EE_password')}
</Box>

<FieldGroup w='full'>
<Field>
<FieldLabel htmlFor={passwordId}>{t('New_encryption_password')}</FieldLabel>
<FieldLabel htmlFor={passwordId}>{t('New_E2EE_password')}</FieldLabel>
<FieldRow>
<Controller
control={control}
name='password'
rules={{ required: t('Required_field', { field: t('New_encryption_password') }) }}
rules={{ required: t('Required_field', { field: t('New_E2EE_password') }) }}
render={({ field }) => (
<PasswordInput
{...field}
id={passwordId}
error={errors.password?.message}
placeholder={t('New_Password_Placeholder')}
disabled={!keysExist}
aria-describedby={`${e2ePasswordExplanationId} ${passwordId}-hint ${passwordId}-error`}
aria-invalid={errors.password ? 'true' : 'false'}
/>
)}
/>
</FieldRow>
{!keysExist && <FieldHint id={`${passwordId}-hint`}>{t('EncryptionKey_Change_Disabled')}</FieldHint>}
{!keysExist && (
<FieldHint id={`${passwordId}-hint`}>
<Trans i18nKey='Enter_current_E2EE_password_to_set_new'>
To set a new password, first
<Box
is='a'
href='#'
onClick={async (e) => {
e.preventDefault();
await e2e.decodePrivateKeyFlow();
}}
>
enter your current E2EE password.
</Box>
</Trans>
</FieldHint>
)}
{errors?.password && (
<FieldError aria-live='assertive' id={`${passwordId}-error`}>
<FieldError role='alert' id={`${passwordId}-error`}>
{errors.password.message}
</FieldError>
)}
</Field>
{hasTypedPassword && (
<Field>
<FieldLabel htmlFor={passwordConfirmId}>{t('Confirm_new_encryption_password')}</FieldLabel>
<FieldLabel htmlFor={passwordConfirmId}>{t('Confirm_new_E2EE_password')}</FieldLabel>
<FieldRow>
<Controller
control={control}
name='passwordConfirm'
rules={{
required: t('Required_field', { field: t('Confirm_new_encryption_password') }),
validate: (value: string) => (password !== value ? 'Your passwords do no match' : true),
required: t('Required_field', { field: t('Confirm_new_E2EE_password') }),
validate: (value: string) => (password !== value ? t('Passwords_do_not_match') : true),
}}
render={({ field }) => (
<PasswordInput
{...field}
id={passwordConfirmId}
error={errors.passwordConfirm?.message}
placeholder={t('Confirm_New_Password_Placeholder')}
aria-describedby={`${passwordConfirmId}-error`}
aria-invalid={errors.password ? 'true' : 'false'}
aria-invalid={errors.passwordConfirm ? 'true' : 'false'}
/>
)}
/>
</FieldRow>
{errors.passwordConfirm && (
<FieldError aria-live='assertive' id={`${passwordConfirmId}-error`}>
<FieldError role='alert' id={`${passwordConfirmId}-error`}>
{errors.passwordConfirm.message}
</FieldError>
)}
Expand All @@ -141,16 +157,16 @@ const EndToEnd = (props: ComponentProps<typeof Box>): ReactElement => {
{t('Save_changes')}
</Button>
</Box>

<Divider mb={36} width='full' />

<Box>
<Box is='h4' fontScale='h4' mbe={12}>
{t('Reset_E2E_Key')}
{t('Reset_E2EE_password')}
</Box>
<Box is='p' fontScale='p1' mbe={12}>
{t('Reset_E2EE_password_description')}
</Box>
<Box is='p' fontScale='p1' mbe={12} dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(t('E2E_Reset_Key_Explanation')) }} />
<Button onClick={() => resetE2EPassword.mutate()} data-qa-type='e2e-encryption-reset-key-button'>
{t('Reset_E2E_Key')}
{t('Reset_E2EE_password')}
</Button>
</Box>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const useResetE2EEKeyAction = (userId: IUser['_id']): AdminUserAction | u
return canResetE2EEKey
? {
icon: 'key',
content: t('Reset_E2E_Key'),
content: t('Reset_E2EE_password'),
onClick: confirmResetE2EEKey,
}
: undefined;
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/views/e2e/SaveE2EPasswordModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const SaveE2EPasswordModal = ({ randomPassword, onClose, onCancel, onConfirm }:
cancelText={t('Do_It_Later')}
confirmText={t('I_Saved_My_Password')}
variant='warning'
title={t('Save_your_encryption_password')}
title={t('Save_your_new_E2EE_password')}
annotation={t('You_can_do_from_account_preferences')}
>
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const useResetE2EPasswordMutation = ({ options }: { options?: MutationOpt
return useMutation({
mutationFn: async () => resetE2eKey(),
onSuccess: () => {
dispatchToastMessage({ type: 'success', message: t('User_e2e_key_was_reset') });
dispatchToastMessage({ type: 'success', message: t('E2EE_password_reset') });
logout();
},
onError: (error) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const DisableE2EEModal = ({ onConfirm, onCancel, roomType, canResetRoomKey, onRe
onConfirm={onConfirm}
onCancel={onCancel}
onDismiss={() => undefined}
annotation={t('Proceed_with_caution')}
>
<Box mbe={16} is='p'>
<Trans i18nKey='E2E_disable_encryption_description' tOptions={{ roomType }} />
Expand Down
10 changes: 1 addition & 9 deletions apps/meteor/tests/e2e/page-objects/account-profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,7 @@ export class AccountProfile {
}

get securityE2EEncryptionResetKeyButton(): Locator {
return this.page.locator("role=button[name='Reset E2EE key']");
}

get securityE2EEncryptionPassword(): Locator {
return this.page.locator('role=textbox[name="New encryption password"]');
}

get securityE2EEncryptionPasswordConfirmation(): Locator {
return this.page.locator('role=textbox[name="Confirm new encryption password"]');
return this.page.locator("role=button[name='Reset E2EE password']");
}

get securityE2EEncryptionSavePasswordButton(): Locator {
Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/tests/e2e/page-objects/account-security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ export class AccountSecurityPage {
}

private get resetE2EEPasswordButton() {
return this.page.getByRole('button', { name: 'Reset E2EE key' });
return this.page.getByRole('button', { name: 'Reset E2EE password' });
}

private get newE2EEPasswordInput() {
return this.page.getByRole('textbox', { name: 'New encryption password' });
return this.page.getByRole('textbox', { name: 'New E2EE password' });
}

private get confirmNewE2EEPasswordInput() {
return this.page.getByRole('textbox', { name: 'Confirm new encryption password' });
return this.page.getByRole('textbox', { name: 'Confirm new E2EE password' });
}

private get saveChangesButton() {
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/tests/e2e/page-objects/fragments/e2ee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ abstract class E2EEBanner {

export class SaveE2EEPasswordBanner extends E2EEBanner {
constructor(page: Page) {
super(page.getByRole('button', { name: 'Save your encryption password' }));
super(page.getByRole('button', { name: 'Save your new E2EE password' }));
}
}

Expand All @@ -43,7 +43,7 @@ export class SaveE2EEPasswordModal extends Modal {
private readonly toastMessages: ToastMessages;

constructor(page: Page) {
super(page.getByRole('dialog', { name: 'Save your encryption password' }));
super(page.getByRole('dialog', { name: 'Save your new E2EE password' }));
this.toastMessages = new ToastMessages(page);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ export class HomeFlextab {
}

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

get btnEnableE2E(): Locator {
return this.page.locator('role=menuitem[name="Enable E2E"]');
return this.page.locator('role=menuitem[name="Enable E2E encryption"]');
}

get btnEnableOTR(): Locator {
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/tests/e2e/page-objects/home-channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class HomeChannel {
}

get dialogSaveE2EEPassword(): Locator {
return this.page.getByRole('dialog', { name: 'Save your encryption password' });
return this.page.getByRole('dialog', { name: 'Save your new E2EE password' });
}

get btnRoomSaveE2EEPassword(): Locator {
Expand All @@ -102,7 +102,7 @@ export class HomeChannel {
}

get bannerSaveEncryptionPassword(): Locator {
return this.page.getByRole('button', { name: 'Save your encryption password' });
return this.page.getByRole('button', { name: 'Save your new E2EE password' });
}

get bannerEnterE2EEPassword(): Locator {
Expand Down
2 changes: 0 additions & 2 deletions packages/i18n/src/locales/af.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,6 @@
"Community": "Gemeenskap",
"Computer": "rekenaar",
"Condensed": "verkorte",
"Confirm_New_Password_Placeholder": "Voer asseblief nuwe wagwoord weer in ...",
"Confirm_new_password": "Bevestig nuwe wagwoord",
"Confirm_password": "Bevestig jou wagwoord",
"Confirm_your_password": "Bevestig jou wagwoord",
Expand Down Expand Up @@ -1527,7 +1526,6 @@
"New_Custom_Field": "Nuwe aangepaste veld",
"New_Department": "Nuwe Departement",
"New_Message_Notification": "Nuwe boodskap kennisgewing",
"New_Password_Placeholder": "Voer asseblief nuwe wagwoord in ...",
"New_Room_Notification": "Nuwe kamer kennisgewing",
"New_Trigger": "Nuwe Trigger",
"New_integration": "Nuwe integrasie",
Expand Down
Loading
Loading