alibi_plugins/passkey/
authentication.rs1use alibi_core::{AuthConfig, AuthRequest, AuthResult, ContextExtensions, utils::json::JsValue};
3use async_trait::async_trait;
4use std::sync::Arc;
5#[derive(Debug, Clone)]
8pub enum AuthenticationResult {
9 Core(webauthn_rs::prelude::AuthenticationResult),
10 Raw(RawAuthenticationResult),
11}
12
13#[derive(Debug, Clone)]
14pub struct RawAuthenticationResult {
15 pub(super) credential_id: webauthn_rs::prelude::CredentialID,
16 pub(super) counter: u32,
17 pub(super) user_verified: bool,
18 pub(super) backup_eligible: bool,
19 pub(super) backup_state: bool,
20}
21
22impl AuthenticationResult {
23 pub fn cred_id(&self) -> &webauthn_rs::prelude::CredentialID {
24 match self {
25 Self::Core(result) => result.cred_id(),
26 Self::Raw(result) => &result.credential_id,
27 }
28 }
29 pub fn counter(&self) -> u32 {
30 match self {
31 Self::Core(result) => result.counter(),
32 Self::Raw(result) => result.counter,
33 }
34 }
35 pub fn user_verified(&self) -> bool {
36 match self {
37 Self::Core(result) => result.user_verified(),
38 Self::Raw(result) => result.user_verified,
39 }
40 }
41 pub fn backup_eligible(&self) -> bool {
42 match self {
43 Self::Core(result) => result.backup_eligible(),
44 Self::Raw(result) => result.backup_eligible,
45 }
46 }
47 pub fn backup_state(&self) -> bool {
48 match self {
49 Self::Core(result) => result.backup_state(),
50 Self::Raw(result) => result.backup_state,
51 }
52 }
53}
54
55pub struct PasskeyAuthenticationContext<'a> {
57 pub request: Option<&'a AuthRequest>,
59 pub endpoint: Option<&'a alibi_core::endpoint::EndpointCall>,
61 pub auth_config: &'a AuthConfig,
62 pub extensions: &'a ContextExtensions,
63}
64
65impl std::fmt::Debug for PasskeyAuthenticationContext<'_> {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 f.debug_struct("PasskeyAuthenticationContext")
68 .finish_non_exhaustive()
69 }
70}
71
72#[derive(Debug, Clone)]
74pub struct VerifiedPasskeyAuthentication {
75 pub result: AuthenticationResult,
76 pub origin: String,
77 pub rp_id: String,
78}
79
80#[async_trait]
83pub trait PasskeyAuthenticationAfterVerification: Send + Sync {
84 async fn after_verification(
85 &self,
86 context: &PasskeyAuthenticationContext<'_>,
87 verification: &VerifiedPasskeyAuthentication,
88 client_data: &JsValue,
89 ) -> AuthResult<()>;
90}
91
92#[derive(Clone, Default)]
93pub struct PasskeyAuthenticationConfig {
94 pub extensions: Option<super::PasskeyExtensions>,
95 pub after_verification: Option<Arc<dyn PasskeyAuthenticationAfterVerification>>,
96}
97impl std::fmt::Debug for PasskeyAuthenticationConfig {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 f.debug_struct("PasskeyAuthenticationConfig")
100 .field("extensions", &self.extensions)
101 .field("after_verification", &self.after_verification.is_some())
102 .finish()
103 }
104}