BlueWallet/screen/settings/encryptStorage.js

202 lines
7 KiB
JavaScript
Raw Normal View History

/* global alert */
2020-07-15 13:32:59 -04:00
import React, { useEffect, useState, useCallback } from 'react';
import { ScrollView, Alert, Platform, TouchableOpacity, TouchableWithoutFeedback, StyleSheet } from 'react-native';
2020-07-20 16:38:46 +03:00
import { useNavigation, StackActions } from '@react-navigation/native';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import {
2020-07-15 13:32:59 -04:00
BlueLoadingHook,
SafeBlueArea,
BlueSpacing20,
BlueCard,
2020-09-21 21:53:28 -04:00
BlueListItem,
2020-07-15 13:32:59 -04:00
BlueHeaderDefaultSubHooks,
BlueTextHooks,
BlueNavigationStyle,
} from '../../BlueComponents';
2019-08-23 03:04:23 -04:00
import { AppStorage } from '../../class';
import Biometric from '../../class/biometrics';
2020-07-20 16:38:46 +03:00
import loc from '../../loc';
2020-07-15 13:32:59 -04:00
import { colors } from 'react-native-elements';
const BlueApp: AppStorage = require('../../BlueApp');
const prompt = require('../../blue_modules/prompt');
2020-07-15 13:32:59 -04:00
const EncryptStorage = () => {
const [isLoading, setIsLoading] = useState(true);
const [deleteWalletsAfterUninstall, setDeleteWalletsAfterUninstall] = useState(false);
const [biometrics, setBiometrics] = useState({ isDeviceBiometricCapable: false, isBiometricsEnabled: false, biometricsType: '' });
const [storageIsEncrypted, setStorageIsEncrypted] = useState(false);
const { navigate, dispatch } = useNavigation();
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: colors.background,
},
});
2020-07-15 13:32:59 -04:00
const initialState = useCallback(async () => {
const isBiometricsEnabled = await Biometric.isBiometricUseEnabled();
const isDeviceBiometricCapable = await Biometric.isDeviceBiometricCapable();
const biometricsType = (await Biometric.biometricType()) || 'biometrics';
2020-07-15 13:32:59 -04:00
const deleteWalletsAfterUninstall = await BlueApp.isDeleteWalletAfterUninstallEnabled();
const isStorageEncrypted = await BlueApp.storageIsEncrypted();
setBiometrics(biometrics);
setStorageIsEncrypted(isStorageEncrypted);
setDeleteWalletsAfterUninstall(deleteWalletsAfterUninstall);
setBiometrics({ isBiometricsEnabled, isDeviceBiometricCapable, biometricsType });
setIsLoading(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
initialState();
}, [initialState]);
2020-07-15 13:32:59 -04:00
const decryptStorage = useCallback(async () => {
2019-08-23 03:04:23 -04:00
const password = await prompt(loc.settings.password, loc._.storage_is_encrypted).catch(() => {
2020-07-15 13:32:59 -04:00
setIsLoading(false);
2019-08-23 03:04:23 -04:00
});
try {
await BlueApp.decryptStorage(password);
2020-07-15 13:32:59 -04:00
dispatch(StackActions.popToTop());
2019-08-23 03:04:23 -04:00
} catch (e) {
if (password) {
alert(loc._.bad_password);
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
}
2020-07-15 13:32:59 -04:00
setIsLoading(false);
setStorageIsEncrypted(await BlueApp.storageIsEncrypted());
setDeleteWalletsAfterUninstall(await BlueApp.isDeleteWalletAfterUninstallEnabled());
2019-08-23 03:04:23 -04:00
}
2020-07-15 13:32:59 -04:00
}, [dispatch]);
2019-08-23 03:04:23 -04:00
2020-07-15 13:32:59 -04:00
const onDeleteWalletsAfterUninstallSwitch = useCallback(async value => {
await BlueApp.setResetOnAppUninstallTo(value);
2020-07-15 13:32:59 -04:00
setDeleteWalletsAfterUninstall(value);
}, []);
2019-08-23 03:04:23 -04:00
2020-07-15 13:32:59 -04:00
const onEncryptStorageSwitch = useCallback(
async value => {
setIsLoading(true);
2019-08-23 03:04:23 -04:00
if (value === true) {
let p1 = await prompt(loc.settings.password, loc.settings.password_explain).catch(() => {
2020-07-15 13:32:59 -04:00
setIsLoading(false);
2019-08-23 03:04:23 -04:00
p1 = undefined;
});
if (!p1) {
2020-07-15 13:32:59 -04:00
setIsLoading(false);
2019-08-23 03:04:23 -04:00
return;
}
const p2 = await prompt(loc.settings.password, loc.settings.retype_password).catch(() => {
2020-07-15 13:32:59 -04:00
setIsLoading(false);
2019-08-23 03:04:23 -04:00
});
if (p1 === p2) {
await BlueApp.encryptStorage(p1);
2020-07-15 13:32:59 -04:00
setIsLoading(false);
setStorageIsEncrypted(await BlueApp.storageIsEncrypted());
2019-08-23 03:04:23 -04:00
} else {
2020-07-15 13:32:59 -04:00
setIsLoading(false);
2019-08-23 03:04:23 -04:00
alert(loc.settings.passwords_do_not_match);
}
} else {
Alert.alert(
2020-07-20 16:38:46 +03:00
loc.settings.encrypt_decrypt,
loc.settings.encrypt_decrypt_q,
2019-08-23 03:04:23 -04:00
[
{
2020-07-20 16:38:46 +03:00
text: loc._.cancel,
2019-08-23 03:04:23 -04:00
style: 'cancel',
2020-07-15 13:32:59 -04:00
onPress: () => setIsLoading(false),
2019-08-23 03:04:23 -04:00
},
{
text: loc._.ok,
style: 'destructive',
2020-07-15 13:32:59 -04:00
onPress: decryptStorage,
2019-08-23 03:04:23 -04:00
},
],
{ cancelable: false },
);
}
2020-07-15 13:32:59 -04:00
},
[decryptStorage],
);
2019-08-23 03:04:23 -04:00
2020-07-15 13:32:59 -04:00
const onUseBiometricSwitch = useCallback(
async value => {
const isBiometricsEnabled = {
isDeviceBiometricCapable: biometrics.isDeviceBiometricCapable,
isBiometricsEnabled: biometrics.isBiometricsEnabled,
biometricsType: biometrics.biometricsType,
};
if (await Biometric.unlockWithBiometrics()) {
isBiometricsEnabled.isBiometricsEnabled = value;
await Biometric.setBiometricUseEnabled(value);
setBiometrics(isBiometricsEnabled);
}
},
[biometrics],
);
2020-07-15 13:32:59 -04:00
const navigateToPlausibleDeniability = () => {
navigate('PlausibleDeniability');
};
2020-07-15 13:32:59 -04:00
return isLoading ? (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<BlueLoadingHook />
</SafeBlueArea>
) : (
<SafeBlueArea forceInset={{ horizontal: 'always' }} style={styles.root}>
<ScrollView contentContainerStyle={styles.root}>
{biometrics.isDeviceBiometricCapable && (
<>
<BlueHeaderDefaultSubHooks leftText="biometrics" rightComponent={null} />
2020-09-21 21:53:28 -04:00
<BlueListItem
2020-07-20 16:38:46 +03:00
title={loc.formatString(loc.settings.encrypt_use, { type: biometrics.biometricsType })}
2020-07-15 13:32:59 -04:00
Component={TouchableWithoutFeedback}
switch={{ value: biometrics.isBiometricsEnabled, onValueChange: onUseBiometricSwitch }}
/>
<BlueCard>
2020-07-20 16:38:46 +03:00
<BlueTextHooks>{loc.formatString(loc.settings.encrypt_use_expl, { type: biometrics.biometricsType })}</BlueTextHooks>
2020-07-15 13:32:59 -04:00
</BlueCard>
<BlueSpacing20 />
</>
)}
2020-07-20 16:38:46 +03:00
<BlueHeaderDefaultSubHooks leftText={loc.settings.encrypt_tstorage} rightComponent={null} />
2020-09-21 21:53:28 -04:00
<BlueListItem
2020-07-15 13:32:59 -04:00
testID="EncyptedAndPasswordProtected"
hideChevron
2020-07-20 16:38:46 +03:00
title={loc.settings.encrypt_enc_and_pass}
2020-07-15 13:32:59 -04:00
Component={TouchableWithoutFeedback}
switch={{ onValueChange: onEncryptStorageSwitch, value: storageIsEncrypted }}
/>
{Platform.OS === 'ios' && (
2020-09-21 21:53:28 -04:00
<BlueListItem
2019-08-23 03:04:23 -04:00
hideChevron
2020-07-20 16:38:46 +03:00
title={loc.settings.encrypt_del_uninstall}
2020-05-03 14:17:49 -04:00
Component={TouchableWithoutFeedback}
2020-07-15 13:32:59 -04:00
switch={{
onValueChange: onDeleteWalletsAfterUninstallSwitch,
value: deleteWalletsAfterUninstall,
}}
2019-08-23 03:04:23 -04:00
/>
2020-07-15 13:32:59 -04:00
)}
{storageIsEncrypted && (
2020-09-21 21:53:28 -04:00
<BlueListItem
2020-07-15 13:32:59 -04:00
onPress={navigateToPlausibleDeniability}
title={loc.settings.plausible_deniability}
chevron
testID="PlausibleDeniabilityButton"
Component={TouchableOpacity}
/>
)}
</ScrollView>
</SafeBlueArea>
);
};
2020-07-15 13:32:59 -04:00
export default EncryptStorage;
EncryptStorage.navigationOptions = () => ({
...BlueNavigationStyle(),
2020-07-20 16:38:46 +03:00
headerTitle: loc.settings.encrypt_title,
2020-07-15 13:32:59 -04:00
});