From b6b9e62374d50f66bcb28886a7e128d8a02be316 Mon Sep 17 00:00:00 2001 From: Davis Wolfermann Date: Wed, 26 Aug 2026 21:58:32 +0200 Subject: [PATCH 1/2] fix(autofill): abort autofill when biometric is canceled --- .../presentation/activity/AutofillActivity.kt | 2 +- .../presentation/activity/AutofillViewModel.kt | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillActivity.kt b/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillActivity.kt index d058c0053..8304b6992 100644 --- a/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillActivity.kt +++ b/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillActivity.kt @@ -99,7 +99,7 @@ internal class AutofillActivity : FragmentActivity() { }.onSuccess { viewModel.onBiometricLoginSucceeded() }.onFailure { - viewModel.onBiometricLoginFailed() + viewModel.onBiometricLoginFailed(it) } } diff --git a/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillViewModel.kt b/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillViewModel.kt index 2a676f315..9d4cc3de0 100644 --- a/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillViewModel.kt +++ b/feature/autofill/src/main/kotlin/de/davis/keygo/feature/autofill/presentation/activity/AutofillViewModel.kt @@ -5,6 +5,7 @@ import androidx.core.util.PatternsCompat import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import de.davis.keygo.core.identity.domain.model.UnlockError import de.davis.keygo.core.item.domain.alias.ItemId import de.davis.keygo.core.item.domain.model.Login import de.davis.keygo.core.item.domain.repository.ItemRepository @@ -15,6 +16,7 @@ import de.davis.keygo.core.security.domain.crypto.CryptographicScopeProvider import de.davis.keygo.core.security.domain.crypto.decrypt import de.davis.keygo.core.security.domain.crypto.model.WrappedVaultKeyInformation import de.davis.keygo.core.security.domain.crypto.wrappedItemKeyInformation +import de.davis.keygo.core.security.domain.model.BiometricAuthError import de.davis.keygo.core.util.getOrNull import de.davis.keygo.feature.autofill.domain.usecase.AddRegistrableDomainsToLoginUseCase import de.davis.keygo.feature.autofill.domain.usecase.DoesItemHaveDomainReferencesUseCase @@ -148,9 +150,18 @@ internal class AutofillViewModel( biometricChannel.send(AutofillBiometricRequest.UnlockItem(itemName)) } - fun onBiometricLoginFailed() { + fun onBiometricLoginFailed(error: UnlockError) { viewModelScope.launch { - _uiState.update { it.copy(request = Request.JustAuthenticateWithPwd) } + when(error) { + is UnlockError.BiometricFailed -> { + when(error.error) { + BiometricAuthError.Canceled -> eventChannel.send(AutofillEvent.Abort) + else -> _uiState.update { it.copy(request = Request.JustAuthenticateWithPwd) } + } + } + + else -> _uiState.update { it.copy(request = Request.JustAuthenticateWithPwd) } + } } } From f429f78e436b2ac9e15e42c8aad0ab9858424b53 Mon Sep 17 00:00:00 2001 From: Davis Wolfermann Date: Wed, 26 Aug 2026 21:58:45 +0200 Subject: [PATCH 2/2] doc(autofill): add decline doc --- .../davis/keygo/core/security/domain/model/BiometricAuthError.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/security/src/main/kotlin/de/davis/keygo/core/security/domain/model/BiometricAuthError.kt b/core/security/src/main/kotlin/de/davis/keygo/core/security/domain/model/BiometricAuthError.kt index ab2434376..25cbbae0b 100644 --- a/core/security/src/main/kotlin/de/davis/keygo/core/security/domain/model/BiometricAuthError.kt +++ b/core/security/src/main/kotlin/de/davis/keygo/core/security/domain/model/BiometricAuthError.kt @@ -2,6 +2,7 @@ package de.davis.keygo.core.security.domain.model sealed interface BiometricAuthError { + /** User canceled the prompt by pressing the negative button. */ data object Declined : BiometricAuthError data object LockedOut : BiometricAuthError data object Canceled : BiometricAuthError