Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions credentialsd-common/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ pub enum Error {
AuthenticatorError,
/// No matching credentials were found on the device.
NoCredentials,
/// Credential was already registered with this device (credential ID contained in excludeCredentials)
CredentialExcluded,
/// Too many incorrect PIN attempts, and authenticator must be removed and
/// reinserted to continue any more PIN attempts.
///
Expand All @@ -292,6 +294,7 @@ impl Display for Error {
match self {
Self::AuthenticatorError => f.write_str("AuthenticatorError"),
Self::NoCredentials => f.write_str("NoCredentials"),
Self::CredentialExcluded => f.write_str("CredentialExcluded"),
Self::PinAttemptsExhausted => f.write_str("PinAttemptsExhausted"),
Self::Internal(s) => write!(f, "InternalError: {s}"),
}
Expand Down
5 changes: 5 additions & 0 deletions credentialsd-common/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,9 @@ pub enum ServiceError {
/// No matching credentials were found on the device.
NoCredentials,

/// Credential was already registered with this device (credential ID contained in excludeCredentials)
CredentialExcluded,

/// Too many incorrect PIN attempts, and authenticator must be removed and
/// reinserted to continue any more PIN attempts.
///
Expand Down Expand Up @@ -363,6 +366,7 @@ impl From<ServiceError> for crate::model::Error {
match value {
ServiceError::AuthenticatorError => Self::AuthenticatorError,
ServiceError::NoCredentials => Self::NoCredentials,
ServiceError::CredentialExcluded => Self::CredentialExcluded,
ServiceError::PinAttemptsExhausted => Self::PinAttemptsExhausted,
// TODO: this is bogus, we should refactor to remove the tuple field
// and let the client decide how to render the error.
Expand Down Expand Up @@ -439,6 +443,7 @@ impl TryFrom<UsbState> for crate::model::UsbState {
match error_code.as_ref() {
"AuthenticatorError" => ServiceError::AuthenticatorError,
"NoCredentials" => ServiceError::NoCredentials,
"CredentialExcluded" => ServiceError::CredentialExcluded,
"PinAttemptsExhausted" => ServiceError::PinAttemptsExhausted,
_ => ServiceError::Internal,
}
Expand Down
3 changes: 3 additions & 0 deletions credentialsd-ui/src/gui/view_model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ impl<F: FlowController + Send> ViewModel<F> {
Error::AuthenticatorError | Error::Internal(_) => {
"Something went wrong while retrieving a credential. Please try again later or use a different authenticator."
}
Error::CredentialExcluded => {
"This credential is already registered on this authenticator."
}
});
self.tx_update
.send(ViewUpdate::Failed(error_msg))
Expand Down
1 change: 1 addition & 0 deletions credentialsd/src/credential_service/usb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ async fn handle_events(
.map_err(|err| match err {
WebAuthnError::Ctap(CtapError::PINAuthBlocked) => Error::PinAttemptsExhausted,
WebAuthnError::Ctap(CtapError::NoCredentials) => Error::NoCredentials,
WebAuthnError::Ctap(CtapError::CredentialExcluded) => Error::CredentialExcluded,
_ => Error::AuthenticatorError,
});
if let Err(err) = signal_tx.send(response).await {
Expand Down