mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-26 00:31:00 +01:00
ADD: Keychain clear if password is lost
This commit is contained in:
parent
e38753c86d
commit
0792add3a2
6 changed files with 95 additions and 4 deletions
20
BlueApp.js
20
BlueApp.js
|
@ -3,14 +3,17 @@
|
|||
*/
|
||||
import { AppStorage } from './class';
|
||||
import DeviceQuickActions from './class/quick-actions';
|
||||
import Biometric from './class/biometrics';
|
||||
import { Platform } from 'react-native';
|
||||
import loc from './loc';
|
||||
const prompt = require('./blue_modules/prompt');
|
||||
const EV = require('./blue_modules/events');
|
||||
const currency = require('./blue_modules/currency');
|
||||
const BlueElectrum = require('./blue_modules/BlueElectrum'); // eslint-disable-line no-unused-vars
|
||||
|
||||
/** @type {AppStorage} */
|
||||
const BlueApp = new AppStorage();
|
||||
// If attempt reaches 10, a wipe keychain option will be provided to the user.
|
||||
let unlockAttempt = 0;
|
||||
|
||||
async function startAndDecrypt(retry) {
|
||||
console.log('startAndDecrypt');
|
||||
|
@ -58,11 +61,24 @@ async function startAndDecrypt(retry) {
|
|||
if (hadToRefresh && noErr) {
|
||||
await BlueApp.saveToDisk(); // caching
|
||||
} */
|
||||
// We want to return true to let the UnlockWith screen that its ok to proceed.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!success && password) {
|
||||
// we had password and yet could not load/decrypt
|
||||
return startAndDecrypt(true);
|
||||
unlockAttempt++;
|
||||
if (unlockAttempt < 10 || Platform.OS !== 'ios') {
|
||||
return startAndDecrypt(true);
|
||||
} else {
|
||||
unlockAttempt = 0;
|
||||
Biometric.showKeychainWipeAlert();
|
||||
// We want to return false to let the UnlockWith screen that it is NOT ok to proceed.
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Return true because there was no wallet data in keychain. Proceed.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,8 +96,11 @@ export default class UnlockWith extends Component {
|
|||
|
||||
unlockWithKey = () => {
|
||||
this.setState({ isAuthenticating: true }, async () => {
|
||||
await BlueApp.startAndDecrypt();
|
||||
this.successfullyAuthenticated();
|
||||
if (await BlueApp.startAndDecrypt()) {
|
||||
this.successfullyAuthenticated();
|
||||
} else {
|
||||
this.setState({ isAuthenticating: false });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
/* global alert */
|
||||
import Biometrics from 'react-native-biometrics';
|
||||
import { Platform, Alert } from 'react-native';
|
||||
import PasscodeAuth from 'react-native-passcode-auth';
|
||||
import * as NavigationService from '../NavigationService';
|
||||
import { StackActions } from '@react-navigation/native';
|
||||
import RNSecureKeyStore from 'react-native-secure-key-store';
|
||||
const BlueApp = require('../BlueApp');
|
||||
const loc = require('../loc');
|
||||
|
||||
export default class Biometric {
|
||||
static STORAGEKEY = 'Biometrics';
|
||||
|
@ -58,4 +65,58 @@ export default class Biometric {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static async clearKeychain() {
|
||||
await RNSecureKeyStore.remove('data');
|
||||
await RNSecureKeyStore.remove('data_encrypted');
|
||||
await BlueApp.setResetOnAppUninstallTo(true);
|
||||
NavigationService.dispatch(StackActions.replace('WalletsRoot'));
|
||||
}
|
||||
|
||||
static async requestDevicePasscode() {
|
||||
let isDevicePasscodeSupported = false;
|
||||
try {
|
||||
isDevicePasscodeSupported = await PasscodeAuth.isSupported();
|
||||
if (isDevicePasscodeSupported) {
|
||||
const isAuthenticated = await PasscodeAuth.authenticate();
|
||||
if (isAuthenticated) {
|
||||
Alert.alert(
|
||||
'Storage',
|
||||
`All your wallets will be removed and your storage will be decrypted. Are you sure you want to proceed?`,
|
||||
[
|
||||
{ text: loc.send.details.cancel, style: 'cancel' },
|
||||
{
|
||||
text: loc._.ok,
|
||||
onPress: () => Biometric.clearKeychain(),
|
||||
},
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
isDevicePasscodeSupported = undefined;
|
||||
}
|
||||
if (isDevicePasscodeSupported === false) {
|
||||
alert('Your device does not have a passcode. In order to proceed, please configure a passcode in the Settings app.');
|
||||
}
|
||||
}
|
||||
|
||||
static showKeychainWipeAlert() {
|
||||
if (Platform.OS === 'ios') {
|
||||
Alert.alert(
|
||||
'Storage',
|
||||
`You have attempted to enter your password 10 times. Would you like to reset your storage? This will remove all wallets and decrypt your storage.`,
|
||||
[
|
||||
{ text: loc.send.details.cancel, onPress: () => {}, style: 'cancel' },
|
||||
{
|
||||
text: loc._.ok,
|
||||
onPress: () => Biometric.requestDevicePasscode(),
|
||||
style: 'default',
|
||||
},
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,8 @@ PODS:
|
|||
- OpenSSL-Universal (1.0.2.19):
|
||||
- OpenSSL-Universal/Static (= 1.0.2.19)
|
||||
- OpenSSL-Universal/Static (1.0.2.19)
|
||||
- PasscodeAuth (1.0.0):
|
||||
- React
|
||||
- RCTRequired (0.62.2)
|
||||
- RCTTypeSafety (0.62.2):
|
||||
- FBLazyVector (= 0.62.2)
|
||||
|
@ -413,6 +415,7 @@ DEPENDENCIES:
|
|||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- lottie-ios (from `../node_modules/lottie-ios`)
|
||||
- lottie-react-native (from `../node_modules/lottie-react-native`)
|
||||
- PasscodeAuth (from `../node_modules/react-native-passcode-auth`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
|
@ -506,6 +509,8 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/lottie-ios"
|
||||
lottie-react-native:
|
||||
:path: "../node_modules/lottie-react-native"
|
||||
PasscodeAuth:
|
||||
:path: "../node_modules/react-native-passcode-auth"
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/RCTRequired"
|
||||
RCTTypeSafety:
|
||||
|
@ -636,6 +641,7 @@ SPEC CHECKSUMS:
|
|||
lottie-ios: 48fac6be217c76937e36e340e2d09cf7b10b7f5f
|
||||
lottie-react-native: a664f59f1f298c2696dd0ae07b15cbdfc433cb02
|
||||
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
|
||||
PasscodeAuth: 1cc99b13d8e4de4716d7e2b4069af2f1a9de30b2
|
||||
RCTRequired: cec6a34b3ac8a9915c37e7e4ad3aa74726ce4035
|
||||
RCTTypeSafety: 93006131180074cffa227a1075802c89a49dd4ce
|
||||
React: 29a8b1a02bd764fb7644ef04019270849b9a7ac3
|
||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -14963,6 +14963,10 @@
|
|||
"resolved": "https://registry.npmjs.org/react-native-obscure/-/react-native-obscure-1.2.1.tgz",
|
||||
"integrity": "sha512-zepY31U2HAWrxPP+uGhDFFa1yGdbIa06iviCYRQJcEN2K4gtcEYBCtsk+PdClaiwIREZOQ7YKscxCIlZyR1m6w=="
|
||||
},
|
||||
"react-native-passcode-auth": {
|
||||
"version": "git+https://github.com/BlueWallet/react-native-passcode-auth.git#a2ff977ba92b36f8d0a5567f59c05cc608e8bd12",
|
||||
"from": "git+https://github.com/BlueWallet/react-native-passcode-auth.git#a2ff977ba92b36f8d0a5567f59c05cc608e8bd12"
|
||||
},
|
||||
"react-native-popup-menu-android": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-popup-menu-android/-/react-native-popup-menu-android-1.0.3.tgz",
|
||||
|
|
|
@ -126,6 +126,7 @@
|
|||
"react-native-localize": " 1.4.0",
|
||||
"react-native-modal": "11.5.6",
|
||||
"react-native-obscure": "1.2.1",
|
||||
"react-native-passcode-auth": "git+https://github.com/BlueWallet/react-native-passcode-auth.git#a2ff977ba92b36f8d0a5567f59c05cc608e8bd12",
|
||||
"react-native-popup-menu-android": "1.0.3",
|
||||
"react-native-privacy-snapshot": "git+https://github.com/BlueWallet/react-native-privacy-snapshot.git",
|
||||
"react-native-prompt-android": "git+https://github.com/BlueWallet/react-native-prompt-android.git#2073b07f64bf5dc95807f64d79f37bdb111e6951",
|
||||
|
|
Loading…
Add table
Reference in a new issue