diff --git a/app/stacks/InsideStack.tsx b/app/stacks/InsideStack.tsx
index 67923c076..54162d730 100644
--- a/app/stacks/InsideStack.tsx
+++ b/app/stacks/InsideStack.tsx
@@ -178,12 +178,7 @@ const SettingsStackNavigator = () => {
>
-
+
diff --git a/app/stacks/MasterDetailStack/index.tsx b/app/stacks/MasterDetailStack/index.tsx
index d26d00b82..5c9235120 100644
--- a/app/stacks/MasterDetailStack/index.tsx
+++ b/app/stacks/MasterDetailStack/index.tsx
@@ -193,12 +193,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
-
+
);
diff --git a/app/views/E2EEncryptionSecurityView.tsx b/app/views/E2EEncryptionSecurityView.tsx
deleted file mode 100644
index 6383a2e07..000000000
--- a/app/views/E2EEncryptionSecurityView.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-import React from 'react';
-import { StyleSheet, Text, View, TextInput as RNTextInput } from 'react-native';
-import { StackNavigationOptions } from '@react-navigation/stack';
-import { connect } from 'react-redux';
-
-import StatusBar from '../containers/StatusBar';
-import * as List from '../containers/List';
-import I18n from '../i18n';
-import log, { events, logEvent } from '../lib/methods/helpers/log';
-import { withTheme } from '../theme';
-import SafeAreaView from '../containers/SafeAreaView';
-import { FormTextInput } from '../containers/TextInput';
-import Button from '../containers/Button';
-import { getUserSelector } from '../selectors/login';
-import { PADDING_HORIZONTAL } from '../containers/List/constants';
-import { themes } from '../lib/constants';
-import { Encryption } from '../lib/encryption';
-import { logout } from '../actions/login';
-import { showConfirmationAlert, showErrorAlert } from '../lib/methods/helpers/info';
-import EventEmitter from '../lib/methods/helpers/events';
-import { LISTENER } from '../containers/Toast';
-import { debounce } from '../lib/methods/helpers';
-import sharedStyles from './Styles';
-import { IApplicationState, IBaseScreen, IUser } from '../definitions';
-import { Services } from '../lib/services';
-import { SettingsStackParamList } from '../stacks/types';
-
-const styles = StyleSheet.create({
- container: {
- paddingHorizontal: PADDING_HORIZONTAL
- },
- title: {
- fontSize: 16,
- ...sharedStyles.textMedium
- },
- description: {
- fontSize: 14,
- paddingVertical: 10,
- ...sharedStyles.textRegular
- },
- changePasswordButton: {
- marginBottom: 4
- },
- separator: {
- marginBottom: 16
- }
-});
-
-interface IE2EEncryptionSecurityViewState {
- newPassword: string;
-}
-
-interface IE2EEncryptionSecurityViewProps extends IBaseScreen {
- user: IUser;
- server: string;
- encryptionEnabled: boolean;
-}
-
-class E2EEncryptionSecurityView extends React.Component {
- private newPasswordInputRef: any = React.createRef();
-
- static navigationOptions = (): StackNavigationOptions => ({
- title: I18n.t('E2E_Encryption')
- });
-
- state = { newPassword: '' };
-
- onChangePasswordText = debounce((text: string) => this.setState({ newPassword: text }), 300);
-
- setNewPasswordRef = (ref: RNTextInput) => (this.newPasswordInputRef = ref);
-
- changePassword = () => {
- const { newPassword } = this.state;
- if (!newPassword.trim()) {
- return;
- }
- showConfirmationAlert({
- title: I18n.t('Are_you_sure_question_mark'),
- message: I18n.t('E2E_encryption_change_password_message'),
- confirmationText: I18n.t('E2E_encryption_change_password_confirmation'),
- onPress: async () => {
- logEvent(events.E2E_SEC_CHANGE_PASSWORD);
- try {
- const { server } = this.props;
- await Encryption.changePassword(server, newPassword);
- EventEmitter.emit(LISTENER, { message: I18n.t('E2E_encryption_change_password_success') });
- this.newPasswordInputRef?.clear();
- this.newPasswordInputRef?.blur();
- } catch (e) {
- log(e);
- showErrorAlert(I18n.t('E2E_encryption_change_password_error'));
- }
- }
- });
- };
-
- resetOwnKey = () => {
- showConfirmationAlert({
- title: I18n.t('Are_you_sure_question_mark'),
- message: I18n.t('E2E_encryption_reset_message'),
- confirmationText: I18n.t('E2E_encryption_reset_confirmation'),
- onPress: async () => {
- logEvent(events.E2E_SEC_RESET_OWN_KEY);
- try {
- const res = await Services.e2eResetOwnKey();
- /**
- * It might return an empty object when TOTP is enabled,
- * that's why we're using strict equality to boolean
- */
- if (res === true) {
- const { dispatch } = this.props;
- dispatch(logout());
- }
- } catch (e) {
- log(e);
- showErrorAlert(I18n.t('E2E_encryption_reset_error'));
- }
- }
- });
- };
-
- renderChangePassword = () => {
- const { newPassword } = this.state;
- const { theme, encryptionEnabled } = this.props;
- if (!encryptionEnabled) {
- return null;
- }
- return (
- <>
-
-
- {I18n.t('E2E_encryption_change_password_title')}
-
-
- {I18n.t('E2E_encryption_change_password_description')}
-
-
-
-
-
- >
- );
- };
-
- render() {
- const { theme } = this.props;
- return (
-
-
-
-
- {this.renderChangePassword()}
-
-
-
- {I18n.t('E2E_encryption_reset_title')}
-
-
- {I18n.t('E2E_encryption_reset_description')}
-
-
-
-
-
-
- );
- }
-}
-
-const mapStateToProps = (state: IApplicationState) => ({
- server: state.server.server,
- user: getUserSelector(state),
- encryptionEnabled: state.encryption.enabled
-});
-
-export default connect(mapStateToProps)(withTheme(E2EEncryptionSecurityView));
diff --git a/app/views/E2EEncryptionSecurityView/ChangePassword.tsx b/app/views/E2EEncryptionSecurityView/ChangePassword.tsx
new file mode 100644
index 000000000..f55f4d216
--- /dev/null
+++ b/app/views/E2EEncryptionSecurityView/ChangePassword.tsx
@@ -0,0 +1,103 @@
+import React, { useRef, useState } from 'react';
+import { StyleSheet, Text, TextInput as RNTextInput } from 'react-native';
+
+import { useTheme } from '../../theme';
+import * as List from '../../containers/List';
+import I18n from '../../i18n';
+import log, { events, logEvent } from '../../lib/methods/helpers/log';
+import { FormTextInput } from '../../containers/TextInput';
+import Button from '../../containers/Button';
+import { Encryption } from '../../lib/encryption';
+import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers/info';
+import EventEmitter from '../../lib/methods/helpers/events';
+import { LISTENER } from '../../containers/Toast';
+import { useDebounce } from '../../lib/methods/helpers';
+import sharedStyles from '../Styles';
+import { useAppSelector } from '../../lib/hooks';
+
+const styles = StyleSheet.create({
+ title: {
+ fontSize: 16,
+ ...sharedStyles.textMedium
+ },
+ description: {
+ fontSize: 14,
+ paddingVertical: 12,
+ ...sharedStyles.textRegular
+ },
+ changePasswordButton: {
+ marginBottom: 4
+ },
+ separator: {
+ marginBottom: 16
+ }
+});
+
+const ChangePassword = () => {
+ const [newPassword, setNewPassword] = useState('');
+ const { colors } = useTheme();
+ const { encryptionEnabled, server } = useAppSelector(state => ({
+ encryptionEnabled: state.encryption.enabled,
+ server: state.server.server
+ }));
+ const newPasswordInputRef = useRef(null);
+
+ const onChangePasswordText = useDebounce((text: string) => setNewPassword(text), 300);
+
+ const changePassword = () => {
+ if (!newPassword.trim()) {
+ return;
+ }
+ showConfirmationAlert({
+ title: I18n.t('Are_you_sure_question_mark'),
+ message: I18n.t('E2E_encryption_change_password_message'),
+ confirmationText: I18n.t('E2E_encryption_change_password_confirmation'),
+ onPress: async () => {
+ logEvent(events.E2E_SEC_CHANGE_PASSWORD);
+ try {
+ await Encryption.changePassword(server, newPassword);
+ EventEmitter.emit(LISTENER, { message: I18n.t('E2E_encryption_change_password_success') });
+ newPasswordInputRef?.current?.clear();
+ newPasswordInputRef?.current?.blur();
+ } catch (e) {
+ log(e);
+ showErrorAlert(I18n.t('E2E_encryption_change_password_error'));
+ }
+ }
+ });
+ };
+
+ if (!encryptionEnabled) {
+ return null;
+ }
+
+ return (
+ <>
+
+ {I18n.t('E2E_encryption_change_password_title')}
+
+ {I18n.t('E2E_encryption_change_password_description')}
+
+
+
+
+
+ >
+ );
+};
+
+export default ChangePassword;
diff --git a/app/views/E2EEncryptionSecurityView/index.tsx b/app/views/E2EEncryptionSecurityView/index.tsx
new file mode 100644
index 000000000..eb739144e
--- /dev/null
+++ b/app/views/E2EEncryptionSecurityView/index.tsx
@@ -0,0 +1,96 @@
+import React, { useLayoutEffect } from 'react';
+import { StyleSheet, Text, View } from 'react-native';
+import { StackNavigationProp } from '@react-navigation/stack';
+import { useDispatch } from 'react-redux';
+import { useNavigation } from '@react-navigation/native';
+
+import StatusBar from '../../containers/StatusBar';
+import * as List from '../../containers/List';
+import I18n from '../../i18n';
+import log, { events, logEvent } from '../../lib/methods/helpers/log';
+import { useTheme } from '../../theme';
+import SafeAreaView from '../../containers/SafeAreaView';
+import Button from '../../containers/Button';
+import { PADDING_HORIZONTAL } from '../../containers/List/constants';
+import { logout } from '../../actions/login';
+import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers/info';
+import sharedStyles from '../Styles';
+import { Services } from '../../lib/services';
+import { SettingsStackParamList } from '../../stacks/types';
+import ChangePassword from './ChangePassword';
+
+const styles = StyleSheet.create({
+ container: {
+ paddingHorizontal: PADDING_HORIZONTAL
+ },
+ title: {
+ fontSize: 16,
+ ...sharedStyles.textMedium
+ },
+ description: {
+ fontSize: 14,
+ paddingVertical: 10,
+ ...sharedStyles.textRegular
+ }
+});
+
+const E2EEncryptionSecurityView = () => {
+ const navigation = useNavigation>();
+ const { colors } = useTheme();
+ const dispatch = useDispatch();
+
+ useLayoutEffect(() => {
+ navigation.setOptions({
+ title: I18n.t('E2E_Encryption')
+ });
+ }, [navigation]);
+
+ const resetOwnKey = () => {
+ showConfirmationAlert({
+ title: I18n.t('Are_you_sure_question_mark'),
+ message: I18n.t('E2E_encryption_reset_message'),
+ confirmationText: I18n.t('E2E_encryption_reset_confirmation'),
+ onPress: async () => {
+ logEvent(events.E2E_SEC_RESET_OWN_KEY);
+ try {
+ const res = await Services.e2eResetOwnKey();
+ /**
+ * It might return an empty object when TOTP is enabled,
+ * that's why we're using strict equality to boolean
+ */
+ if (res === true) {
+ dispatch(logout());
+ }
+ } catch (e) {
+ log(e);
+ showErrorAlert(I18n.t('E2E_encryption_reset_error'));
+ }
+ }
+ });
+ };
+
+ return (
+
+
+
+
+
+
+
+ {I18n.t('E2E_encryption_reset_title')}
+ {I18n.t('E2E_encryption_reset_description')}
+
+
+
+
+
+ );
+};
+
+export default E2EEncryptionSecurityView;