From ba156a85120f9ee6722fc8dd8c2d8e69f4b8f8f7 Mon Sep 17 00:00:00 2001 From: dankito Date: Thu, 19 Sep 2024 01:29:24 +0200 Subject: [PATCH] Showing an error message if biometric authentication fails --- .../BiometricAuthenticationButton.kt | 3 ++- .../banking/ui/config/Internationalization.kt | 2 ++ .../banking/ui/dialogs/ApplicationErrorDialog.kt | 3 ++- .../net/codinux/banking/ui/dialogs/ErrorDialog.kt | 12 ++++++++++-- .../banking/ui/model/error/ErroneousAction.kt | 4 +++- .../net/codinux/banking/ui/screens/LoginScreen.kt | 3 ++- .../banking/ui/service/AuthenticationService.kt | 13 +++++++++++++ 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/authentification/BiometricAuthenticationButton.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/authentification/BiometricAuthenticationButton.kt index 9ea7547..b9e3e64 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/authentification/BiometricAuthenticationButton.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/composables/authentification/BiometricAuthenticationButton.kt @@ -10,12 +10,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import net.codinux.banking.ui.model.AuthenticationResult import net.codinux.banking.ui.service.AuthenticationService +import net.codinux.banking.ui.service.safelyAuthenticateWithBiometrics @Composable fun BiometricAuthenticationButton(authenticationResult: (AuthenticationResult) -> Unit) { 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)) } } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Internationalization.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Internationalization.kt index c655760..1348fba 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Internationalization.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/config/Internationalization.kt @@ -13,6 +13,8 @@ object Internationalization { const val ErrorTransferMoney = "Überweisung konnte nicht ausgeführt werden" + const val ErrorBiometricAuthentication = "Biometrische Authentifizierung fehlgeschlagen" + fun getTextForActionRequiringTan(action: ActionRequiringTan): String = when (action) { ActionRequiringTan.GetAnonymousBankInfo, diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ApplicationErrorDialog.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ApplicationErrorDialog.kt index 42d5380..e1900d1 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ApplicationErrorDialog.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ApplicationErrorDialog.kt @@ -11,9 +11,10 @@ fun ApplicationErrorDialog(error: ApplicationError, onDismiss: (() -> Unit)? = n ErroneousAction.AddAccount -> Internationalization.ErrorAddAccount ErroneousAction.UpdateAccountTransactions -> Internationalization.ErrorUpdateAccountTransactions ErroneousAction.TransferMoney -> Internationalization.ErrorTransferMoney + ErroneousAction.BiometricAuthentication -> Internationalization.ErrorBiometricAuthentication } // add exception stacktrace? - ErrorDialog(error.errorMessage, title, onDismiss = onDismiss) + ErrorDialog(error.errorMessage, title, error.exception, onDismiss = onDismiss) } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt index 047668e..912c047 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/dialogs/ErrorDialog.kt @@ -7,23 +7,31 @@ import androidx.compose.material.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier 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.config.Colors -import net.codinux.banking.ui.config.Style +import net.codinux.banking.ui.extensions.verticalScroll @Composable fun ErrorDialog( text: String, title: String? = null, + exception: Throwable? = null, confirmButtonText: String = "OK", onDismiss: (() -> Unit)? = null ) { + val effectiveText = if (exception == null) text else { + "$text\r\n\r\nFehlermeldung:\r\n${exception.stackTraceToString()}" + } + + AlertDialog( - text = { Text(text) }, + text = { Text(effectiveText, Modifier.verticalScroll()) }, title = { title?.let { HeaderText(title, Modifier.fillMaxWidth(), TextAlign.Center) } }, + properties = if (exception == null) DialogProperties() else DialogProperties(usePlatformDefaultWidth = false), onDismissRequest = { onDismiss?.invoke() }, confirmButton = { Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.End) { diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/model/error/ErroneousAction.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/model/error/ErroneousAction.kt index 6f1fef5..c7ea13c 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/model/error/ErroneousAction.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/model/error/ErroneousAction.kt @@ -5,5 +5,7 @@ enum class ErroneousAction { UpdateAccountTransactions, - TransferMoney + TransferMoney, + + BiometricAuthentication } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/LoginScreen.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/LoginScreen.kt index f609562..b248a3c 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/LoginScreen.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/screens/LoginScreen.kt @@ -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.AppSettings import net.codinux.banking.ui.service.AuthenticationService +import net.codinux.banking.ui.service.safelyAuthenticateWithBiometrics import org.jetbrains.compose.resources.imageResource @Composable @@ -105,7 +106,7 @@ fun LoginScreen(appSettings: AppSettings, onLoginSuccess: () -> Unit) { LaunchedEffect(appSettings.authenticationMethod) { if (appSettings.authenticationMethod == AppAuthenticationMethod.Biometric) { - AuthenticationService.authenticateWithBiometrics { result -> + AuthenticationService.safelyAuthenticateWithBiometrics { result -> checkBiometricLoginResult(result) } } diff --git a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/AuthenticationService.kt b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/AuthenticationService.kt index 42134c9..10ebbc8 100644 --- a/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/AuthenticationService.kt +++ b/composeApp/src/commonMain/kotlin/net/codinux/banking/ui/service/AuthenticationService.kt @@ -1,6 +1,9 @@ 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.error.ErroneousAction +import net.codinux.log.Log expect object AuthenticationService { @@ -13,4 +16,14 @@ expect object AuthenticationService { 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) + } } \ No newline at end of file