diff --git a/.changes/fix-bio-fallback-error-android.md b/.changes/fix-bio-fallback-error-android.md new file mode 100644 index 00000000..892a5c1e --- /dev/null +++ b/.changes/fix-bio-fallback-error-android.md @@ -0,0 +1,6 @@ +--- +"biometric": patch:bug +"biometric-js": patch:bug +--- + +Fix biometric plugin reporting an inconsistent and incorrect error on Android when no device passcode was set. \ No newline at end of file diff --git a/plugins/biometric/android/src/main/java/BiometricActivity.kt b/plugins/biometric/android/src/main/java/BiometricActivity.kt index 011de4d5..4f118775 100644 --- a/plugins/biometric/android/src/main/java/BiometricActivity.kt +++ b/plugins/biometric/android/src/main/java/BiometricActivity.kt @@ -38,15 +38,12 @@ class BiometricActivity : AppCompatActivity() { var title = intent.getStringExtra(BiometricPlugin.TITLE) val subtitle = intent.getStringExtra(BiometricPlugin.SUBTITLE) val description = intent.getStringExtra(BiometricPlugin.REASON) - allowDeviceCredential = false + val allowDeviceCredentialArg = intent.getBooleanExtra(BiometricPlugin.DEVICE_CREDENTIAL, false) // Android docs say we should check if the device is secure before enabling device credential fallback val manager = getSystemService( Context.KEYGUARD_SERVICE ) as KeyguardManager - if (manager.isDeviceSecure) { - allowDeviceCredential = - intent.getBooleanExtra(BiometricPlugin.DEVICE_CREDENTIAL, false) - } + val allowDeviceCredential = allowDeviceCredentialArg && manager.isDeviceSecure; if (title.isNullOrEmpty()) { title = "Authenticate" @@ -73,6 +70,7 @@ class BiometricActivity : AppCompatActivity() { if (negativeButtonText.isNullOrEmpty()) "Cancel" else negativeButtonText ) } + builder.setConfirmationRequired( intent.getBooleanExtra(BiometricPlugin.CONFIRMATION_REQUIRED, true) ) @@ -85,6 +83,13 @@ class BiometricActivity : AppCompatActivity() { errorCode: Int, errorMessage: CharSequence ) { + var errorCode = errorCode + var errorMessage = errorMessage + // override error to properly report no device credential if needed + if (allowDeviceCredentialArg && errorCode == BiometricPrompt.ERROR_NO_BIOMETRICS) { + errorCode = BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL + errorMessage = "No device credential set" + } super.onAuthenticationError(errorCode, errorMessage) finishActivity( BiometryResultType.ERROR, @@ -122,8 +127,4 @@ class BiometricActivity : AppCompatActivity() { setResult(Activity.RESULT_OK, intent) finish() } - - companion object { - var allowDeviceCredential = false - } } \ No newline at end of file diff --git a/plugins/biometric/android/src/main/java/BiometricPlugin.kt b/plugins/biometric/android/src/main/java/BiometricPlugin.kt index b3436fd4..b9b7ab05 100644 --- a/plugins/biometric/android/src/main/java/BiometricPlugin.kt +++ b/plugins/biometric/android/src/main/java/BiometricPlugin.kt @@ -73,7 +73,7 @@ class BiometricPlugin(private val activity: Activity): Plugin(activity) { biometryErrorCodeMap[BiometricPrompt.ERROR_LOCKOUT_PERMANENT] = "biometryLockout" biometryErrorCodeMap[BiometricPrompt.ERROR_NEGATIVE_BUTTON] = "userCancel" biometryErrorCodeMap[BiometricPrompt.ERROR_NO_BIOMETRICS] = "biometryNotEnrolled" - biometryErrorCodeMap[BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL] = "noDeviceCredential" + biometryErrorCodeMap[BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL] = "passcodeNotSet" biometryErrorCodeMap[BiometricPrompt.ERROR_NO_SPACE] = "systemCancel" biometryErrorCodeMap[BiometricPrompt.ERROR_TIMEOUT] = "systemCancel" biometryErrorCodeMap[BiometricPrompt.ERROR_UNABLE_TO_PROCESS] = "systemCancel"