use passkey_authenticator::{CredentialStore, StoreInfo, UserValidationMethod};
use passkey_types::{
ctap2::{get_assertion, get_info, make_credential},
webauthn::{
AuthenticationExtensionsClientInputs, AuthenticationExtensionsClientOutputs,
CredentialPropertiesOutput, PublicKeyCredentialRequestOptions,
},
};
use crate::{Client, WebauthnError};
mod prf;
impl<S, U, P, F> Client<S, U, P, F>
where
S: CredentialStore + Sync,
U: UserValidationMethod + Sync,
P: public_suffix::EffectiveTLDProvider + Sync + 'static,
{
pub(super) fn registration_extension_ctap2_input(
&self,
request: Option<&AuthenticationExtensionsClientInputs>,
supported_extensions: &[get_info::Extension],
) -> Result<Option<make_credential::ExtensionInputs>, WebauthnError> {
prf::registration_prf_to_ctap2_input(request, supported_extensions)
}
pub(super) fn registration_extension_outputs(
&self,
request: Option<&AuthenticationExtensionsClientInputs>,
store_info: StoreInfo,
rk: bool,
authenticator_response: Option<make_credential::UnsignedExtensionOutputs>,
) -> AuthenticationExtensionsClientOutputs {
let cred_props_requested = request.and_then(|ext| ext.cred_props) == Some(true);
let cred_props = if cred_props_requested {
let discoverable = store_info.discoverability.is_passkey_discoverable(rk);
Some(CredentialPropertiesOutput {
discoverable: Some(discoverable),
})
} else {
None
};
let prf = authenticator_response
.and_then(|ext_out| ext_out.prf)
.map(Into::into);
AuthenticationExtensionsClientOutputs { cred_props, prf }
}
pub(super) fn auth_extension_ctap2_input(
&self,
request: &PublicKeyCredentialRequestOptions,
supported_extensions: &[get_info::Extension],
) -> Result<Option<get_assertion::ExtensionInputs>, WebauthnError> {
prf::auth_prf_to_ctap2_input(request, supported_extensions)
}
pub(super) fn auth_extension_outputs(
&self,
authenticator_response: Option<get_assertion::UnsignedExtensionOutputs>,
) -> AuthenticationExtensionsClientOutputs {
let prf = authenticator_response
.and_then(|ext_out| ext_out.prf)
.map(Into::into);
AuthenticationExtensionsClientOutputs {
prf,
..Default::default()
}
}
}