Force sign out if PIN code store is corrupted.

This commit is contained in:
Benoit Marty 2026-05-06 10:36:00 +02:00 committed by Benoit Marty
parent 95c182595c
commit 0124787a4d
4 changed files with 18 additions and 8 deletions

View file

@ -41,8 +41,8 @@ class DefaultPinCodeManager(
return secretKeyRepository.hasKey(SECRET_KEY_ALIAS) return secretKeyRepository.hasKey(SECRET_KEY_ALIAS)
} }
override suspend fun getPinCodeSize(): Int { override suspend fun getPinCodeSize(): Int? {
val encryptedPinCode = lockScreenStore.getEncryptedCode() ?: return 0 val encryptedPinCode = lockScreenStore.getEncryptedCode() ?: return null
val secretKey = secretKeyRepository.getOrCreateKey(SECRET_KEY_ALIAS, false) val secretKey = secretKeyRepository.getOrCreateKey(SECRET_KEY_ALIAS, false)
val decryptedPinCode = encryptionDecryptionService.decrypt(secretKey, EncryptionResult.fromBase64(encryptedPinCode)) val decryptedPinCode = encryptionDecryptionService.decrypt(secretKey, EncryptionResult.fromBase64(encryptedPinCode))
return decryptedPinCode.size return decryptedPinCode.size

View file

@ -51,9 +51,9 @@ interface PinCodeManager {
fun hasPinCode(): Flow<Boolean> fun hasPinCode(): Flow<Boolean>
/** /**
* @return the size of the saved pin code. * @return the size of the saved pin code. Return null if no pin code is saved.
*/ */
suspend fun getPinCodeSize(): Int suspend fun getPinCodeSize(): Int?
/** /**
* Creates a new encrypted pin code. * Creates a new encrypted pin code.

View file

@ -69,7 +69,13 @@ class PinUnlockPresenter(
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
suspend { suspend {
val pinCodeSize = pinCodeManager.getPinCodeSize() val pinCodeSize = pinCodeManager.getPinCodeSize()
PinEntry.createEmpty(pinCodeSize) if (pinCodeSize == null) {
// No pin code set, deleted store? Force sign out
showSignOutPrompt = true
throw Exception("No pin code size found")
} else {
PinEntry.createEmpty(pinCodeSize)
}
}.runCatchingUpdatingState(pinEntryState) }.runCatchingUpdatingState(pinEntryState)
} }
LaunchedEffect(biometricUnlock) { LaunchedEffect(biometricUnlock) {

View file

@ -25,9 +25,13 @@ data class PinUnlockState(
val biometricUnlockResult: BiometricAuthenticator.AuthenticationResult?, val biometricUnlockResult: BiometricAuthenticator.AuthenticationResult?,
val eventSink: (PinUnlockEvents) -> Unit val eventSink: (PinUnlockEvents) -> Unit
) { ) {
val isSignOutPromptCancellable = when (remainingAttempts) { val isSignOutPromptCancellable = if (pinEntry.isFailure()) {
is AsyncData.Success -> remainingAttempts.data > 0 false
else -> true } else {
when (remainingAttempts) {
is AsyncData.Success -> remainingAttempts.data > 0
else -> true
}
} }
val biometricUnlockErrorMessage = when { val biometricUnlockErrorMessage = when {