From 7f8592c0078c83a821d89a2af8890d771b6ebf54 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 8 Dec 2025 19:20:12 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../tap/di/domain/HotWalletDomainModule.kt | 7 +++ .../hotwallet/IsAccessCodeSimpleUseCase.kt | 13 ++++++ .../hotwallet/accesscode/AccessCodeModel.kt | 43 ++++++++++++++++--- 3 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 domain/hot-wallet/src/main/kotlin/com/tangem/domain/hotwallet/IsAccessCodeSimpleUseCase.kt diff --git a/app/src/main/java/com/tangem/tap/di/domain/HotWalletDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/HotWalletDomainModule.kt index 6eb397fb4e..8c8404b2d3 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/HotWalletDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/HotWalletDomainModule.kt @@ -2,6 +2,7 @@ package com.tangem.tap.di.domain import com.tangem.domain.hotwallet.GetAccessCodeSkippedUseCase import com.tangem.domain.hotwallet.IsHotWalletCreationSupported +import com.tangem.domain.hotwallet.IsAccessCodeSimpleUseCase import com.tangem.domain.hotwallet.SetAccessCodeSkippedUseCase import com.tangem.domain.hotwallet.repository.HotWalletRepository import dagger.Module @@ -26,6 +27,12 @@ internal object HotWalletDomainModule { return SetAccessCodeSkippedUseCase(hotWalletRepository) } + @Provides + @Singleton + fun provideIsAccessCodeSimpleUseCase(): IsAccessCodeSimpleUseCase { + return IsAccessCodeSimpleUseCase() + } + @Provides @Singleton fun provideIsWalletCreationSupportedUseCase( diff --git a/domain/hot-wallet/src/main/kotlin/com/tangem/domain/hotwallet/IsAccessCodeSimpleUseCase.kt b/domain/hot-wallet/src/main/kotlin/com/tangem/domain/hotwallet/IsAccessCodeSimpleUseCase.kt new file mode 100644 index 0000000000..04751ad562 --- /dev/null +++ b/domain/hot-wallet/src/main/kotlin/com/tangem/domain/hotwallet/IsAccessCodeSimpleUseCase.kt @@ -0,0 +1,13 @@ +package com.tangem.domain.hotwallet + +class IsAccessCodeSimpleUseCase { + operator fun invoke(accessCode: String): Boolean { + return isSequential(accessCode) || isRepeatedCharacters(accessCode) + } + + fun isSequential(code: String): Boolean = code.length > 1 && + (code.zipWithNext().all { it.second == it.first + 1 } || + code.zipWithNext().all { it.second == it.first - 1 }) + + fun isRepeatedCharacters(code: String): Boolean = code.isNotEmpty() && code.all { it == code.first() } +} \ No newline at end of file diff --git a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt index 93c0b75006..595dff3477 100644 --- a/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt +++ b/features/hot-wallet/impl/src/main/kotlin/com/tangem/features/hotwallet/accesscode/AccessCodeModel.kt @@ -11,6 +11,7 @@ import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.message.DialogMessage import com.tangem.core.ui.message.EventMessageAction import com.tangem.domain.common.wallets.UserWalletsListRepository +import com.tangem.domain.hotwallet.IsAccessCodeSimpleUseCase import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.settings.CanUseBiometryUseCase @@ -56,6 +57,7 @@ internal class AccessCodeModel @Inject constructor( private val shouldShowAskBiometryUseCase: ShouldShowAskBiometryUseCase, private val setAskBiometryShownUseCase: SetAskBiometryShownUseCase, private val canUseBiometryUseCase: CanUseBiometryUseCase, + private val isAccessCodeSimpleUseCase: IsAccessCodeSimpleUseCase, private val uiMessageSender: UiMessageSender, ) : Model() { @@ -117,16 +119,45 @@ internal class AccessCodeModel @Inject constructor( modelScope.launch { delay(timeMillis = SUCCESS_DISPLAY_DURATION_MS) - params.callbacks.onNewAccessCodeInput(params.userWalletId, uiState.value.accessCode) - - uiState.update { currentState -> - currentState.copy( - accessCode = "", - ) + if (isAccessCodeSimpleUseCase(uiState.value.accessCode)) { + showSimpleAccessCodeDialog() + } else { + setNewCode() } } } + private fun setNewCode() { + params.callbacks.onNewAccessCodeInput(params.userWalletId, uiState.value.accessCode) + + uiState.update { currentState -> + currentState.copy( + accessCode = "", + ) + } + } + + private fun showSimpleAccessCodeDialog() { + uiMessageSender.send( + DialogMessage( + title = resourceReference(R.string.access_code_alert_validation_title), + message = resourceReference(R.string.access_code_alert_validation_description), + firstAction = EventMessageAction( + title = resourceReference(R.string.access_code_alert_validation_cancel), + onClick = { + uiState.update { currentState -> + currentState.copy(onAccessCodeChange = ::onAccessCodeChange) + } + }, + ), + secondAction = EventMessageAction( + title = resourceReference(R.string.access_code_alert_validation_ok), + onClick = ::setNewCode, + ), + ), + ) + } + private suspend fun showErrorAndReset() { uiState.update { currentState -> currentState.copy(