diff --git a/README.md b/README.md index 86f2c5d..633ad52 100755 --- a/README.md +++ b/README.md @@ -43,13 +43,13 @@ project build.gradle ```groovy dependencies { - commonMainApi("dev.icerock.moko:biometry:0.3.0") + commonMainApi("dev.icerock.moko:biometry:0.4.0") // Compose Multiplatform - commonMainApi("dev.icerock.moko:biometry-compose:0.3.0") + commonMainApi("dev.icerock.moko:biometry-compose:0.4.0") // Jetpack Compose (only for android, if you don't use multiplatform) - implementation("dev.icerock.moko:biometry-compose:0.3.0") + implementation("dev.icerock.moko:biometry-compose:0.4.0") } ``` @@ -69,7 +69,8 @@ class SampleViewModel( val isSuccess = biometryAuthenticator.checkBiometryAuthentication( requestTitle = "Biometry".desc(), requestReason = "Just for test".desc(), - failureButtonText = "Oops".desc() + failureButtonText = "Oops".desc(), + allowDeviceCredentials = false // true - if biometric permission is not granted user can authorise by device creds ) if (isSuccess) { diff --git a/biometry/src/androidMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt b/biometry/src/androidMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt index 718c2f7..c97421b 100644 --- a/biometry/src/androidMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt +++ b/biometry/src/androidMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt @@ -42,7 +42,8 @@ actual class BiometryAuthenticator( actual suspend fun checkBiometryAuthentication( requestTitle: StringDesc, requestReason: StringDesc, - failureButtonText: StringDesc + failureButtonText: StringDesc, + allowDeviceCredentials: Boolean ): Boolean { val resolverFragment: ResolverFragment = getResolverFragment() @@ -52,7 +53,7 @@ actual class BiometryAuthenticator( requestTitle = requestTitle, requestReason = requestReason, failureButtonText = failureButtonText, - credentialAllowed = true + credentialAllowed = allowDeviceCredentials ) { if (!resumed) { continuation.resumeWith(it) diff --git a/biometry/src/commonMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt b/biometry/src/commonMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt index 2a897ff..539429d 100644 --- a/biometry/src/commonMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt +++ b/biometry/src/commonMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt @@ -15,6 +15,8 @@ expect class BiometryAuthenticator { * @param requestReason - Text describing the reason for confirmation via biometrics * @param failureButtonText - Text of the button to go to the backup verification method in * case of unsuccessful biometrics recognition + * @param allowDeviceCredentials - Boolean value of device credentials availability, + * if biometric permission is not granted user can authorise by device passcode * * @throws Exception if authentication failed * @@ -24,7 +26,8 @@ expect class BiometryAuthenticator { suspend fun checkBiometryAuthentication( requestTitle: StringDesc, requestReason: StringDesc, - failureButtonText: StringDesc + failureButtonText: StringDesc, + allowDeviceCredentials: Boolean = true ): Boolean /** diff --git a/biometry/src/iosMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt b/biometry/src/iosMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt index 9ff1d1c..23c2bb4 100644 --- a/biometry/src/iosMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt +++ b/biometry/src/iosMain/kotlin/dev/icerock/moko/biometry/BiometryAuthenticator.kt @@ -19,15 +19,22 @@ actual class BiometryAuthenticator constructor() { actual suspend fun checkBiometryAuthentication( requestTitle: StringDesc, requestReason: StringDesc, - failureButtonText: StringDesc + failureButtonText: StringDesc, + allowDeviceCredentials: Boolean ): Boolean { val laContext = LAContext() laContext.setLocalizedFallbackTitle(failureButtonText.localized()) + val policy = if (allowDeviceCredentials) { + LAPolicyDeviceOwnerAuthentication + } else { + LAPolicyDeviceOwnerAuthenticationWithBiometrics + } + val (canEvaluate: Boolean?, error: NSError?) = memScoped { val p = alloc>() val canEvaluate: Boolean? = runCatching { - laContext.canEvaluatePolicy(LAPolicyDeviceOwnerAuthentication, error = p.ptr) + laContext.canEvaluatePolicy(policy, error = p.ptr) }.getOrNull() canEvaluate to p.value } @@ -37,7 +44,7 @@ actual class BiometryAuthenticator constructor() { return callbackToCoroutine { callback -> laContext.evaluatePolicy( - policy = LAPolicyDeviceOwnerAuthentication, + policy = policy, localizedReason = requestReason.localized(), reply = mainContinuation { result: Boolean, error: NSError? -> callback(result, error) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cb10cb2..71b08ee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ coroutinesVersion = "1.6.4" composeJetBrainsVersion = "1.3.1" mokoResourcesVersion = "0.21.1" mokoMvvmVersion = "0.16.0" -mokoBiometryVersion = "0.3.0" +mokoBiometryVersion = "0.4.0" [libraries] appCompat = { module = "androidx.appcompat:appcompat", version.ref = "androidAppCompatVersion" }