Skip to main content

alibi_plugins/passkey/
options.rs

1//! Application inputs resolved before a passkey challenge is persisted.
2use alibi_core::{AuthConfig, AuthRequest, AuthResult, ContextExtensions, wire::UserView};
3use async_trait::async_trait;
4use serde_json::Value;
5use std::sync::Arc;
6
7pub struct PasskeyOptionsContext<'a> {
8    pub request: &'a AuthRequest,
9    pub auth_config: &'a AuthConfig,
10    pub extensions: &'a ContextExtensions,
11    pub user: Option<&'a UserView>,
12}
13
14#[async_trait]
15pub trait PasskeyExtensionsResolver: Send + Sync {
16    async fn resolve(&self, context: &PasskeyOptionsContext<'_>) -> AuthResult<Value>;
17}
18
19#[derive(Clone)]
20pub enum PasskeyExtensions {
21    Static(Value),
22    Resolver(Arc<dyn PasskeyExtensionsResolver>),
23}
24impl std::fmt::Debug for PasskeyExtensions {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        match self {
27            Self::Static(value) => f.debug_tuple("Static").field(value).finish(),
28            Self::Resolver(_) => f.write_str("Resolver(..)"),
29        }
30    }
31}
32impl PasskeyExtensions {
33    pub(super) async fn resolve(&self, context: &PasskeyOptionsContext<'_>) -> AuthResult<Value> {
34        let value = match self {
35            Self::Static(value) => Ok(value.clone()),
36            Self::Resolver(resolver) => resolver.resolve(context).await.map_err(|error| {
37                if alibi_core::endpoint::is_endpoint_api_error(&error) {
38                    error
39                } else {
40                    alibi_core::AuthError::CallbackFailure(Box::new(error))
41                }
42            }),
43        }?;
44        if !value.is_object() {
45            return Err(alibi_core::AuthError::config(
46                "Passkey extensions must be an object",
47            ));
48        }
49        Ok(value)
50    }
51}
52
53#[derive(Debug, Clone, Default)]
54pub struct PasskeyAuthenticatorSelection {
55    pub resident_key: Option<String>,
56    pub user_verification: Option<String>,
57    pub authenticator_attachment: Option<String>,
58}