From b2265433a84d42ee94a3a75cb1c5cdf07d72c39b Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Wed, 19 Jun 2024 14:24:10 -0300 Subject: [PATCH 1/2] feat: Disallow users from sending unencrypted messages in E2EE rooms (#5600) --- app/actions/actionsTypes.ts | 9 +- app/actions/encryption.ts | 6 ++ app/containers/ActivityIndicator.tsx | 6 +- app/containers/AudioPlayer/PlayButton.tsx | 8 +- app/containers/List/ListItem.tsx | 7 +- app/containers/RoomHeader/RoomHeader.tsx | 13 ++- app/containers/RoomHeader/index.tsx | 5 +- .../SupportedVersionsWarning.tsx | 2 +- app/containers/UIKit/MultiSelect/Items.tsx | 4 +- .../Components/RightIcons/Translated.tsx | 1 - app/containers/message/Content.tsx | 5 +- app/containers/message/Thread.tsx | 5 +- .../OmnichannelHeader/OmnichannelQueue.tsx | 5 +- app/i18n/locales/ar.json | 9 +- app/i18n/locales/bn-IN.json | 9 +- app/i18n/locales/de.json | 9 +- app/i18n/locales/en.json | 17 +++- app/i18n/locales/fi.json | 9 +- app/i18n/locales/fr.json | 9 +- app/i18n/locales/hi-IN.json | 9 +- app/i18n/locales/hu.json | 9 +- app/i18n/locales/it.json | 9 +- app/i18n/locales/ja.json | 9 +- app/i18n/locales/nl.json | 9 +- app/i18n/locales/pt-BR.json | 15 ++- app/i18n/locales/pt-PT.json | 9 +- app/i18n/locales/ru.json | 9 +- app/i18n/locales/sl-SI.json | 9 +- app/i18n/locales/sv.json | 9 +- app/i18n/locales/ta-IN.json | 9 +- app/i18n/locales/te-IN.json | 9 +- app/i18n/locales/tr.json | 9 +- app/i18n/locales/zh-CN.json | 9 +- app/i18n/locales/zh-TW.json | 9 +- app/lib/encryption/constants.ts | 1 + app/lib/encryption/encryption.ts | 5 +- app/lib/encryption/helpers/toggleRoomE2EE.ts | 70 +++++++++++++ app/lib/encryption/index.ts | 2 + app/lib/encryption/room.ts | 12 ++- app/lib/encryption/utils.ts | 39 ++++++++ app/lib/methods/search.ts | 16 ++- app/reducers/encryption.test.ts | 25 ++++- app/reducers/encryption.ts | 15 ++- app/sagas/createChannel.js | 5 + app/sagas/encryption.js | 9 +- app/views/AutoTranslateView/index.tsx | 6 +- app/views/ChangePasscodeView.tsx | 1 - .../RoomSettings/SwitchItem.tsx | 7 +- app/views/E2EEnterYourPasswordView.tsx | 41 +++++++- app/views/JitsiMeetView/JitsiAuthModal.tsx | 4 +- app/views/RegisterView.tsx | 4 +- .../components/CallSection.tsx | 4 +- app/views/RoomActionsView/index.tsx | 91 +++++++---------- .../components/RoomInfoButtons.tsx | 4 +- app/views/RoomInfoView/hooks.ts | 15 +++ app/views/RoomMembersView/index.tsx | 4 +- app/views/RoomView/RightButtons.tsx | 71 ++++++++++++-- .../RoomView/components/EncryptedRoom.tsx | 98 +++++++++++++++++++ .../RoomView/components/HeaderCallButton.tsx | 6 +- .../components/MissingRoomE2EEKey.tsx | 77 +++++++++++++++ app/views/RoomView/components/index.ts | 3 + app/views/RoomView/constants.ts | 4 +- app/views/RoomView/definitions.ts | 1 + app/views/RoomView/index.tsx | 30 +++++- app/views/RoomsListView/ListHeader/index.tsx | 4 +- app/views/SecurityPrivacyView.tsx | 8 +- app/views/ShareListView/index.tsx | 75 +++++++++----- e2e/tests/assorted/01-e2eencryption.spec.ts | 20 ++-- 68 files changed, 819 insertions(+), 237 deletions(-) create mode 100644 app/lib/encryption/constants.ts create mode 100644 app/lib/encryption/helpers/toggleRoomE2EE.ts create mode 100644 app/views/RoomInfoView/hooks.ts create mode 100644 app/views/RoomView/components/EncryptedRoom.tsx create mode 100644 app/views/RoomView/components/MissingRoomE2EEKey.tsx create mode 100644 app/views/RoomView/components/index.ts diff --git a/app/actions/actionsTypes.ts b/app/actions/actionsTypes.ts index ae8485ba03..d5399d4577 100644 --- a/app/actions/actionsTypes.ts +++ b/app/actions/actionsTypes.ts @@ -81,7 +81,14 @@ export const INVITE_LINKS = createRequestTypes('INVITE_LINKS', [ export const SETTINGS = createRequestTypes('SETTINGS', ['CLEAR', 'ADD', 'UPDATE']); export const APP_STATE = createRequestTypes('APP_STATE', ['FOREGROUND', 'BACKGROUND']); export const ENTERPRISE_MODULES = createRequestTypes('ENTERPRISE_MODULES', ['CLEAR', 'SET']); -export const ENCRYPTION = createRequestTypes('ENCRYPTION', ['INIT', 'STOP', 'DECODE_KEY', 'SET', 'SET_BANNER']); +export const ENCRYPTION = createRequestTypes('ENCRYPTION', [ + 'INIT', + 'STOP', + 'DECODE_KEY', + 'DECODE_KEY_FAILURE', + 'SET', + 'SET_BANNER' +]); export const PERMISSIONS = createRequestTypes('PERMISSIONS', ['SET', 'UPDATE']); export const ROLES = createRequestTypes('ROLES', ['SET', 'UPDATE', 'REMOVE']); diff --git a/app/actions/encryption.ts b/app/actions/encryption.ts index be3fb43fa1..4b06291e64 100644 --- a/app/actions/encryption.ts +++ b/app/actions/encryption.ts @@ -50,3 +50,9 @@ export function encryptionDecodeKey(password: string): IEncryptionDecodeKey { password }; } + +export function encryptionDecodeKeyFailure(): Action { + return { + type: ENCRYPTION.DECODE_KEY_FAILURE + }; +} diff --git a/app/containers/ActivityIndicator.tsx b/app/containers/ActivityIndicator.tsx index 7469b7f29d..90da8eccf7 100644 --- a/app/containers/ActivityIndicator.tsx +++ b/app/containers/ActivityIndicator.tsx @@ -27,7 +27,11 @@ const styles = StyleSheet.create({ const RCActivityIndicator = ({ absolute, ...props }: IActivityIndicator): React.ReactElement => { const { theme } = useTheme(); return ( - + ); }; diff --git a/app/containers/AudioPlayer/PlayButton.tsx b/app/containers/AudioPlayer/PlayButton.tsx index 6951d249fd..138dc856a7 100644 --- a/app/containers/AudioPlayer/PlayButton.tsx +++ b/app/containers/AudioPlayer/PlayButton.tsx @@ -31,7 +31,13 @@ const Icon = ({ audioState, disabled }: { audioState: TAudioState; disabled: boo customIconName = 'play-shape-filled'; } - return ; + return ( + + ); }; const PlayButton = ({ onPress, disabled = false, audioState }: IButton): React.ReactElement => { diff --git a/app/containers/List/ListItem.tsx b/app/containers/List/ListItem.tsx index 80026daf2a..79538736ff 100644 --- a/app/containers/List/ListItem.tsx +++ b/app/containers/List/ListItem.tsx @@ -100,7 +100,12 @@ const Content = React.memo( {translateTitle && title ? I18n.t(title) : title} {alert ? ( - + ) : null} {subtitle ? ( diff --git a/app/containers/RoomHeader/RoomHeader.tsx b/app/containers/RoomHeader/RoomHeader.tsx index 19bbeb3160..bdcdddafeb 100644 --- a/app/containers/RoomHeader/RoomHeader.tsx +++ b/app/containers/RoomHeader/RoomHeader.tsx @@ -74,6 +74,7 @@ interface IRoomHeader { onPress: Function; testID?: string; sourceType?: IOmnichannelSource; + disabled?: boolean; } const SubTitle = React.memo(({ usersTyping, subtitle, renderFunc, scale }: TRoomHeaderSubTitle) => { @@ -139,7 +140,8 @@ const Header = React.memo( teamMain, testID, usersTyping = [], - sourceType + sourceType, + disabled }: IRoomHeader) => { const { colors } = useTheme(); const portrait = height > width; @@ -177,8 +179,13 @@ const Header = React.memo( testID='room-header' accessibilityLabel={title} onPress={handleOnPress} - style={styles.container} - disabled={!!tmid} + style={[ + styles.container, + { + opacity: disabled ? 0.5 : 1 + } + ]} + disabled={disabled} hitSlop={HIT_SLOP}> {tmid ? null : ( diff --git a/app/containers/RoomHeader/index.tsx b/app/containers/RoomHeader/index.tsx index 91814380f7..79d261dd9c 100644 --- a/app/containers/RoomHeader/index.tsx +++ b/app/containers/RoomHeader/index.tsx @@ -20,6 +20,7 @@ interface IRoomHeaderContainerProps { testID?: string; sourceType?: IOmnichannelSource; visitor?: IVisitor; + disabled?: boolean; } const RoomHeaderContainer = React.memo( @@ -36,7 +37,8 @@ const RoomHeaderContainer = React.memo( tmid, type, sourceType, - visitor + visitor, + disabled }: IRoomHeaderContainerProps) => { let subtitle: string | undefined; let statusVisitor: TUserStatus | undefined; @@ -86,6 +88,7 @@ const RoomHeaderContainer = React.memo( testID={testID} onPress={onPress} sourceType={sourceType} + disabled={disabled} /> ); } diff --git a/app/containers/SupportedVersions/SupportedVersionsWarning.tsx b/app/containers/SupportedVersions/SupportedVersionsWarning.tsx index 9d67587269..b71b812343 100644 --- a/app/containers/SupportedVersions/SupportedVersionsWarning.tsx +++ b/app/containers/SupportedVersions/SupportedVersionsWarning.tsx @@ -52,7 +52,7 @@ export const SupportedVersionsWarning = ({ navigation, route }: { navigation?: a ) : null}