From e08af6ad55016d121aeb3649a62cb60d113c54ab Mon Sep 17 00:00:00 2001 From: sethkfman <10342624+sethkfman@users.noreply.github.com> Date: Tue, 16 Nov 2021 15:01:50 -0700 Subject: [PATCH] [FIX] iOS FaceID Deny Handler (#3371) * added method to catch deny biometric pop-up and reset view * Updated function comment * remove android check and simplified setState --- app/components/Views/ChoosePassword/index.js | 26 ++++++++++++++++++-- locales/languages/en.json | 3 ++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/components/Views/ChoosePassword/index.js b/app/components/Views/ChoosePassword/index.js index 5e61892ce3e..bc54a2fcc66 100644 --- a/app/components/Views/ChoosePassword/index.js +++ b/app/components/Views/ChoosePassword/index.js @@ -206,6 +206,7 @@ const styles = StyleSheet.create({ }); const PASSCODE_NOT_SET_ERROR = 'Error: Passcode not set.'; +const IOS_DENY_BIOMETRIC_ERROR = 'The user name or passphrase you entered is not correct.'; /** * View where users can set their password for the first time @@ -341,7 +342,12 @@ class ChoosePassword extends PureComponent { // Set state in app as it was with password await SecureKeychain.resetGenericPassword(); if (this.state.biometryType && this.state.biometryChoice) { - await SecureKeychain.setGenericPassword(password, SecureKeychain.TYPES.BIOMETRICS); + try { + await SecureKeychain.setGenericPassword(password, SecureKeychain.TYPES.BIOMETRICS); + } catch (error) { + if (Device.isIos) await this.handleRejectedOsBiometricPrompt(error); + throw error; + } } else if (this.state.rememberMe) { await SecureKeychain.setGenericPassword(password, SecureKeychain.TYPES.REMEMBER_ME); } else { @@ -351,7 +357,6 @@ class ChoosePassword extends PureComponent { await AsyncStorage.removeItem(SEED_PHRASE_HINTS); this.props.passwordSet(); this.props.setLockTime(AppConstants.DEFAULT_LOCK_TIMEOUT); - this.setState({ loading: false }); this.props.navigation.navigate('AccountBackupStep1'); InteractionManager.runAfterInteractions(() => { @@ -391,6 +396,23 @@ class ChoosePassword extends PureComponent { } }; + /** + * This function handles the case when the user rejects the OS prompt for allowing use of biometrics. + * It resets the state and and prompts the user to both set the "Remember Me" state and to try again. + * @param {*} error - error provide from try catch wrapping the biometric set password attempt + */ + handleRejectedOsBiometricPrompt = async (error) => { + const biometryType = await SecureKeychain.getSupportedBiometryType(); + if (error.toString().includes(IOS_DENY_BIOMETRIC_ERROR) && !biometryType) { + this.setState({ + biometryType, + biometryChoice: true, + }); + this.updateBiometryChoice(); + throw Error(strings('choose_password.disable_biometric_error')); + } + }; + /** * Recreates a vault * diff --git a/locales/languages/en.json b/locales/languages/en.json index 382baf49f6e..eb9ff48a4c7 100644 --- a/locales/languages/en.json +++ b/locales/languages/en.json @@ -179,7 +179,8 @@ "i_understand": "I understand that MetaMask cannot recover this password for me.", "learn_more": "Learn more.", "secure": "Secure wallet", - "confirm": "Confirm Secret Recovery Phrase" + "confirm": "Confirm Secret Recovery Phrase", + "disable_biometric_error": "You have disabled biometrics for the app. Update Remember Me settings and try again." }, "reset_password": { "title": "Change password",