diff --git a/README.md b/README.md
index 4ef388f..f99b79b 100644
--- a/README.md
+++ b/README.md
@@ -133,6 +133,7 @@ Get what type of hardware biometry support the device has. Resolves to a `Keycha
|-----|-------------|
|**`TOUCH_ID`**|Device supports authentication with Touch ID.|
|**`FACE_ID`**|Device supports authentication with Face ID.|
+|**`FINGERPRINT`**|Device supports authentication with Android Fingerprint.|
## Manual Installation
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 19a839b..ddbe506 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/android/src/main/java/com/oblador/keychain/DeviceAvailability.java b/android/src/main/java/com/oblador/keychain/DeviceAvailability.java
new file mode 100644
index 0000000..75afa6d
--- /dev/null
+++ b/android/src/main/java/com/oblador/keychain/DeviceAvailability.java
@@ -0,0 +1,23 @@
+package com.oblador.keychain;
+
+import android.os.Build;
+import android.content.Context;
+import android.app.KeyguardManager;
+import android.hardware.fingerprint.FingerprintManager;
+
+public class DeviceAvailability {
+ public static boolean isFingerprintAuthAvailable(Context context) {
+ FingerprintManager fingerprintManager =
+ (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
+
+ return android.os.Build.VERSION.SDK_INT >= 23 &&
+ fingerprintManager.isHardwareDetected() &&
+ fingerprintManager.hasEnrolledFingerprints();
+ }
+
+ public static boolean isSecure(Context context) {
+ KeyguardManager keyguardManager =
+ (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
+ return android.os.Build.VERSION.SDK_INT >= 23 && keyguardManager.isDeviceSecure();
+ }
+}
diff --git a/android/src/main/java/com/oblador/keychain/KeychainModule.java b/android/src/main/java/com/oblador/keychain/KeychainModule.java
index edbac50..45ee5a8 100644
--- a/android/src/main/java/com/oblador/keychain/KeychainModule.java
+++ b/android/src/main/java/com/oblador/keychain/KeychainModule.java
@@ -20,6 +20,7 @@ import com.oblador.keychain.cipherStorage.CipherStorageKeystoreAESCBC;
import com.oblador.keychain.exceptions.CryptoFailedException;
import com.oblador.keychain.exceptions.EmptyParameterException;
import com.oblador.keychain.exceptions.KeyStoreAccessException;
+import com.oblador.keychain.DeviceAvailability;
import java.util.HashMap;
import java.util.Map;
@@ -29,7 +30,9 @@ public class KeychainModule extends ReactContextBaseJavaModule {
public static final String E_EMPTY_PARAMETERS = "E_EMPTY_PARAMETERS";
public static final String E_CRYPTO_FAILED = "E_CRYPTO_FAILED";
public static final String E_KEYSTORE_ACCESS_ERROR = "E_KEYSTORE_ACCESS_ERROR";
+ public static final String E_SUPPORTED_BIOMETRY_ERROR = "E_SUPPORTED_BIOMETRY_ERROR";
public static final String KEYCHAIN_MODULE = "RNKeychainManager";
+ public static final String FINGERPRINT_SUPPORTED_NAME = "Fingerprint";
public static final String EMPTY_STRING = "";
private final Map cipherStorageMap = new HashMap<>();
@@ -161,6 +164,21 @@ public class KeychainModule extends ReactContextBaseJavaModule {
resetGenericPasswordForOptions(server, promise);
}
+ @ReactMethod
+ public void getSupportedBiometryType(Promise promise) {
+ try {
+ boolean fingerprintAuthAvailable = isFingerprintAuthAvailable();
+ if (fingerprintAuthAvailable) {
+ promise.resolve(FINGERPRINT_SUPPORTED_NAME);
+ } else {
+ promise.resolve(null);
+ }
+ } catch (Exception e) {
+ Log.e(KEYCHAIN_MODULE, e.getMessage());
+ promise.reject(E_SUPPORTED_BIOMETRY_ERROR, e);
+ }
+ }
+
// The "Current" CipherStorage is the cipherStorage with the highest API level that is lower than or equal to the current API level
private CipherStorage getCipherStorageForCurrentAPILevel() throws CryptoFailedException {
int currentAPILevel = Build.VERSION.SDK_INT;
@@ -184,6 +202,10 @@ public class KeychainModule extends ReactContextBaseJavaModule {
return cipherStorageMap.get(cipherStorageName);
}
+ private boolean isFingerprintAuthAvailable() {
+ return DeviceAvailability.isFingerprintAuthAvailable(getCurrentActivity());
+ }
+
@NonNull
private String getDefaultServiceIfNull(String service) {
return service == null ? EMPTY_STRING : service;
diff --git a/index.js b/index.js
index 18f481b..cadec3d 100644
--- a/index.js
+++ b/index.js
@@ -30,6 +30,7 @@ export const AUTHENTICATION_TYPE = {
export const BIOMETRY_TYPE = {
TOUCH_ID: 'TouchID',
FACE_ID: 'FaceID',
+ FINGERPRINT: 'Fingerprint',
};
type SecAccessible =