Showing an error message if biometric authentication fails

This commit is contained in:
dankito 2024-09-19 01:29:24 +02:00
parent 41c2b89c34
commit ba156a8512
7 changed files with 34 additions and 6 deletions

View File

@ -10,12 +10,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import net.codinux.banking.ui.model.AuthenticationResult import net.codinux.banking.ui.model.AuthenticationResult
import net.codinux.banking.ui.service.AuthenticationService import net.codinux.banking.ui.service.AuthenticationService
import net.codinux.banking.ui.service.safelyAuthenticateWithBiometrics
@Composable @Composable
fun BiometricAuthenticationButton(authenticationResult: (AuthenticationResult) -> Unit) { fun BiometricAuthenticationButton(authenticationResult: (AuthenticationResult) -> Unit) {
Row(Modifier.fillMaxWidth().padding(horizontal = 16.dp), horizontalArrangement = Arrangement.Center) { Row(Modifier.fillMaxWidth().padding(horizontal = 16.dp), horizontalArrangement = Arrangement.Center) {
Button({ AuthenticationService.authenticateWithBiometrics(authenticationResult) }, enabled = AuthenticationService.supportsBiometricAuthentication) { Button({ AuthenticationService.safelyAuthenticateWithBiometrics(authenticationResult) }, enabled = AuthenticationService.supportsBiometricAuthentication) {
Icon(Icons.Outlined.Fingerprint, "Sich mittels Biometrie authentifizieren", Modifier.size(84.dp)) Icon(Icons.Outlined.Fingerprint, "Sich mittels Biometrie authentifizieren", Modifier.size(84.dp))
} }
} }

View File

@ -13,6 +13,8 @@ object Internationalization {
const val ErrorTransferMoney = "Überweisung konnte nicht ausgeführt werden" const val ErrorTransferMoney = "Überweisung konnte nicht ausgeführt werden"
const val ErrorBiometricAuthentication = "Biometrische Authentifizierung fehlgeschlagen"
fun getTextForActionRequiringTan(action: ActionRequiringTan): String = when (action) { fun getTextForActionRequiringTan(action: ActionRequiringTan): String = when (action) {
ActionRequiringTan.GetAnonymousBankInfo, ActionRequiringTan.GetAnonymousBankInfo,

View File

@ -11,9 +11,10 @@ fun ApplicationErrorDialog(error: ApplicationError, onDismiss: (() -> Unit)? = n
ErroneousAction.AddAccount -> Internationalization.ErrorAddAccount ErroneousAction.AddAccount -> Internationalization.ErrorAddAccount
ErroneousAction.UpdateAccountTransactions -> Internationalization.ErrorUpdateAccountTransactions ErroneousAction.UpdateAccountTransactions -> Internationalization.ErrorUpdateAccountTransactions
ErroneousAction.TransferMoney -> Internationalization.ErrorTransferMoney ErroneousAction.TransferMoney -> Internationalization.ErrorTransferMoney
ErroneousAction.BiometricAuthentication -> Internationalization.ErrorBiometricAuthentication
} }
// add exception stacktrace? // add exception stacktrace?
ErrorDialog(error.errorMessage, title, onDismiss = onDismiss) ErrorDialog(error.errorMessage, title, error.exception, onDismiss = onDismiss)
} }

View File

@ -7,23 +7,31 @@ import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.window.DialogProperties
import net.codinux.banking.ui.composables.text.HeaderText import net.codinux.banking.ui.composables.text.HeaderText
import net.codinux.banking.ui.config.Colors import net.codinux.banking.ui.config.Colors
import net.codinux.banking.ui.config.Style import net.codinux.banking.ui.extensions.verticalScroll
@Composable @Composable
fun ErrorDialog( fun ErrorDialog(
text: String, text: String,
title: String? = null, title: String? = null,
exception: Throwable? = null,
confirmButtonText: String = "OK", confirmButtonText: String = "OK",
onDismiss: (() -> Unit)? = null onDismiss: (() -> Unit)? = null
) { ) {
val effectiveText = if (exception == null) text else {
"$text\r\n\r\nFehlermeldung:\r\n${exception.stackTraceToString()}"
}
AlertDialog( AlertDialog(
text = { Text(text) }, text = { Text(effectiveText, Modifier.verticalScroll()) },
title = { title?.let { title = { title?.let {
HeaderText(title, Modifier.fillMaxWidth(), TextAlign.Center) HeaderText(title, Modifier.fillMaxWidth(), TextAlign.Center)
} }, } },
properties = if (exception == null) DialogProperties() else DialogProperties(usePlatformDefaultWidth = false),
onDismissRequest = { onDismiss?.invoke() }, onDismissRequest = { onDismiss?.invoke() },
confirmButton = { confirmButton = {
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) { Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) {

View File

@ -5,5 +5,7 @@ enum class ErroneousAction {
UpdateAccountTransactions, UpdateAccountTransactions,
TransferMoney TransferMoney,
BiometricAuthentication
} }

View File

@ -22,6 +22,7 @@ import net.codinux.banking.ui.model.AuthenticationResult
import net.codinux.banking.ui.model.settings.AppAuthenticationMethod import net.codinux.banking.ui.model.settings.AppAuthenticationMethod
import net.codinux.banking.ui.model.settings.AppSettings import net.codinux.banking.ui.model.settings.AppSettings
import net.codinux.banking.ui.service.AuthenticationService import net.codinux.banking.ui.service.AuthenticationService
import net.codinux.banking.ui.service.safelyAuthenticateWithBiometrics
import org.jetbrains.compose.resources.imageResource import org.jetbrains.compose.resources.imageResource
@Composable @Composable
@ -105,7 +106,7 @@ fun LoginScreen(appSettings: AppSettings, onLoginSuccess: () -> Unit) {
LaunchedEffect(appSettings.authenticationMethod) { LaunchedEffect(appSettings.authenticationMethod) {
if (appSettings.authenticationMethod == AppAuthenticationMethod.Biometric) { if (appSettings.authenticationMethod == AppAuthenticationMethod.Biometric) {
AuthenticationService.authenticateWithBiometrics { result -> AuthenticationService.safelyAuthenticateWithBiometrics { result ->
checkBiometricLoginResult(result) checkBiometricLoginResult(result)
} }
} }

View File

@ -1,6 +1,9 @@
package net.codinux.banking.ui.service package net.codinux.banking.ui.service
import net.codinux.banking.ui.config.DI
import net.codinux.banking.ui.model.AuthenticationResult import net.codinux.banking.ui.model.AuthenticationResult
import net.codinux.banking.ui.model.error.ErroneousAction
import net.codinux.log.Log
expect object AuthenticationService { expect object AuthenticationService {
@ -13,4 +16,14 @@ expect object AuthenticationService {
fun authenticateWithBiometrics(authenticationResult: (AuthenticationResult) -> Unit) fun authenticateWithBiometrics(authenticationResult: (AuthenticationResult) -> Unit)
}
fun AuthenticationService.safelyAuthenticateWithBiometrics(authenticationResult: (AuthenticationResult) -> Unit) {
try {
this.authenticateWithBiometrics(authenticationResult)
} catch (e: Throwable) {
Log.error(e) { "Could not authenticate with Biometrics" }
DI.uiState.applicationErrorOccurred(ErroneousAction.BiometricAuthentication, "Beim Login mit Fingerabdruck / Gesichtsscan ist etwas fehlgeschlagen, was nicht fehlschlagen sollte. Die folgende Fehlermeldung wird Ihnen vermutlich nichts sagen. Am besten informieren Sie die Entwickler (die faulen Säcke), z. B. mit einem Screenshot dieser Fehlermeldung, damit diese sich darum kümmern.", e)
}
} }