diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index ea66f8f8c3..38fec40852 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -94,7 +94,6 @@ import com.x8bit.bitwarden.ui.vault.feature.itemlisting.util.toSendItemType import com.x8bit.bitwarden.ui.vault.feature.itemlisting.util.toVaultItemCipherType import com.x8bit.bitwarden.ui.vault.feature.itemlisting.util.toViewState import com.x8bit.bitwarden.ui.vault.feature.itemlisting.util.updateWithAdditionalDataIfNecessary -import com.x8bit.bitwarden.ui.vault.feature.vault.VaultAction import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterType import com.x8bit.bitwarden.ui.vault.feature.vault.util.toAccountSummaries import com.x8bit.bitwarden.ui.vault.feature.vault.util.toActiveAccountSummary @@ -116,7 +115,6 @@ import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import java.time.Clock import javax.inject.Inject -import kotlin.collections.map /** * Manages [VaultItemListingState], handles [VaultItemListingsAction], @@ -1985,11 +1983,11 @@ class VaultItemListingViewModel @Inject constructor( ) { mutableStateFlow.update { it.copy( - dialogState = when (error) { - is ValidateOriginResult.Error.PrivilegedAppNotAllowed -> { - @Suppress("MaxLineLength") + dialogState = when { + shouldShowTrustPrompt(error) -> { VaultItemListingState.DialogState.TrustPrivilegedAddPrompt( - message = R.string.passkey_operation_failed_because_browser_x_is_not_trusted + message = R.string + .passkey_operation_failed_because_browser_x_is_not_trusted .asText(callingAppInfo.packageName), selectedCipherId = selectedCipherId, ) @@ -2006,6 +2004,10 @@ class VaultItemListingViewModel @Inject constructor( } } + private fun shouldShowTrustPrompt(error: ValidateOriginResult.Error): Boolean = + error is ValidateOriginResult.Error.PrivilegedAppNotAllowed && + featureFlagManager.getFeatureFlag(FlagKey.UserManagedPrivilegedApps) + private fun handleFido2AssertionDataReceive( action: VaultItemListingsAction.Internal.Fido2AssertionDataReceive, ) { diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt index 0bfe8dd8da..24968d9cb6 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt @@ -245,6 +245,9 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { every { getFeatureFlagFlow(FlagKey.RemoveCardPolicy) } returns mutableRemoveCardPolicyFeatureFlow + every { + getFeatureFlag(FlagKey.UserManagedPrivilegedApps) + } returns true } private val initialState = createVaultItemListingState() @@ -2868,7 +2871,7 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { @Suppress("MaxLineLength") @Test - fun `ValidateOriginResult should update dialog state on PrivilegedAppNotAllowed error`() = + fun `ValidateOriginResult should show TrustPrivilegedAddPrompt dialog when feature flag is on`() = runTest { specialCircumstanceManager.specialCircumstance = SpecialCircumstance.ProviderCreateCredential( @@ -2893,6 +2896,36 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { ) } + @Suppress("MaxLineLength") + @Test + fun `ValidateOriginResult should show not show TrustPrivilegedAppPrompt dialog when feature flag is off`() = + runTest { + specialCircumstanceManager.specialCircumstance = + SpecialCircumstance.ProviderCreateCredential( + createCredentialRequest = createMockCreateCredentialRequest(number = 1), + ) + coEvery { + originManager.validateOrigin( + relyingPartyId = DEFAULT_RELYING_PARTY_ID, + callingAppInfo = mockCallingAppInfo, + ) + } returns ValidateOriginResult.Error.PrivilegedAppNotAllowed + every { + featureFlagManager.getFeatureFlag(FlagKey.UserManagedPrivilegedApps) + } returns false + + val viewModel = createVaultItemListingViewModel() + + assertEquals( + VaultItemListingState.DialogState.CredentialManagerOperationFail( + title = R.string.an_error_has_occurred.asText(), + message = R.string.passkey_operation_failed_because_browser_is_not_privileged + .asText(), + ), + viewModel.stateFlow.value.dialogState, + ) + } + @Suppress("MaxLineLength") @Test fun `ValidateOriginResult should update dialog state on PrivilegedAppSignatureNotFound error`() =