/* global alert */ import FingerprintScanner from 'react-native-fingerprint-scanner'; import { Platform, Alert } from 'react-native'; import PasscodeAuth from 'react-native-passcode-auth'; import * as NavigationService from '../NavigationService'; import { StackActions, CommonActions } from '@react-navigation/native'; import RNSecureKeyStore from 'react-native-secure-key-store'; import loc from '../loc'; import { useContext } from 'react'; import { BlueStorageContext } from '../blue_modules/storage-context'; import * as Sentry from '@sentry/react-native'; function Biometric() { const { getItem, setItem } = useContext(BlueStorageContext); Biometric.STORAGEKEY = 'Biometrics'; Biometric.FaceID = 'Face ID'; Biometric.TouchID = 'Touch ID'; Biometric.Biometrics = 'Biometrics'; Biometric.isDeviceBiometricCapable = async () => { try { const isDeviceBiometricCapable = await FingerprintScanner.isSensorAvailable(); if (isDeviceBiometricCapable) { return true; } } catch { Biometric.setBiometricUseEnabled(false); return false; } }; Biometric.biometricType = async () => { try { const isSensorAvailable = await FingerprintScanner.isSensorAvailable(); return isSensorAvailable; } catch (e) { console.log(e); } return false; }; Biometric.isBiometricUseEnabled = async () => { try { const enabledBiometrics = await getItem(Biometric.STORAGEKEY); return !!enabledBiometrics; } catch (_) {} return false; }; Biometric.isBiometricUseCapableAndEnabled = async () => { const isBiometricUseEnabled = await Biometric.isBiometricUseEnabled(); const isDeviceBiometricCapable = await Biometric.isDeviceBiometricCapable(); return isBiometricUseEnabled && isDeviceBiometricCapable; }; Biometric.setBiometricUseEnabled = async value => { await setItem(Biometric.STORAGEKEY, value === true ? '1' : ''); }; Biometric.unlockWithBiometrics = async () => { const isDeviceBiometricCapable = await Biometric.isDeviceBiometricCapable(); if (isDeviceBiometricCapable) { return new Promise(resolve => { FingerprintScanner.authenticate({ description: loc.settings.biom_conf_identity, fallbackEnabled: true }) .then(() => resolve(true)) .catch(() => resolve(false)) .finally(() => FingerprintScanner.release()); }); } return false; }; Biometric.clearKeychain = async () => { Sentry.captureMessage('Biometric.clearKeychain()'); await RNSecureKeyStore.remove('data'); await RNSecureKeyStore.remove('data_encrypted'); await RNSecureKeyStore.remove(Biometric.STORAGEKEY); NavigationService.dispatch(StackActions.replace('WalletsRoot')); }; Biometric.requestDevicePasscode = async () => { let isDevicePasscodeSupported = false; try { isDevicePasscodeSupported = await PasscodeAuth.isSupported(); if (isDevicePasscodeSupported) { const isAuthenticated = await PasscodeAuth.authenticate(); if (isAuthenticated) { Alert.alert( loc.settings.encrypt_tstorage, loc.settings.biom_remove_decrypt, [ { text: loc._.cancel, style: 'cancel' }, { text: loc._.ok, onPress: () => Biometric.clearKeychain(), }, ], { cancelable: false }, ); } } } catch { isDevicePasscodeSupported = undefined; } if (isDevicePasscodeSupported === false) { alert(loc.settings.biom_no_passcode); } }; Biometric.showKeychainWipeAlert = () => { if (Platform.OS === 'ios') { Alert.alert( loc.settings.encrypt_tstorage, loc.settings.biom_10times, [ { text: loc._.cancel, onPress: () => { NavigationService.dispatch( CommonActions.setParams({ index: 0, routes: [{ name: 'UnlockWithScreenRoot' }, { params: { unlockOnComponentMount: false } }], }), ); }, style: 'cancel', }, { text: loc._.ok, onPress: () => Biometric.requestDevicePasscode(), style: 'default', }, ], { cancelable: false }, ); } }; return null; } export default Biometric;