diff --git a/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAssertionOptions.kt b/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAssertionOptions.kt index 359533ff9ae..7f19e043f1f 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAssertionOptions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAssertionOptions.kt @@ -16,5 +16,5 @@ data class PasskeyAssertionOptions( @SerialName("rpId") val relyingPartyId: String?, @SerialName("userVerification") - val userVerification: UserVerificationRequirement?, + val userVerification: UserVerificationRequirement = UserVerificationRequirement.PREFERRED, ) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAttestationOptions.kt b/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAttestationOptions.kt index b3576eae61d..8439941b4c7 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAttestationOptions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/autofill/fido2/model/PasskeyAttestationOptions.kt @@ -32,7 +32,7 @@ data class PasskeyAttestationOptions( @SerialName("residentKey") val residentKeyRequirement: ResidentKeyRequirement? = null, @SerialName("userVerification") - val userVerification: UserVerificationRequirement? = null, + val userVerification: UserVerificationRequirement = UserVerificationRequirement.PREFERRED, ) { /** * Enum class representing the types of attachments associated with selection criteria. diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt index 5ac257fba55..cc023483b40 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt @@ -468,12 +468,6 @@ class VaultAddEditViewModel @Inject constructor( UserVerificationRequirement.REQUIRED -> { sendEvent(VaultAddEditEvent.Fido2UserVerification(isRequired = true)) } - - null -> { - // Per WebAuthn spec members should be ignored when invalid. Since the request - // violates spec we display an error and terminate the operation. - showFido2ErrorDialog() - } } } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index 8cb755d0422..a3f9f169b0a 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -657,12 +657,6 @@ class VaultItemListingViewModel @Inject constructor( ), ) } - - null -> { - // Per WebAuthn spec, members should be ignored when invalid. Since the request - // violates spec, we display an error and terminate the operation. - showFido2ErrorDialog() - } } } @@ -1450,10 +1444,6 @@ class VaultItemListingViewModel @Inject constructor( UserVerificationRequirement.REQUIRED -> { sendUserVerificationEvent(isRequired = true, selectedCipher = selectedCipher) } - - null -> { - showFido2ErrorDialog() - } } } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt index dd7cb7abce7..fcb52b26a27 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt @@ -1050,51 +1050,6 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { } } - @Suppress("MaxLineLength") - @Test - fun `in add mode during fido2, SaveClick should show Fido2ErrorDialog when user is not verified and registration user verification option is null`() = - runTest { - val fido2CredentialRequest = createMockFido2CredentialRequest(number = 1) - val stateWithName = createVaultAddItemState( - vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN), - commonContentViewState = createCommonContentViewState( - name = "mockName-1", - ), - ) - .copy(shouldExitOnSave = true) - specialCircumstanceManager.specialCircumstance = - SpecialCircumstance.Fido2Save( - fido2CredentialRequest = fido2CredentialRequest, - ) - every { - fido2CredentialManager.getPasskeyAttestationOptionsOrNull( - requestJson = fido2CredentialRequest.requestJson, - ) - } returns createMockPasskeyAttestationOptions( - number = 1, - userVerificationRequirement = null, - ) - mutableVaultDataFlow.value = DataState.Loaded( - createVaultData(), - ) - val viewModel = createAddVaultItemViewModel( - createSavedStateHandleWithState( - state = stateWithName, - vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN), - ), - ) - - viewModel.trySendAction(VaultAddEditAction.Common.SaveClick) - - assertEquals( - VaultAddEditState.DialogState.Fido2Error( - message = R.string.passkey_operation_failed_because_user_could_not_be_verified - .asText(), - ), - viewModel.stateFlow.value.dialog, - ) - } - @Test fun `in add mode, createCipherInOrganization success should ShowToast and NavigateBack`() = runTest { diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAssertionOptionsTestHelpers.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAssertionOptionsTestHelpers.kt index 6f6448f69d7..f081b16e18f 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAssertionOptionsTestHelpers.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAssertionOptionsTestHelpers.kt @@ -10,7 +10,7 @@ import com.x8bit.bitwarden.data.autofill.fido2.model.UserVerificationRequirement */ fun createMockPasskeyAssertionOptions( number: Int, - userVerificationRequirement: UserVerificationRequirement? = + userVerificationRequirement: UserVerificationRequirement = UserVerificationRequirement.PREFERRED, ) = PasskeyAssertionOptions( challenge = "mockChallenge-$number", diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAttestationOptionsTestHelpers.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAttestationOptionsTestHelpers.kt index eb8149c7bd7..207bc8a4d80 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAttestationOptionsTestHelpers.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/addedit/util/PasskeyAttestationOptionsTestHelpers.kt @@ -11,7 +11,8 @@ import com.x8bit.bitwarden.data.autofill.fido2.model.UserVerificationRequirement @Suppress("MaxLineLength") fun createMockPasskeyAttestationOptions( number: Int, - userVerificationRequirement: UserVerificationRequirement? = null, + userVerificationRequirement: UserVerificationRequirement = + UserVerificationRequirement.PREFERRED, ) = PasskeyAttestationOptions( authenticatorSelection = PasskeyAttestationOptions .AuthenticatorSelectionCriteria(userVerification = userVerificationRequirement), diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt index decd4463947..de32616dc61 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt @@ -2455,69 +2455,6 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { } } - @Suppress("MaxLineLength") - @Test - fun `Fido2AssertionRequest should show error dialog when user is not verified and verification is null`() = - runTest { - val mockAssertionRequest = createMockFido2CredentialAssertionRequest(number = 1) - .copy(cipherId = "mockId-1") - val mockFido2CredentialList = createMockSdkFido2CredentialList(number = 1) - val mockCipherView = createMockCipherView( - number = 1, - fido2Credentials = mockFido2CredentialList, - ) - specialCircumstanceManager.specialCircumstance = SpecialCircumstance.Fido2Assertion( - mockAssertionRequest, - ) - every { authRepository.activeUserId } returns "activeUserId" - every { - fido2CredentialManager.getPasskeyAssertionOptionsOrNull( - mockAssertionRequest.requestJson, - ) - } returns createMockPasskeyAssertionOptions( - number = 1, - userVerificationRequirement = null, - ) - every { - vaultRepository - .ciphersStateFlow - .value - .data - } returns listOf( - createMockCipherView( - number = 1, - fido2Credentials = mockFido2CredentialList, - ), - ) - coEvery { - fido2CredentialManager.authenticateFido2Credential( - userId = "activeUserId", - request = mockAssertionRequest, - selectedCipherView = mockCipherView, - ) - } returns Fido2CredentialAssertionResult.Success(responseJson = "responseJson") - - val viewModel = createVaultItemListingViewModel() - viewModel.eventFlow.test { - assertEquals( - VaultItemListingState.DialogState.Fido2OperationFail( - title = R.string.an_error_has_occurred.asText(), - message = R.string.passkey_operation_failed_because_user_could_not_be_verified - .asText(), - ), - viewModel.stateFlow.value.dialogState, - ) - verify { fido2CredentialManager.isUserVerified } - coVerify(exactly = 0) { - fido2CredentialManager.authenticateFido2Credential( - userId = "activeUserId", - request = mockAssertionRequest, - selectedCipherView = mockCipherView, - ) - } - } - } - @Suppress("MaxLineLength") @Test fun `Fido2AssertionRequest should show error dialog when assertion options are null`() =