From 94185b7c020cc98b41cba06f4665bf295a6e8acd Mon Sep 17 00:00:00 2001 From: Carson <375162094@qq.com> Date: Fri, 24 Apr 2020 16:33:23 +0800 Subject: [PATCH 1/6] =?UTF-8?q?1=E3=80=81=E5=AE=89=E5=8D=93=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=8F=82=E6=95=B0=20cancelButton=202=E3=80=81?= =?UTF-8?q?=E5=AE=89=E5=8D=93=E4=BF=AE=E5=A4=8D=20lockout=20=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E7=8A=B6=E6=80=81=203=E3=80=81=E5=85=B6?= =?UTF-8?q?=E4=BB=96=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReactNativeFingerprintScannerModule.java | 29 ++++++++++--------- src/authenticate.android.js | 13 ++++++--- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java b/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java index 28372f23..eaf51d33 100644 --- a/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java +++ b/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java @@ -84,7 +84,7 @@ public AuthCallback(final Promise promise) { @Override public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) { super.onAuthenticationError(errorCode, errString); - this.promise.reject(biometricPromptErrName(errorCode), TYPE_BIOMETRICS); + this.promise.reject(biometricPromptErrName(errorCode), biometricPromptErrName(errorCode)); } @Override @@ -115,7 +115,7 @@ public BiometricPrompt getBiometricPrompt(final Promise promise) { return biometricPrompt; } - private void biometricAuthenticate(final String description, final Promise promise) { + private void biometricAuthenticate(final String description, final String cancelButton, final Promise promise) { UiThreadUtil.runOnUiThread( new Runnable() { @Override @@ -125,7 +125,7 @@ public void run() { PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() .setDeviceCredentialAllowed(false) .setConfirmationRequired(false) - .setNegativeButtonText("Cancel") + .setNegativeButtonText(cancelButton) .setTitle(description) .build(); @@ -146,7 +146,7 @@ private String biometricPromptErrName(int errCode) { case BiometricPrompt.ERROR_LOCKOUT: return "DeviceLocked"; case BiometricPrompt.ERROR_LOCKOUT_PERMANENT: - return "DeviceLocked"; + return "DeviceLockedPermanent"; case BiometricPrompt.ERROR_NEGATIVE_BUTTON: return "UserCancel"; case BiometricPrompt.ERROR_NO_BIOMETRICS: @@ -188,19 +188,18 @@ private String getSensorError() { } @ReactMethod - public void authenticate(String description, final Promise promise) { + public void authenticate(String description, String cancelButton, final Promise promise) { if (requiresLegacyAuthentication()) { legacyAuthenticate(promise); } else { final String errorName = getSensorError(); if (errorName != null) { - promise.reject(errorName, TYPE_BIOMETRICS); - ReactNativeFingerprintScannerModule.this.release(); + promise.reject(errorName, errorName); return; } - biometricAuthenticate(description, promise); + biometricAuthenticate(description, cancelButton, promise); } } @@ -234,13 +233,12 @@ public void isSensorAvailable(final Promise promise) { // current API String errorName = getSensorError(); if (errorName != null) { - promise.reject(errorName, TYPE_BIOMETRICS); + promise.reject(errorName, errorName); } else { promise.resolve(TYPE_BIOMETRICS); } } - // for Samsung/MeiZu compat, Android v16-23 private FingerprintIdentify getFingerprintIdentify() { if (mFingerprintIdentify != null) { @@ -287,13 +285,17 @@ private void legacyAuthenticate(final Promise promise) { @Override public void onSucceed() { promise.resolve(true); - ReactNativeFingerprintScannerModule.this.release(); } @Override public void onNotMatch(int availableTimes) { - mReactContext.getJSModule(RCTDeviceEventEmitter.class) - .emit("FINGERPRINT_SCANNER_AUTHENTICATION", "AuthenticationNotMatch"); + if( availableTimes <= 0 ){ + mReactContext.getJSModule(RCTDeviceEventEmitter.class) + .emit("FINGERPRINT_SCANNER_AUTHENTICATION", "AuthenticationLockout"); + }else{ + mReactContext.getJSModule(RCTDeviceEventEmitter.class) + .emit("FINGERPRINT_SCANNER_AUTHENTICATION", "AuthenticationNotMatch"); + } } @Override @@ -303,7 +305,6 @@ public void onFailed(boolean isDeviceLocked) { } else { promise.reject("AuthenticationFailed", TYPE_FINGERPRINT_LEGACY); } - ReactNativeFingerprintScannerModule.this.release(); } @Override diff --git a/src/authenticate.android.js b/src/authenticate.android.js index 439ab857..0f89ca0c 100644 --- a/src/authenticate.android.js +++ b/src/authenticate.android.js @@ -7,8 +7,8 @@ import createError from './createError'; const { ReactNativeFingerprintScanner } = NativeModules; -const authCurrent = (description, resolve, reject) => { - ReactNativeFingerprintScanner.authenticate(description) +const authCurrent = (description, cancelButton, resolve, reject) => { + ReactNativeFingerprintScanner.authenticate(description, cancelButton) .then(() => { resolve(true); }) @@ -38,11 +38,16 @@ const authLegacy = (onAttempt, resolve, reject) => { const nullOnAttempt = () => null; -export default ({ description, onAttempt }) => { +export default ({ description, cancelButton, onAttempt }) => { return new Promise((resolve, reject) => { if (!description) { description = "Log In"; } + + if (!cancelButton) { + cancelButton = "Cancel"; + } + if (!onAttempt) { onAttempt = nullOnAttempt; } @@ -51,6 +56,6 @@ export default ({ description, onAttempt }) => { return authLegacy(onAttempt, resolve, reject); } - return authCurrent(description, resolve, reject); + return authCurrent(description, cancelButton, resolve, reject); }); } From 986f031841661cf5000f74f5fab72a647a385db4 Mon Sep 17 00:00:00 2001 From: Carson <375162094@qq.com> Date: Fri, 24 Apr 2020 16:37:09 +0800 Subject: [PATCH 2/6] =?UTF-8?q?1=E3=80=81ios=20=E4=BC=98=E5=8C=96=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BF=A1=E6=81=AF=EF=BC=8C=E6=9B=B4=E5=85=A8=E9=9D=A2?= =?UTF-8?q?=202=E3=80=81ios=20=E6=96=B0=E5=A2=9E=20authenticateDevice=20?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E5=94=A4=E8=B5=B7=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E8=A7=A3=E9=94=81=203=E3=80=81ios=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20biometric=20=E8=BF=94=E5=9B=9E=E7=9A=84=20?= =?UTF-8?q?code=20=E4=B8=8D=E6=AD=A3=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=204=E3=80=81=E6=96=B0=E5=A2=9E=E9=94=99=E8=AF=AF=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/ReactNativeFingerprintScanner.m | 99 +++++++++++++++++++++++++++-- src/authenticateDevice.android.js | 1 + src/authenticateDevice.ios.js | 16 +++++ src/createError.js | 2 + src/index.js | 2 + 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 src/authenticateDevice.android.js create mode 100644 src/authenticateDevice.ios.js diff --git a/ios/ReactNativeFingerprintScanner.m b/ios/ReactNativeFingerprintScanner.m index 5d324ebc..e6174ece 100644 --- a/ios/ReactNativeFingerprintScanner.m +++ b/ios/ReactNativeFingerprintScanner.m @@ -32,13 +32,43 @@ @implementation ReactNativeFingerprintScanner message = [self getBiometryType:context]; break; + case LAErrorTouchIDLockout: + code = @"AuthenticationLockout"; + message = [self getBiometryType:context]; + break; + + case LAErrorAuthenticationFailed: + code = @"AuthenticationFailed"; + message = [self getBiometryType:context]; + break; + + case LAErrorUserCancel: + code = @"UserCancel"; + message = [self getBiometryType:context]; + break; + + case LAErrorUserFallback: + code = @"UserFallback"; + message = [self getBiometryType:context]; + break; + + case LAErrorSystemCancel: + code = @"SystemCancel"; + message = [self getBiometryType:context]; + break; + + case LAErrorPasscodeNotSet: + code = @"PasscodeNotSet"; + message = [self getBiometryType:context]; + break; + default: - code = @"FingerprintScannerNotSupported"; + code = @"AuthenticationNotMatch"; message = nil; break; } - - callback(@[RCTJSErrorFromCodeMessageAndNSError(code, message, nil)]); + NSLog(@"Authentication failed: %@", code); + callback(@[RCTJSErrorFromCodeMessageAndNSError(code, code, nil)]); return; } } @@ -67,6 +97,11 @@ @implementation ReactNativeFingerprintScanner NSString *errorReason; switch (error.code) { + + case LAErrorTouchIDLockout: + errorReason = @"AuthenticationLockout"; + break; + case LAErrorAuthenticationFailed: errorReason = @"AuthenticationFailed"; break; @@ -96,7 +131,7 @@ @implementation ReactNativeFingerprintScanner break; default: - errorReason = @"FingerprintScannerUnknownError"; + errorReason = @"AuthenticationNotMatch"; break; } @@ -116,11 +151,65 @@ @implementation ReactNativeFingerprintScanner } else { // Device does not support FingerprintScanner - callback(@[RCTJSErrorFromCodeMessageAndNSError(@"FingerprintScannerNotSupported", @"FingerprintScannerNotSupported", nil)]); + // callback(@[RCTJSErrorFromCodeMessageAndNSError(@"FingerprintScannerNotSupported", @"FingerprintScannerNotSupported", nil)]); + NSString *errorReason; + + switch (error.code) { + case LAErrorTouchIDNotAvailable: + errorReason = @"FingerprintScannerNotAvailable"; + break; + + case LAErrorTouchIDNotEnrolled: + errorReason = @"FingerprintScannerNotEnrolled"; + break; + + case LAErrorTouchIDLockout: + errorReason = @"AuthenticationLockout"; + break; + + case LAErrorAuthenticationFailed: + errorReason = @"AuthenticationFailed"; + break; + + case LAErrorUserCancel: + errorReason = @"UserCancel"; + break; + + case LAErrorUserFallback: + errorReason = @"UserFallback"; + break; + + case LAErrorSystemCancel: + errorReason = @"SystemCancel"; + break; + + case LAErrorPasscodeNotSet: + errorReason = @"PasscodeNotSet"; + break; + + default: + errorReason = @"AuthenticationNotMatch"; + break; + } + callback(@[RCTJSErrorFromCodeMessageAndNSError(errorReason, errorReason, nil)]); return; } } +RCT_EXPORT_METHOD(authenticateDevice: (RCTResponseSenderBlock)callback) +{ + LAContext *context = [[LAContext alloc] init]; + [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason: @" " reply:^(BOOL success, NSError * _Nullable error) { + if(error) { + NSString *errorReason = @"UserDeviceCancel"; + NSLog(@"Authentication failed: %@", errorReason); + callback(@[RCTJSErrorFromCodeMessageAndNSError(errorReason, errorReason, nil)]); + } else { + callback(@[[NSNull null], @"Authentication unlock."]); + } + }]; +} + - (NSString *)getBiometryType:(LAContext *)context { if (@available(iOS 11, *)) { diff --git a/src/authenticateDevice.android.js b/src/authenticateDevice.android.js new file mode 100644 index 00000000..461f67a0 --- /dev/null +++ b/src/authenticateDevice.android.js @@ -0,0 +1 @@ +export default () => null; diff --git a/src/authenticateDevice.ios.js b/src/authenticateDevice.ios.js new file mode 100644 index 00000000..a878cdd8 --- /dev/null +++ b/src/authenticateDevice.ios.js @@ -0,0 +1,16 @@ +import { NativeModules } from 'react-native'; +import createError from 'react-native-fingerprint-scanner/src/createError'; + +const { ReactNativeFingerprintScanner } = NativeModules; + +export default () => { + return new Promise((resolve, reject) => { + ReactNativeFingerprintScanner.authenticateDevice(error => { + if (error) { + return reject(createError(error.code, error.message)) + } + + return resolve(true); + }); + }); +} diff --git a/src/createError.js b/src/createError.js index f4535649..34a2c13f 100644 --- a/src/createError.js +++ b/src/createError.js @@ -5,6 +5,7 @@ const ERRORS = { FingerprintScannerNotAvailable: 'Authentication could not start because Fingerprint Scanner is not available on the device.', // auth failures + AuthenticationLockout: 'Authentication lockout', AuthenticationNotMatch: 'No match.', AuthenticationFailed: 'Authentication was not successful because the user failed to provide valid credentials.', AuthenticationTimeout: 'Authentication was not successful because the operation timed out.', @@ -18,6 +19,7 @@ const ERRORS = { DeviceLockedPermanent: 'Authentication was not successful, device must be unlocked via password.', DeviceOutOfMemory: 'Authentication could not proceed because there is not enough free memory on the device.', HardwareError: 'A hardware error occurred.', + UserDeviceCancel: 'Authentication Device was canceled' }; class FingerprintScannerError extends Error { diff --git a/src/index.js b/src/index.js index 3fc84b54..4d9400e6 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,11 @@ import authenticate from './authenticate'; import isSensorAvailable from './isSensorAvailable'; import release from './release'; +import authenticateDevice from './authenticateDevice'; export default { authenticate, release, isSensorAvailable, + authenticateDevice }; From 47a2683bb9016875c94bc362a1cfc674c1d9c1a0 Mon Sep 17 00:00:00 2001 From: Carson <375162094@qq.com> Date: Fri, 24 Apr 2020 17:16:06 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 105 +++++++++++++++++++++++++++++++++++++---------------- index.d.ts | 32 ++++++++++++++-- 2 files changed, 102 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 094aec5c..9363ea00 100644 --- a/README.md +++ b/README.md @@ -74,14 +74,14 @@ $ react-native link react-native-fingerprint-scanner - Add `import com.hieuvp.fingerprint.ReactNativeFingerprintScannerPackage;` to the imports at the top of the file - Add `new ReactNativeFingerprintScannerPackage()` to the list returned by the `getPackages()` method 2. Append the following lines to `android/settings.gradle`: - ``` - include ':react-native-fingerprint-scanner' - project(':react-native-fingerprint-scanner').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fingerprint-scanner/android') - ``` + ``` + include ':react-native-fingerprint-scanner' + project(':react-native-fingerprint-scanner').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fingerprint-scanner/android') + ``` 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: - ``` + ``` implementation project(':react-native-fingerprint-scanner') - ``` + ``` ### App Permissions @@ -162,27 +162,61 @@ import FingerprintScanner from 'react-native-fingerprint-scanner'; class FingerprintPopup extends Component { componentDidMount() { + this._iosTouchID() + } + + _iosTouchID = () => { FingerprintScanner .authenticate({ description: 'Scan your fingerprint on the device scanner to continue' }) .then(() => { - this.props.handlePopupDismissed(); AlertIOS.alert('Authenticated successfully'); }) .catch((error) => { - this.props.handlePopupDismissed(); + switch (error.biometric) { + case 'UserCancel': + console.log('The user clicks the cancel button') + break + case 'AuthenticationFailed': + console.log('User failed to identify 3 times') + break + case 'AuthenticationLockout': + console.log('Accumulated 5 identification failures, fingerprint identification was locked') + AlertIOS.alert('Identify cumulative multiple failures, temporarily unavailable', [ + { + text: 'cancel', + style: 'default', + onPress: () => { + } + }, { + text: 'To unlock', + style: 'default', + onPress: () => { + this._iosAuthenticateDevice() + } + } + ]) + break + default: + break + } AlertIOS.alert(error.message); }); } + _iosAuthenticateDevice = () => { + FingerprintScanner.authenticateDevice().then(() => { + console.log('Device unlocked') + this._iosTouchID() + }).catch((error) => { + console.log('catch error:', error.message, error.biometric) + }) + } + render() { return false; } } -FingerprintPopup.propTypes = { - handlePopupDismissed: PropTypes.func.isRequired, -}; - export default FingerprintPopup; ``` @@ -222,11 +256,7 @@ class BiometricPopup extends Component { } componentDidMount() { - if (this.requiresLegacyAuthentication()) { - this.authLegacy(); - } else { - this.authCurrent(); - } + this._androidTouchID(); } componentWillUnmount = () => { @@ -237,27 +267,18 @@ class BiometricPopup extends Component { return Platform.Version < 23; } - authCurrent() { + _androidTouchID() { FingerprintScanner - .authenticate({ description: 'Log in with Biometrics' }) + .authenticate({ + description: 'Scan your fingerprint on the device scanner to continue', + cancelButton: 'cancel', + onAttempt: this.handleAuthenticationAttemptedLegacy + }) .then(() => { this.props.onAuthenticate(); }); } - authLegacy() { - FingerprintScanner - .authenticate({ onAttempt: this.handleAuthenticationAttemptedLegacy }) - .then(() => { - this.props.handlePopupDismissedLegacy(); - Alert.alert('Fingerprint Authentication', 'Authenticated successfully'); - }) - .catch((error) => { - this.setState({ errorMessageLegacy: error.message, biometricLegacy: error.biometric }); - this.description.shake(); - }); - } - handleAuthenticationAttemptedLegacy = (error) => { this.setState({ errorMessageLegacy: error.message }); this.description.shake(); @@ -339,6 +360,24 @@ componentDidMount() { } ``` +### `authenticateDevice()`: (iOS) +Unlock with the device password. + +- Returns a `Promise` +- `error: FingerprintScannerError { name, message, biometric }` - The name and message of failure and the biometric type in use. + + +```javascript + FingerprintScanner + .authenticateDevice() + .then(() => { + console.log('Device unlocked') + this._iosTouchID() + }).catch((error) => { + console.log('catch error:', error.message, error.biometric) + }) +``` + ### `authenticate({ description, fallbackEnabled })`: (iOS) Starts Fingerprint authentication on iOS. @@ -435,6 +474,7 @@ componentWillUnmount() { | Name | Message | |---|---| +| AuthenticationLockout | Authentication lockout | | AuthenticationNotMatch | No match | | AuthenticationFailed | Authentication was not successful because the user failed to provide valid credentials | | AuthenticationTimeout | Authentication was not successful because the operation timed out | @@ -447,6 +487,7 @@ componentWillUnmount() { | DeviceLockedPermanent | Authentication was not successful, device must be unlocked via password | | DeviceOutOfMemory | Authentication could not proceed because there is not enough free memory on the device | | HardwareError | A hardware error occurred | +| UserDeviceCancel | Authentication Device was canceled | | FingerprintScannerUnknownError | Could not authenticate for an unknown reason | | FingerprintScannerNotSupported | Device does not support Fingerprint Scanner | | FingerprintScannerNotEnrolled | Authentication could not start because Fingerprint Scanner has no enrolled fingers | diff --git a/index.d.ts b/index.d.ts index e05866d9..17e5f4fe 100644 --- a/index.d.ts +++ b/index.d.ts @@ -7,7 +7,8 @@ export type AuthenticateAndroid = { onAttempt: (error: FingerprintScannerError) export type Biometrics = 'Touch ID' | 'Face ID' | 'Biometrics'; export type Errors = - | { name: 'AuthenticationNotMatch'; message: 'No match' } + | { name: 'AuthenticationLockout'; message: 'Authentication lockout'; } + | { name: 'AuthenticationNotMatch'; message: 'No match'; } | { name: 'AuthenticationFailed'; message: 'Authentication was not successful because the user failed to provide valid credentials'; @@ -38,11 +39,11 @@ export type Errors = } | { name: 'FingerprintScannerNotAvailable'; - message: ' Authentication could not start because Fingerprint Scanner is not available on the device'; + message: ' Authentication could not start because Fingerprint Scanner is not available on the device'; } | { name: 'FingerprintScannerNotEnrolled'; - message: ' Authentication could not start because Fingerprint Scanner has no enrolled fingers'; + message: ' Authentication could not start because Fingerprint Scanner has no enrolled fingers'; } | { name: 'FingerprintScannerUnknownError'; @@ -67,6 +68,10 @@ export type Errors = | { name: 'HardwareError'; message: 'A hardware error occurred.'; + } + | { + name: 'UserDeviceCancel'; + message: 'Authentication Device was canceled'; }; export type FingerprintScannerError = { biometric: Biometrics } & Errors; @@ -160,6 +165,27 @@ export interface FingerPrintProps { authenticate: ( platformProps: AuthenticateIOS | AuthenticateAndroid ) => Promise; + + /** + ### authenticateDevice(): (iOS) + Unlock with the device password. + - Returns a `Promise` + - `error: FingerprintScannerError { name, message, biometric }` - The name and message of failure and the biometric type in use. + + ------------- + Exemple + + ``` + FingerprintScanner + .authenticateDevice() + .then(() => { + AlertIOS.alert('Authenticated successfully'); + }) + .catch(error => this.setState({ errorMessage: error.message })); + ``` + ------------ + */ + authenticateDevice: () => Promise; } declare const FingerprintScanner: FingerPrintProps; From 4f2b28fa3d338f71df64341207f3e74957eed80c Mon Sep 17 00:00:00 2001 From: Carson <375162094@qq.com> Date: Fri, 24 Apr 2020 17:41:46 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 9363ea00..ad61cb28 100644 --- a/README.md +++ b/README.md @@ -268,6 +268,7 @@ class BiometricPopup extends Component { } _androidTouchID() { + FingerprintScanner.release() FingerprintScanner .authenticate({ description: 'Scan your fingerprint on the device scanner to continue', @@ -276,6 +277,24 @@ class BiometricPopup extends Component { }) .then(() => { this.props.onAuthenticate(); + }) + .catch(error => { + console.log('_androidTouchID:', error.message) + console.log('_androidTouchID:', error.biometric) + FingerprintScanner.release() + switch (error.biometric) { + case 'UserCancel': + console.log('Click the cancel button') + break + case 'DeviceLocked': + console.log('Accumulated 5 identification failures, fingerprint identification was locked') + break + case 'DeviceLockedPermanent': + console.log('Accumulates many times to recognize the failure, is locked permanently, needs to unlock') + break + default: + break + } }); } From 63facfc4e2b5c4d343753b2da1f2584febdb0d0d Mon Sep 17 00:00:00 2001 From: Carson <375162094@qq.com> Date: Sun, 26 Apr 2020 10:55:05 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ad61cb28..2e45b84c 100644 --- a/README.md +++ b/README.md @@ -174,13 +174,13 @@ class FingerprintPopup extends Component { .catch((error) => { switch (error.biometric) { case 'UserCancel': - console.log('The user clicks the cancel button') + AlertIOS.alert('The user clicks the cancel button') break case 'AuthenticationFailed': - console.log('User failed to identify 3 times') + AlertIOS.alert('User failed to identify 3 times') break case 'AuthenticationLockout': - console.log('Accumulated 5 identification failures, fingerprint identification was locked') + // console.log('Accumulated 5 identification failures, fingerprint identification was locked') AlertIOS.alert('Identify cumulative multiple failures, temporarily unavailable', [ { text: 'cancel', @@ -205,10 +205,11 @@ class FingerprintPopup extends Component { _iosAuthenticateDevice = () => { FingerprintScanner.authenticateDevice().then(() => { - console.log('Device unlocked') + // console.log('Device unlocked') this._iosTouchID() }).catch((error) => { - console.log('catch error:', error.message, error.biometric) + // error.biometric + AlertIOS.alert('catch error:', error.message) }) } @@ -272,25 +273,23 @@ class BiometricPopup extends Component { FingerprintScanner .authenticate({ description: 'Scan your fingerprint on the device scanner to continue', - cancelButton: 'cancel', + cancelButton: 'cancel', // Android adds a cancelButton onAttempt: this.handleAuthenticationAttemptedLegacy }) .then(() => { this.props.onAuthenticate(); }) .catch(error => { - console.log('_androidTouchID:', error.message) - console.log('_androidTouchID:', error.biometric) FingerprintScanner.release() switch (error.biometric) { case 'UserCancel': - console.log('Click the cancel button') + AlertIOS.alert('Click the cancel button') break case 'DeviceLocked': - console.log('Accumulated 5 identification failures, fingerprint identification was locked') + AlertIOS.alert('Accumulated 5 identification failures, fingerprint identification was locked') break case 'DeviceLockedPermanent': - console.log('Accumulates many times to recognize the failure, is locked permanently, needs to unlock') + AlertIOS.alert('Accumulates many times to recognize the failure, is locked permanently, needs to unlock') break default: break @@ -390,10 +389,10 @@ Unlock with the device password. FingerprintScanner .authenticateDevice() .then(() => { - console.log('Device unlocked') + // AlertIOS.alert('Device unlocked') this._iosTouchID() }).catch((error) => { - console.log('catch error:', error.message, error.biometric) + // AlertIOS.alert('catch error:', error.message, error.biometric) }) ``` @@ -515,3 +514,5 @@ componentWillUnmount() { ## License MIT + + From 2ab53975bfeee9b07771ae6d36b5ad67381d680c Mon Sep 17 00:00:00 2001 From: Carson <375162094@qq.com> Date: Sun, 26 Apr 2020 10:57:44 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fingerprint/ReactNativeFingerprintScannerModule.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java b/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java index eaf51d33..067ee1b2 100644 --- a/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java +++ b/android/src/main/java/com/hieuvp/fingerprint/ReactNativeFingerprintScannerModule.java @@ -191,8 +191,7 @@ private String getSensorError() { public void authenticate(String description, String cancelButton, final Promise promise) { if (requiresLegacyAuthentication()) { legacyAuthenticate(promise); - } - else { + } else { final String errorName = getSensorError(); if (errorName != null) { promise.reject(errorName, errorName); @@ -289,10 +288,10 @@ public void onSucceed() { @Override public void onNotMatch(int availableTimes) { - if( availableTimes <= 0 ){ + if (availableTimes <= 0) { mReactContext.getJSModule(RCTDeviceEventEmitter.class) .emit("FINGERPRINT_SCANNER_AUTHENTICATION", "AuthenticationLockout"); - }else{ + } else { mReactContext.getJSModule(RCTDeviceEventEmitter.class) .emit("FINGERPRINT_SCANNER_AUTHENTICATION", "AuthenticationNotMatch"); } @@ -300,7 +299,7 @@ public void onNotMatch(int availableTimes) { @Override public void onFailed(boolean isDeviceLocked) { - if(isDeviceLocked){ + if (isDeviceLocked) { promise.reject("AuthenticationFailed", "DeviceLocked"); } else { promise.reject("AuthenticationFailed", TYPE_FINGERPRINT_LEGACY);