mirror of
https://github.com/bitwarden/android.git
synced 2024-11-25 19:06:05 +03:00
[PM-8137] Refactor FIDO 2 credential registration result object (#3445)
This commit is contained in:
parent
c409132825
commit
9b240ddf5f
15 changed files with 270 additions and 91 deletions
|
@ -2,12 +2,12 @@ package com.x8bit.bitwarden.data.autofill.fido2.manager
|
||||||
|
|
||||||
import com.bitwarden.vault.CipherView
|
import com.bitwarden.vault.CipherView
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.PublicKeyCredentialCreationOptions
|
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.PublicKeyCredentialCreationOptions
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
||||||
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for managing FIDO 2 credential creation and authentication.
|
* Responsible for managing FIDO 2 credential registration and authentication.
|
||||||
*/
|
*/
|
||||||
interface Fido2CredentialManager {
|
interface Fido2CredentialManager {
|
||||||
|
|
||||||
|
@ -32,5 +32,5 @@ interface Fido2CredentialManager {
|
||||||
userId: String,
|
userId: String,
|
||||||
fido2CredentialRequest: Fido2CredentialRequest,
|
fido2CredentialRequest: Fido2CredentialRequest,
|
||||||
selectedCipherView: CipherView,
|
selectedCipherView: CipherView,
|
||||||
): Fido2CreateCredentialResult
|
): Fido2RegisterCredentialResult
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.x8bit.bitwarden.data.autofill.fido2.manager
|
package com.x8bit.bitwarden.data.autofill.fido2.manager
|
||||||
|
|
||||||
import androidx.credentials.exceptions.CreateCredentialUnknownException
|
|
||||||
import androidx.credentials.provider.CallingAppInfo
|
import androidx.credentials.provider.CallingAppInfo
|
||||||
import com.bitwarden.fido.ClientData
|
import com.bitwarden.fido.ClientData
|
||||||
import com.bitwarden.sdk.CheckUserResult
|
import com.bitwarden.sdk.CheckUserResult
|
||||||
|
@ -10,8 +9,8 @@ import com.bitwarden.vault.CipherView
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.DigitalAssetLinkResponseJson
|
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.DigitalAssetLinkResponseJson
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.PublicKeyCredentialCreationOptions
|
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.PublicKeyCredentialCreationOptions
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.service.DigitalAssetLinkService
|
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.service.DigitalAssetLinkService
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
||||||
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
||||||
import com.x8bit.bitwarden.data.platform.manager.AssetManager
|
import com.x8bit.bitwarden.data.platform.manager.AssetManager
|
||||||
import com.x8bit.bitwarden.data.platform.util.asFailure
|
import com.x8bit.bitwarden.data.platform.util.asFailure
|
||||||
|
@ -46,15 +45,11 @@ class Fido2CredentialManagerImpl(
|
||||||
userId: String,
|
userId: String,
|
||||||
fido2CredentialRequest: Fido2CredentialRequest,
|
fido2CredentialRequest: Fido2CredentialRequest,
|
||||||
selectedCipherView: CipherView,
|
selectedCipherView: CipherView,
|
||||||
): Fido2CreateCredentialResult {
|
): Fido2RegisterCredentialResult {
|
||||||
val clientData = if (fido2CredentialRequest.callingAppInfo.isOriginPopulated()) {
|
val clientData = if (fido2CredentialRequest.callingAppInfo.isOriginPopulated()) {
|
||||||
fido2CredentialRequest.callingAppInfo.getAppSigningSignatureFingerprint()
|
fido2CredentialRequest.callingAppInfo.getAppSigningSignatureFingerprint()
|
||||||
?.let { ClientData.DefaultWithCustomHash(hash = it) }
|
?.let { ClientData.DefaultWithCustomHash(hash = it) }
|
||||||
?: return Fido2CreateCredentialResult.Error(
|
?: return Fido2RegisterCredentialResult.Error
|
||||||
exception = CreateCredentialUnknownException(
|
|
||||||
errorMessage = "Application contains multiple signing certificates.",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
ClientData.DefaultWithExtraData(
|
ClientData.DefaultWithExtraData(
|
||||||
androidPackageName = fido2CredentialRequest
|
androidPackageName = fido2CredentialRequest
|
||||||
|
@ -82,9 +77,9 @@ class Fido2CredentialManagerImpl(
|
||||||
.map { it.toAndroidAttestationResponse() }
|
.map { it.toAndroidAttestationResponse() }
|
||||||
.mapCatching { json.encodeToString(it) }
|
.mapCatching { json.encodeToString(it) }
|
||||||
.fold(
|
.fold(
|
||||||
onSuccess = { Fido2CreateCredentialResult.Success(it) },
|
onSuccess = { Fido2RegisterCredentialResult.Success(it) },
|
||||||
onFailure = {
|
onFailure = {
|
||||||
Fido2CreateCredentialResult.Error(CreateCredentialUnknownException())
|
Fido2RegisterCredentialResult.Error
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package com.x8bit.bitwarden.data.autofill.fido2.model
|
|
||||||
|
|
||||||
import androidx.credentials.exceptions.CreateCredentialException
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Models the data returned from creating a FIDO 2 credential.
|
|
||||||
*/
|
|
||||||
sealed class Fido2CreateCredentialResult {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Models a successful response for creating a credential.
|
|
||||||
*/
|
|
||||||
data class Success(
|
|
||||||
val registrationResponse: String,
|
|
||||||
) : Fido2CreateCredentialResult()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Models an error response for creating a credential.
|
|
||||||
*/
|
|
||||||
data class Error(
|
|
||||||
val exception: CreateCredentialException,
|
|
||||||
) : Fido2CreateCredentialResult()
|
|
||||||
}
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.x8bit.bitwarden.data.autofill.fido2.model
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Models the data returned from creating a FIDO 2 credential.
|
||||||
|
*/
|
||||||
|
sealed class Fido2RegisterCredentialResult {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the credential has been successfully registered.
|
||||||
|
*/
|
||||||
|
data class Success(
|
||||||
|
val registrationResponse: String,
|
||||||
|
) : Fido2RegisterCredentialResult()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates there was an error and the credential was not registered.
|
||||||
|
*/
|
||||||
|
data object Error : Fido2RegisterCredentialResult()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the user cancelled the request.
|
||||||
|
*/
|
||||||
|
data object Cancelled : Fido2RegisterCredentialResult()
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package com.x8bit.bitwarden.ui.autofill.fido2.manager
|
package com.x8bit.bitwarden.ui.autofill.fido2.manager
|
||||||
|
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A manager for completing the FIDO 2 creation process.
|
* A manager for completing the FIDO 2 creation process.
|
||||||
|
@ -8,7 +8,7 @@ import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
||||||
interface Fido2CompletionManager {
|
interface Fido2CompletionManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Completes the FIDO 2 creation process with the provided [result].
|
* Completes the FIDO 2 registration process with the provided [result].
|
||||||
*/
|
*/
|
||||||
fun completeFido2Create(result: Fido2CreateCredentialResult)
|
fun completeFido2Registration(result: Fido2RegisterCredentialResult)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,10 @@ import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.credentials.CreatePublicKeyCredentialResponse
|
import androidx.credentials.CreatePublicKeyCredentialResponse
|
||||||
|
import androidx.credentials.exceptions.CreateCredentialCancellationException
|
||||||
|
import androidx.credentials.exceptions.CreateCredentialUnknownException
|
||||||
import androidx.credentials.provider.PendingIntentHandler
|
import androidx.credentials.provider.PendingIntentHandler
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,19 +20,19 @@ class Fido2CompletionManagerImpl(
|
||||||
) : Fido2CompletionManager {
|
) : Fido2CompletionManager {
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||||
override fun completeFido2Create(result: Fido2CreateCredentialResult) {
|
override fun completeFido2Registration(result: Fido2RegisterCredentialResult) {
|
||||||
activity.also {
|
activity.also {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
when (result) {
|
when (result) {
|
||||||
is Fido2CreateCredentialResult.Error -> {
|
is Fido2RegisterCredentialResult.Error -> {
|
||||||
PendingIntentHandler
|
PendingIntentHandler
|
||||||
.setCreateCredentialException(
|
.setCreateCredentialException(
|
||||||
intent = intent,
|
intent = intent,
|
||||||
exception = result.exception,
|
exception = CreateCredentialUnknownException(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is Fido2CreateCredentialResult.Success -> {
|
is Fido2RegisterCredentialResult.Success -> {
|
||||||
PendingIntentHandler
|
PendingIntentHandler
|
||||||
.setCreateCredentialResponse(
|
.setCreateCredentialResponse(
|
||||||
intent = intent,
|
intent = intent,
|
||||||
|
@ -39,6 +41,14 @@ class Fido2CompletionManagerImpl(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is Fido2RegisterCredentialResult.Cancelled -> {
|
||||||
|
PendingIntentHandler
|
||||||
|
.setCreateCredentialException(
|
||||||
|
intent = intent,
|
||||||
|
exception = CreateCredentialCancellationException(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it.setResult(Activity.RESULT_OK, intent)
|
it.setResult(Activity.RESULT_OK, intent)
|
||||||
it.finish()
|
it.finish()
|
||||||
|
|
|
@ -112,8 +112,8 @@ fun VaultAddEditScreen(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is VaultAddEditEvent.CompleteFido2Create -> {
|
is VaultAddEditEvent.CompleteFido2Registration -> {
|
||||||
fido2CompletionManager.completeFido2Create(event.result)
|
fido2CompletionManager.completeFido2Registration(event.result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.x8bit.bitwarden.ui.vault.feature.addedit
|
package com.x8bit.bitwarden.ui.vault.feature.addedit
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.credentials.exceptions.CreateCredentialUnknownException
|
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.bitwarden.vault.CipherView
|
import com.bitwarden.vault.CipherView
|
||||||
|
@ -10,8 +9,8 @@ import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||||
import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult
|
import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult
|
||||||
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
||||||
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
|
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
|
||||||
import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager
|
import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager
|
||||||
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
|
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||||
|
@ -379,14 +378,12 @@ class VaultAddEditViewModel @Inject constructor(
|
||||||
?: run {
|
?: run {
|
||||||
sendAction(
|
sendAction(
|
||||||
VaultAddEditAction.Internal.Fido2RegisterCredentialResultReceive(
|
VaultAddEditAction.Internal.Fido2RegisterCredentialResultReceive(
|
||||||
result = Fido2CreateCredentialResult.Error(
|
result = Fido2RegisterCredentialResult.Error,
|
||||||
exception = CreateCredentialUnknownException(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
val result: Fido2CreateCredentialResult =
|
val result: Fido2RegisterCredentialResult =
|
||||||
fido2CredentialManager.registerFido2Credential(
|
fido2CredentialManager.registerFido2Credential(
|
||||||
userId = activeUserId,
|
userId = activeUserId,
|
||||||
fido2CredentialRequest = request,
|
fido2CredentialRequest = request,
|
||||||
|
@ -1356,15 +1353,19 @@ class VaultAddEditViewModel @Inject constructor(
|
||||||
) {
|
) {
|
||||||
clearDialogState()
|
clearDialogState()
|
||||||
when (action.result) {
|
when (action.result) {
|
||||||
is Fido2CreateCredentialResult.Error -> {
|
is Fido2RegisterCredentialResult.Error -> {
|
||||||
sendEvent(VaultAddEditEvent.ShowToast(R.string.an_error_has_occurred.asText()))
|
sendEvent(VaultAddEditEvent.ShowToast(R.string.an_error_has_occurred.asText()))
|
||||||
}
|
}
|
||||||
|
|
||||||
is Fido2CreateCredentialResult.Success -> {
|
is Fido2RegisterCredentialResult.Success -> {
|
||||||
sendEvent(VaultAddEditEvent.ShowToast(R.string.item_updated.asText()))
|
sendEvent(VaultAddEditEvent.ShowToast(R.string.item_updated.asText()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fido2RegisterCredentialResult.Cancelled -> {
|
||||||
|
// no-op: The OS will handle re-displaying the system prompt.
|
||||||
}
|
}
|
||||||
sendEvent(VaultAddEditEvent.CompleteFido2Create(action.result))
|
}
|
||||||
|
sendEvent(VaultAddEditEvent.CompleteFido2Registration(action.result))
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion Internal Type Handlers
|
//endregion Internal Type Handlers
|
||||||
|
@ -1989,12 +1990,12 @@ sealed class VaultAddEditEvent {
|
||||||
) : VaultAddEditEvent()
|
) : VaultAddEditEvent()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Complete the current FIDO 2 credential creation process.
|
* Complete the current FIDO 2 credential registration process.
|
||||||
*
|
*
|
||||||
* @property result the result of FIDO 2 credential creation.
|
* @property result the result of FIDO 2 credential creation.
|
||||||
*/
|
*/
|
||||||
data class CompleteFido2Create(
|
data class CompleteFido2Registration(
|
||||||
val result: Fido2CreateCredentialResult,
|
val result: Fido2RegisterCredentialResult,
|
||||||
) : VaultAddEditEvent()
|
) : VaultAddEditEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2484,7 +2485,7 @@ sealed class VaultAddEditAction {
|
||||||
* Indicates that the FIDO 2 registration result has been received.
|
* Indicates that the FIDO 2 registration result has been received.
|
||||||
*/
|
*/
|
||||||
data class Fido2RegisterCredentialResultReceive(
|
data class Fido2RegisterCredentialResultReceive(
|
||||||
val result: Fido2CreateCredentialResult,
|
val result: Fido2RegisterCredentialResult,
|
||||||
) : Internal()
|
) : Internal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,8 +134,8 @@ fun VaultItemListingScreen(
|
||||||
onNavigateToVaultItemListing(VaultItemListingType.Collection(event.collectionId))
|
onNavigateToVaultItemListing(VaultItemListingType.Collection(event.collectionId))
|
||||||
}
|
}
|
||||||
|
|
||||||
is VaultItemListingEvent.CompleteFido2Create -> {
|
is VaultItemListingEvent.CompleteFido2Registration -> {
|
||||||
fido2CompletionManager.completeFido2Create(event.result)
|
fido2CompletionManager.completeFido2Registration(event.result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package com.x8bit.bitwarden.ui.vault.feature.itemlisting
|
package com.x8bit.bitwarden.ui.vault.feature.itemlisting
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.credentials.exceptions.CreateCredentialUnknownException
|
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.x8bit.bitwarden.R
|
import com.x8bit.bitwarden.R
|
||||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||||
import com.x8bit.bitwarden.data.auth.repository.model.ValidatePasswordResult
|
import com.x8bit.bitwarden.data.auth.repository.model.ValidatePasswordResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
||||||
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
||||||
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManager
|
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManager
|
||||||
import com.x8bit.bitwarden.data.autofill.model.AutofillSelectionData
|
import com.x8bit.bitwarden.data.autofill.model.AutofillSelectionData
|
||||||
|
@ -408,10 +407,8 @@ class VaultItemListingViewModel @Inject constructor(
|
||||||
|
|
||||||
private fun handleDismissFido2ErrorDialogClick() {
|
private fun handleDismissFido2ErrorDialogClick() {
|
||||||
sendEvent(
|
sendEvent(
|
||||||
VaultItemListingEvent.CompleteFido2Create(
|
VaultItemListingEvent.CompleteFido2Registration(
|
||||||
result = Fido2CreateCredentialResult.Error(
|
result = Fido2RegisterCredentialResult.Error,
|
||||||
exception = CreateCredentialUnknownException(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -766,15 +763,19 @@ class VaultItemListingViewModel @Inject constructor(
|
||||||
) {
|
) {
|
||||||
mutableStateFlow.update { it.copy(dialogState = null) }
|
mutableStateFlow.update { it.copy(dialogState = null) }
|
||||||
when (action.result) {
|
when (action.result) {
|
||||||
is Fido2CreateCredentialResult.Error -> {
|
is Fido2RegisterCredentialResult.Error -> {
|
||||||
sendEvent(VaultItemListingEvent.ShowToast(R.string.an_error_has_occurred.asText()))
|
sendEvent(VaultItemListingEvent.ShowToast(R.string.an_error_has_occurred.asText()))
|
||||||
}
|
}
|
||||||
|
|
||||||
is Fido2CreateCredentialResult.Success -> {
|
is Fido2RegisterCredentialResult.Success -> {
|
||||||
sendEvent(VaultItemListingEvent.ShowToast(R.string.item_updated.asText()))
|
sendEvent(VaultItemListingEvent.ShowToast(R.string.item_updated.asText()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Fido2RegisterCredentialResult.Cancelled -> {
|
||||||
|
// no-op: The OS will handle re-displaying the system prompt.
|
||||||
}
|
}
|
||||||
sendEvent(VaultItemListingEvent.CompleteFido2Create(action.result))
|
}
|
||||||
|
sendEvent(VaultItemListingEvent.CompleteFido2Registration(action.result))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleValidateFido2OriginResultReceive(
|
private fun handleValidateFido2OriginResultReceive(
|
||||||
|
@ -1346,8 +1347,8 @@ sealed class VaultItemListingEvent {
|
||||||
*
|
*
|
||||||
* @property result the result of FIDO 2 credential creation.
|
* @property result the result of FIDO 2 credential creation.
|
||||||
*/
|
*/
|
||||||
data class CompleteFido2Create(
|
data class CompleteFido2Registration(
|
||||||
val result: Fido2CreateCredentialResult,
|
val result: Fido2RegisterCredentialResult,
|
||||||
) : VaultItemListingEvent()
|
) : VaultItemListingEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1529,7 +1530,7 @@ sealed class VaultItemListingsAction {
|
||||||
* Indicates that a result for FIDO 2 credential registration has been received.
|
* Indicates that a result for FIDO 2 credential registration has been received.
|
||||||
*/
|
*/
|
||||||
data class Fido2RegisterCredentialResultReceive(
|
data class Fido2RegisterCredentialResultReceive(
|
||||||
val result: Fido2CreateCredentialResult,
|
val result: Fido2RegisterCredentialResult,
|
||||||
) : Internal()
|
) : Internal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.DigitalA
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.PublicKeyCredentialCreationOptions
|
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.model.PublicKeyCredentialCreationOptions
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.service.DigitalAssetLinkService
|
import com.x8bit.bitwarden.data.autofill.fido2.datasource.network.service.DigitalAssetLinkService
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2AttestationResponse
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2AttestationResponse
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
||||||
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.createMockFido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.createMockFido2CredentialRequest
|
||||||
import com.x8bit.bitwarden.data.platform.manager.AssetManager
|
import com.x8bit.bitwarden.data.platform.manager.AssetManager
|
||||||
|
@ -486,7 +486,7 @@ class Fido2CredentialManagerTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
result is Fido2CreateCredentialResult.Error,
|
result is Fido2RegisterCredentialResult.Error,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +530,7 @@ class Fido2CredentialManagerTest {
|
||||||
)
|
)
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
result is Fido2CreateCredentialResult.Error,
|
result is Fido2RegisterCredentialResult.Error,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ import androidx.compose.ui.test.performTextInput
|
||||||
import androidx.compose.ui.test.performTouchInput
|
import androidx.compose.ui.test.performTouchInput
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.bitwarden.vault.UriMatchType
|
import com.bitwarden.vault.UriMatchType
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
|
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView
|
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView
|
||||||
import com.x8bit.bitwarden.ui.autofill.fido2.manager.Fido2CompletionManager
|
import com.x8bit.bitwarden.ui.autofill.fido2.manager.Fido2CompletionManager
|
||||||
|
@ -96,7 +96,7 @@ class VaultAddEditScreenTest : BaseComposeTest() {
|
||||||
every { launchUri(any()) } just runs
|
every { launchUri(any()) } just runs
|
||||||
}
|
}
|
||||||
private val fido2CompletionManager: Fido2CompletionManager = mockk {
|
private val fido2CompletionManager: Fido2CompletionManager = mockk {
|
||||||
every { completeFido2Create(any()) } just runs
|
every { completeFido2Registration(any()) } just runs
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -194,11 +194,11 @@ class VaultAddEditScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `on CompleteFido2Create even should invoke Fido2CompletionManager`() {
|
fun `on CompleteFido2Create even should invoke Fido2CompletionManager`() {
|
||||||
val result = Fido2CreateCredentialResult.Success(
|
val result = Fido2RegisterCredentialResult.Success(
|
||||||
registrationResponse = "mockRegistrationResponse",
|
registrationResponse = "mockRegistrationResponse",
|
||||||
)
|
)
|
||||||
mutableEventFlow.tryEmit(VaultAddEditEvent.CompleteFido2Create(result = result))
|
mutableEventFlow.tryEmit(VaultAddEditEvent.CompleteFido2Registration(result = result))
|
||||||
verify { fido2CompletionManager.completeFido2Create(result) }
|
verify { fido2CompletionManager.completeFido2Registration(result) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.x8bit.bitwarden.ui.vault.feature.addedit
|
package com.x8bit.bitwarden.ui.vault.feature.addedit
|
||||||
|
|
||||||
import android.content.pm.SigningInfo
|
import android.content.pm.SigningInfo
|
||||||
import androidx.credentials.exceptions.CreateCredentialUnknownException
|
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import app.cash.turbine.turbineScope
|
import app.cash.turbine.turbineScope
|
||||||
|
@ -17,8 +16,8 @@ import com.x8bit.bitwarden.data.auth.repository.model.Organization
|
||||||
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||||
import com.x8bit.bitwarden.data.auth.repository.model.VaultUnlockType
|
import com.x8bit.bitwarden.data.auth.repository.model.VaultUnlockType
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CreateCredentialResult
|
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
||||||
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.autofill.model.AutofillSaveItem
|
import com.x8bit.bitwarden.data.autofill.model.AutofillSaveItem
|
||||||
import com.x8bit.bitwarden.data.autofill.model.AutofillSelectionData
|
import com.x8bit.bitwarden.data.autofill.model.AutofillSelectionData
|
||||||
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
|
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
|
||||||
|
@ -725,7 +724,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
||||||
vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN),
|
vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val mockCreateResult = Fido2CreateCredentialResult.Success(
|
val mockCreateResult = Fido2RegisterCredentialResult.Success(
|
||||||
registrationResponse = "mockRegistrationResponse",
|
registrationResponse = "mockRegistrationResponse",
|
||||||
)
|
)
|
||||||
coEvery {
|
coEvery {
|
||||||
|
@ -750,7 +749,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
||||||
eventTurbine.awaitItem(),
|
eventTurbine.awaitItem(),
|
||||||
)
|
)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
VaultAddEditEvent.CompleteFido2Create(result = mockCreateResult),
|
VaultAddEditEvent.CompleteFido2Registration(result = mockCreateResult),
|
||||||
eventTurbine.awaitItem(),
|
eventTurbine.awaitItem(),
|
||||||
)
|
)
|
||||||
assertEquals(stateWithName, stateTurbine.awaitItem())
|
assertEquals(stateWithName, stateTurbine.awaitItem())
|
||||||
|
@ -767,7 +766,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in add mode during fido2, SaveClick should show dialog, register credential, show toast on error, and emit ExitApp`() =
|
fun `in add mode during fido2, SaveClick should show dialog, register credential, show toast on error, and emit ExitApp when result is Error`() =
|
||||||
runTest {
|
runTest {
|
||||||
val fido2CredentialRequest = Fido2CredentialRequest(
|
val fido2CredentialRequest = Fido2CredentialRequest(
|
||||||
userId = "mockUserId",
|
userId = "mockUserId",
|
||||||
|
@ -807,9 +806,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
||||||
vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN),
|
vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val mockCreateResult = Fido2CreateCredentialResult.Error(
|
val mockCreateResult = Fido2RegisterCredentialResult.Error
|
||||||
exception = CreateCredentialUnknownException(),
|
|
||||||
)
|
|
||||||
coEvery {
|
coEvery {
|
||||||
fido2CredentialManager.registerFido2Credential(
|
fido2CredentialManager.registerFido2Credential(
|
||||||
userId = "mockUserId",
|
userId = "mockUserId",
|
||||||
|
@ -832,7 +829,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
||||||
eventTurbine.awaitItem(),
|
eventTurbine.awaitItem(),
|
||||||
)
|
)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
VaultAddEditEvent.CompleteFido2Create(result = mockCreateResult),
|
VaultAddEditEvent.CompleteFido2Registration(result = mockCreateResult),
|
||||||
eventTurbine.awaitItem(),
|
eventTurbine.awaitItem(),
|
||||||
)
|
)
|
||||||
assertEquals(stateWithName, stateTurbine.awaitItem())
|
assertEquals(stateWithName, stateTurbine.awaitItem())
|
||||||
|
@ -847,6 +844,86 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `in add mode during fido2, SaveClick should show saving dialog, register credential, dismiss dialog, show toast on error, and emit ExitApp when activeUserId is null`() =
|
||||||
|
runTest {
|
||||||
|
val fido2CredentialRequest = Fido2CredentialRequest(
|
||||||
|
userId = "mockUserId",
|
||||||
|
requestJson = "mockRequestJson",
|
||||||
|
packageName = "mockPackageName",
|
||||||
|
signingInfo = mockk<SigningInfo>(),
|
||||||
|
origin = null,
|
||||||
|
)
|
||||||
|
specialCircumstanceManager.specialCircumstance =
|
||||||
|
SpecialCircumstance.Fido2Save(
|
||||||
|
fido2CredentialRequest = fido2CredentialRequest,
|
||||||
|
)
|
||||||
|
val stateWithDialog = createVaultAddItemState(
|
||||||
|
vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN),
|
||||||
|
dialogState = VaultAddEditState.DialogState.Loading(
|
||||||
|
R.string.saving.asText(),
|
||||||
|
),
|
||||||
|
commonContentViewState = createCommonContentViewState(
|
||||||
|
name = "mockName-1",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copy(shouldExitOnSave = true)
|
||||||
|
|
||||||
|
val stateWithName = createVaultAddItemState(
|
||||||
|
vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN),
|
||||||
|
commonContentViewState = createCommonContentViewState(
|
||||||
|
name = "mockName-1",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copy(shouldExitOnSave = true)
|
||||||
|
mutableVaultDataFlow.value = DataState.Loaded(
|
||||||
|
createVaultData(),
|
||||||
|
)
|
||||||
|
val viewModel = createAddVaultItemViewModel(
|
||||||
|
createSavedStateHandleWithState(
|
||||||
|
state = stateWithName,
|
||||||
|
vaultAddEditType = VaultAddEditType.AddItem(VaultItemCipherType.LOGIN),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
val mockCreateResult = Fido2RegisterCredentialResult.Error
|
||||||
|
coEvery {
|
||||||
|
fido2CredentialManager.registerFido2Credential(
|
||||||
|
userId = "mockUserId",
|
||||||
|
selectedCipherView = any(),
|
||||||
|
fido2CredentialRequest = fido2CredentialRequest,
|
||||||
|
)
|
||||||
|
} returns mockCreateResult
|
||||||
|
every { authRepository.activeUserId } returns null
|
||||||
|
|
||||||
|
turbineScope {
|
||||||
|
val stateTurbine = viewModel.stateFlow.testIn(backgroundScope)
|
||||||
|
val eventTurbine = viewModel.eventFlow.testIn(backgroundScope)
|
||||||
|
|
||||||
|
viewModel.trySendAction(VaultAddEditAction.Common.SaveClick)
|
||||||
|
|
||||||
|
assertEquals(stateWithName, stateTurbine.awaitItem())
|
||||||
|
assertEquals(stateWithDialog, stateTurbine.awaitItem())
|
||||||
|
assertEquals(
|
||||||
|
VaultAddEditEvent.ShowToast(R.string.an_error_has_occurred.asText()),
|
||||||
|
eventTurbine.awaitItem(),
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
VaultAddEditEvent.CompleteFido2Registration(result = mockCreateResult),
|
||||||
|
eventTurbine.awaitItem(),
|
||||||
|
)
|
||||||
|
assertEquals(stateWithName, stateTurbine.awaitItem())
|
||||||
|
|
||||||
|
coVerify(exactly = 0) {
|
||||||
|
fido2CredentialManager.registerFido2Credential(
|
||||||
|
userId = "mockUserId",
|
||||||
|
selectedCipherView = any(),
|
||||||
|
fido2CredentialRequest = fido2CredentialRequest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in add mode, createCipherInOrganization success should ShowToast and NavigateBack`() =
|
fun `in add mode, createCipherInOrganization success should ShowToast and NavigateBack`() =
|
||||||
runTest {
|
runTest {
|
||||||
|
|
|
@ -82,7 +82,7 @@ class VaultItemListingScreenTest : BaseComposeTest() {
|
||||||
every { launchUri(any()) } just runs
|
every { launchUri(any()) } just runs
|
||||||
}
|
}
|
||||||
private val fido2CompletionManager: Fido2CompletionManager = mockk {
|
private val fido2CompletionManager: Fido2CompletionManager = mockk {
|
||||||
every { completeFido2Create(any()) } just runs
|
every { completeFido2Registration(any()) } just runs
|
||||||
}
|
}
|
||||||
private val mutableEventFlow = bufferedMutableSharedFlow<VaultItemListingEvent>()
|
private val mutableEventFlow = bufferedMutableSharedFlow<VaultItemListingEvent>()
|
||||||
private val mutableStateFlow = MutableStateFlow(DEFAULT_STATE)
|
private val mutableStateFlow = MutableStateFlow(DEFAULT_STATE)
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||||
import com.x8bit.bitwarden.data.auth.repository.model.ValidatePasswordResult
|
import com.x8bit.bitwarden.data.auth.repository.model.ValidatePasswordResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2CredentialRequest
|
||||||
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2RegisterCredentialResult
|
||||||
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
import com.x8bit.bitwarden.data.autofill.fido2.model.Fido2ValidateOriginResult
|
||||||
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManager
|
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManager
|
||||||
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManagerImpl
|
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManagerImpl
|
||||||
|
@ -66,6 +67,7 @@ import kotlinx.coroutines.flow.emptyFlow
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertFalse
|
import org.junit.jupiter.api.Assertions.assertFalse
|
||||||
|
import org.junit.jupiter.api.Assertions.assertNull
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import java.time.Clock
|
import java.time.Clock
|
||||||
|
@ -1736,6 +1738,98 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `Fido2RegisterCredentialResult Error should show toast and emit CompleteFido2Registration result`() =
|
||||||
|
runTest {
|
||||||
|
val mockResult = Fido2RegisterCredentialResult.Error
|
||||||
|
|
||||||
|
val viewModel = createVaultItemListingViewModel()
|
||||||
|
viewModel.trySendAction(
|
||||||
|
VaultItemListingsAction.Internal.Fido2RegisterCredentialResultReceive(
|
||||||
|
mockResult,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.eventFlow.test {
|
||||||
|
assertEquals(
|
||||||
|
VaultItemListingEvent.ShowToast(R.string.an_error_has_occurred.asText()),
|
||||||
|
awaitItem(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
VaultItemListingEvent.CompleteFido2Registration(mockResult),
|
||||||
|
awaitItem(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `Fido2RegisterCredentialResult Success should show toast and emit CompleteFido2Registration result`() =
|
||||||
|
runTest {
|
||||||
|
val mockResult = Fido2RegisterCredentialResult.Success(
|
||||||
|
registrationResponse = "mockResponse",
|
||||||
|
)
|
||||||
|
|
||||||
|
val viewModel = createVaultItemListingViewModel()
|
||||||
|
viewModel.trySendAction(
|
||||||
|
VaultItemListingsAction.Internal.Fido2RegisterCredentialResultReceive(
|
||||||
|
mockResult,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.eventFlow.test {
|
||||||
|
assertEquals(
|
||||||
|
VaultItemListingEvent.ShowToast(R.string.item_updated.asText()),
|
||||||
|
awaitItem(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
VaultItemListingEvent.CompleteFido2Registration(mockResult),
|
||||||
|
awaitItem(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `Fido2RegisterCredentialResult Cancelled should emit CompleteFido2Registration result`() =
|
||||||
|
runTest {
|
||||||
|
val mockResult = Fido2RegisterCredentialResult.Cancelled
|
||||||
|
val viewModel = createVaultItemListingViewModel()
|
||||||
|
|
||||||
|
viewModel.trySendAction(
|
||||||
|
VaultItemListingsAction.Internal.Fido2RegisterCredentialResultReceive(
|
||||||
|
mockResult,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.eventFlow.test {
|
||||||
|
assertEquals(
|
||||||
|
VaultItemListingEvent.CompleteFido2Registration(mockResult),
|
||||||
|
awaitItem(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `DismissFido2ErrorDialogClick should clear the dialog state then complete FIDO 2 create`() =
|
||||||
|
runTest {
|
||||||
|
val viewModel = createVaultItemListingViewModel()
|
||||||
|
viewModel.trySendAction(VaultItemListingsAction.DismissFido2CreationErrorDialogClick)
|
||||||
|
viewModel.eventFlow.test {
|
||||||
|
assertNull(viewModel.stateFlow.value.dialogState)
|
||||||
|
assertEquals(
|
||||||
|
VaultItemListingEvent.CompleteFido2Registration(
|
||||||
|
result = Fido2RegisterCredentialResult.Error,
|
||||||
|
),
|
||||||
|
awaitItem(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("CyclomaticComplexMethod")
|
@Suppress("CyclomaticComplexMethod")
|
||||||
private fun createSavedStateHandleWithVaultItemListingType(
|
private fun createSavedStateHandleWithVaultItemListingType(
|
||||||
vaultItemListingType: VaultItemListingType,
|
vaultItemListingType: VaultItemListingType,
|
||||||
|
|
Loading…
Reference in a new issue