mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
feat: Add biometric authentication check
This commit is contained in:
parent
bf84396a86
commit
a73fc6c48f
@ -553,16 +553,8 @@ data class NotificationSettings(
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class AppLockSettings {
|
class AppLockSettings {
|
||||||
|
// If the object is present, biometric authentication is enabled.
|
||||||
|
// To disable biometric authentication, set the instance to null.
|
||||||
val isEnabled
|
val isEnabled
|
||||||
get() = true
|
get() = true
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun getDefaultInstance(): AppLockSettings = AppLockSettings()
|
|
||||||
|
|
||||||
fun isSupported(context: Context): Boolean {
|
|
||||||
val biometricManager = BiometricManager.from(context)
|
|
||||||
when (biometricManager.canAuthenticate(Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL)) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package app.myzel394.alibi.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.biometric.BiometricManager
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.biometric.BiometricPrompt
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
|
import kotlinx.coroutines.CompletableDeferred
|
||||||
|
|
||||||
|
class AppLockHelper {
|
||||||
|
enum class SupportType {
|
||||||
|
AVAILABLE,
|
||||||
|
UNAVAILABLE,
|
||||||
|
NONE_ENROLLED,
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun isSupported(context: Context): SupportType {
|
||||||
|
val biometricManager = BiometricManager.from(context)
|
||||||
|
when (biometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.DEVICE_CREDENTIAL)) {
|
||||||
|
BiometricManager.BIOMETRIC_SUCCESS -> return SupportType.AVAILABLE
|
||||||
|
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> return SupportType.NONE_ENROLLED
|
||||||
|
|
||||||
|
else -> return SupportType.UNAVAILABLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun authenticate(
|
||||||
|
context: Context,
|
||||||
|
title: String,
|
||||||
|
subtitle: String
|
||||||
|
): CompletableDeferred<Unit> {
|
||||||
|
val deferred = CompletableDeferred<Unit>()
|
||||||
|
|
||||||
|
val mainExecutor = ContextCompat.getMainExecutor(context)
|
||||||
|
val biometricPrompt = BiometricPrompt(
|
||||||
|
context as FragmentActivity,
|
||||||
|
object : BiometricPrompt.AuthenticationCallback() {
|
||||||
|
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||||
|
deferred.completeExceptionally(Exception(errString.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||||
|
deferred.complete(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAuthenticationFailed() {
|
||||||
|
deferred.completeExceptionally(Exception("Authentication failed"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||||
|
.setTitle(title)
|
||||||
|
.setSubtitle(subtitle)
|
||||||
|
.setAllowedAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG or BiometricManager.Authenticators.DEVICE_CREDENTIAL)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
biometricPrompt.authenticate(promptInfo)
|
||||||
|
|
||||||
|
return deferred
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,7 @@ import app.myzel394.alibi.ui.screens.CustomRecordingNotificationsScreen
|
|||||||
import app.myzel394.alibi.ui.screens.SettingsScreen
|
import app.myzel394.alibi.ui.screens.SettingsScreen
|
||||||
import app.myzel394.alibi.ui.screens.WelcomeScreen
|
import app.myzel394.alibi.ui.screens.WelcomeScreen
|
||||||
import app.myzel394.alibi.ui.utils.CameraInfo
|
import app.myzel394.alibi.ui.utils.CameraInfo
|
||||||
|
import app.myzel394.alibi.helpers.AppLockHelper
|
||||||
|
|
||||||
const val SCALE_IN = 1.25f
|
const val SCALE_IN = 1.25f
|
||||||
|
|
||||||
@ -73,34 +74,7 @@ fun Navigation(
|
|||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
val executor = ContextCompat.getMainExecutor(context)
|
AppLockHelper.authenticate(context, "Title", "Subtitle")
|
||||||
val promptInfo = BiometricPrompt.Builder(context)
|
|
||||||
.setTitle("Biometric login for my app")
|
|
||||||
.setSubtitle("Log in using your biometric credential")
|
|
||||||
.setAllowedAuthenticators(
|
|
||||||
BIOMETRIC_STRONG or DEVICE_CREDENTIAL
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
// Prompt appears when user clicks "Log in".
|
|
||||||
// Consider integrating with the keystore to unlock cryptographic operations,
|
|
||||||
// if needed by your app.
|
|
||||||
promptInfo.authenticate(
|
|
||||||
CancellationSignal(),
|
|
||||||
executor,
|
|
||||||
object : BiometricPrompt.AuthenticationCallback() {
|
|
||||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
|
||||||
super.onAuthenticationError(errorCode, errString)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
|
||||||
super.onAuthenticationSucceeded(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAuthenticationFailed() {
|
|
||||||
super.onAuthenticationFailed()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user