alibi_api/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: &'a AuthRequest,
58 pub auth_config: &'a AuthConfig,
59 pub extensions: &'a ContextExtensions,
60}
61
62impl std::fmt::Debug for PasskeyAuthenticationContext<'_> {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 f.debug_struct("PasskeyAuthenticationContext")
65 .finish_non_exhaustive()
66 }
67}
68
69#[derive(Debug, Clone)]
71pub struct VerifiedPasskeyAuthentication {
72 pub result: AuthenticationResult,
73 pub origin: String,
74 pub rp_id: String,
75}
76
77#[async_trait]
80pub trait PasskeyAuthenticationAfterVerification: Send + Sync {
81 async fn after_verification(
82 &self,
83 context: &PasskeyAuthenticationContext<'_>,
84 verification: &VerifiedPasskeyAuthentication,
85 client_data: &JsValue,
86 ) -> AuthResult<()>;
87}
88
89#[derive(Clone, Default)]
90pub struct PasskeyAuthenticationConfig {
91 pub after_verification: Option<Arc<dyn PasskeyAuthenticationAfterVerification>>,
92}
93impl std::fmt::Debug for PasskeyAuthenticationConfig {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 f.debug_struct("PasskeyAuthenticationConfig")
96 .field("after_verification", &self.after_verification.is_some())
97 .finish()
98 }
99}