diff --git a/android/src/main/java/com/reactnativesimplebiometrics/SimpleBiometricsModule.java b/android/src/main/java/com/reactnativesimplebiometrics/SimpleBiometricsModule.java
index d4c53a4..64fff5f 100644
--- a/android/src/main/java/com/reactnativesimplebiometrics/SimpleBiometricsModule.java
+++ b/android/src/main/java/com/reactnativesimplebiometrics/SimpleBiometricsModule.java
@@ -1,6 +1,7 @@
package com.reactnativesimplebiometrics;
import android.app.Activity;
+import android.content.pm.PackageManager;
import androidx.annotation.NonNull;
import java.util.concurrent.Executor;
@@ -16,8 +17,6 @@
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
-
-
@ReactModule(name = SimpleBiometricsModule.NAME)
public class SimpleBiometricsModule extends ReactContextBaseJavaModule {
public static final String NAME = "SimpleBiometrics";
@@ -96,4 +95,22 @@ public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationRes
);
}
+
+ @ReactMethod
+ public void getBiometryType(Promise promise) {
+ try {
+ ReactApplicationContext context = getReactApplicationContext();
+ PackageManager pm = context.getPackageManager();
+
+ if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+ promise.resolve("Fingerprint");
+ } else if (pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ promise.resolve("Face");
+ } else {
+ promise.resolve("None");
+ }
+ } catch (Exception e) {
+ promise.resolve("Unknown");
+ }
+ }
}
diff --git a/example/App.tsx b/example/App.tsx
index 2743461..ed9fab7 100644
--- a/example/App.tsx
+++ b/example/App.tsx
@@ -10,12 +10,21 @@ import RNBiometrics from 'react-native-simple-biometrics';
const App = () => {
const [canAuth, setCanAuth] = useState(false);
+ const [type, setType] = useState('');
const [authenticated, setAuthenticated] = useState(false);
useEffect(() => {
RNBiometrics.canAuthenticate().then(setCanAuth);
}, []);
+ useEffect(() => {
+ if (!canAuth) {
+ setType('Unknown');
+ return;
+ }
+ RNBiometrics.getBiometryType().then(setType);
+ }, [canAuth]);
+
const authenticate = useCallback(async () => {
try {
const success = await RNBiometrics.requestBioAuth(
@@ -40,7 +49,7 @@ const App = () => {
{authenticated ? '🔓' : '🔒'}
- {authenticated ? '$1,000,000' : '(tap to unlock)'}
+ {authenticated ? '$1,000,000' : `(tap to unlock using ${type})`}
>
) : (
diff --git a/ios/RNSimpleBiometricsSpec.h b/ios/RNSimpleBiometricsSpec.h
new file mode 100644
index 0000000..8760e14
--- /dev/null
+++ b/ios/RNSimpleBiometricsSpec.h
@@ -0,0 +1,20 @@
+#import
+#import
+#import
+#import
+
+namespace facebook {
+namespace react {
+
+ class JSI_EXPORT NativeSimpleBiometricsSpecJSI : public ObjCTurboModule {
+ public:
+ NativeSimpleBiometricsSpecJSI(const ObjCTurboModule::InitParams ¶ms);
+
+ // Declare the methods your module exports
+ void canAuthenticate(jsi::Runtime &rt, std::function &&resolve, std::function &&reject);
+ void requestBioAuth(jsi::Runtime &rt, const std::string &title, const std::string &subtitle, std::function &&resolve, std::function &&reject);
+ void getBiometryType(jsi::Runtime &rt, std::function &&resolve, std::function &&reject);
+ };
+
+}
+}
diff --git a/ios/SimpleBiometrics.mm b/ios/SimpleBiometrics.mm
index 1bad425..e9e8812 100644
--- a/ios/SimpleBiometrics.mm
+++ b/ios/SimpleBiometrics.mm
@@ -56,6 +56,34 @@ @implementation SimpleBiometrics
}
+RCT_REMAP_METHOD(getBiometryType,
+ getBiometryTypeWithResolver:(RCTPromiseResolveBlock)resolve
+ rejecter:(RCTPromiseRejectBlock)reject)
+{
+ LAContext *context = [[LAContext alloc] init];
+ NSError *la_error = nil;
+
+ // Check if the device can evaluate a biometric policy
+ if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&la_error]) {
+ if (@available(iOS 11.0, *)) {
+ // iOS 11+ supports biometryType property
+ if (context.biometryType == LABiometryTypeFaceID) {
+ resolve(@"FaceID");
+ } else if (context.biometryType == LABiometryTypeTouchID) {
+ resolve(@"TouchID");
+ } else {
+ resolve(@"None");
+ }
+ } else {
+ // Fallback for iOS versions earlier than 11.0
+ resolve(@"Unknown");
+ }
+ } else {
+ // Handle the error case where biometric authentication is not available
+ resolve(@"None");
+ }
+}
+
// Don't compile this code when we build for the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr)getTurboModule:
diff --git a/package.json b/package.json
index ff04659..877c7ce 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-simple-biometrics",
- "version": "1.5.2",
+ "version": "1.8.0",
"description": "test",
"main": "lib/commonjs/index",
"module": "lib/module/index",
@@ -35,13 +35,13 @@
"ios",
"android"
],
- "repository": "https://github.com/smallcase/react-native-simple-biometrics",
+ "repository": "https://github.com/kierancrown/react-native-simple-biometrics",
"author": "smallcase (https://github.com/smallcase)",
"license": "MIT",
"bugs": {
- "url": "https://github.com/smallcase/react-native-simple-biometrics/issues"
+ "url": "https://github.com/kierancrown/react-native-simple-biometrics/issues"
},
- "homepage": "https://github.com/smallcase/react-native-simple-biometrics#readme",
+ "homepage": "https://github.com/kierancrown/react-native-simple-biometrics#readme",
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
@@ -49,11 +49,11 @@
"@arkweid/lefthook": "^0.7.7",
"@babel/eslint-parser": "^7.18.2",
"@commitlint/config-conventional": "^17.0.2",
- "@react-native-community/eslint-config": "^3.0.2",
+ "@react-native-community/eslint-config": "^3.2.0",
"@release-it/conventional-changelog": "^5.0.0",
"@types/jest": "^28.1.2",
"@types/react": "~17.0.21",
- "@types/react-native": "0.68.0",
+ "@types/react-native": "^0.73.0",
"commitlint": "^17.0.2",
"eslint": "^8.4.1",
"eslint-config-prettier": "^8.5.0",
@@ -61,8 +61,8 @@
"jest": "^28.1.1",
"pod-install": "^0.1.0",
"prettier": "^2.0.5",
- "react": "17.0.2",
- "react-native": "0.68.2",
+ "react": "18.3.1",
+ "react-native": "^0.76.0",
"react-native-builder-bob": "^0.18.3",
"release-it": "^15.0.0",
"typescript": "^4.5.2"
diff --git a/react-native-simple-biometrics.podspec b/react-native-simple-biometrics.podspec
index eb3e077..19ee038 100644
--- a/react-native-simple-biometrics.podspec
+++ b/react-native-simple-biometrics.podspec
@@ -1,7 +1,7 @@
require "json"
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
-folly_version = '2021.06.28.00-v2'
+folly_version = '2024.01.01.00'
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
Pod::Spec.new do |s|
@@ -13,7 +13,7 @@ Pod::Spec.new do |s|
s.authors = package["author"]
s.platforms = { :ios => "10.0" }
- s.source = { :git => "https://github.com/smallcase/react-native-simple-biometrics.git", :tag => "#{s.version}" }
+ s.source = { :git => "https://github.com/kierancrown/react-native-simple-biometrics.git", :tag => "#{s.version}" }
s.source_files = "ios/**/*.{h,m,mm}"
diff --git a/src/index.tsx b/src/index.tsx
index 1f688e0..4c77e4a 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -32,9 +32,19 @@ const requestBioAuth = (
return RNBiometricsNative.requestBioAuth(promptTitle, promptMessage);
};
+/**
+ * Get the type of biometric authentication available on the device
+ */
+const getBiometryType = (): Promise<
+ 'Fingerprint' | 'Face' | 'None' | 'Unknown'
+> => {
+ return RNBiometricsNative.getBiometryType();
+};
+
const RNBiometrics = {
requestBioAuth,
canAuthenticate,
+ getBiometryType,
};
export default RNBiometrics;