Skip to main content

passkey_server/
store.rs

1use crate::error::Result;
2use crate::types::{PasskeyState, StoredPasskey};
3use async_trait::async_trait;
4
5/// A trait for managing the persistence of passkeys and authentication state.
6///
7/// Implement this trait to connect the `passkey` library to your chosen database.
8/// All methods are `async` and use `async_trait(?Send)` for compatibility with WASM.
9#[cfg_attr(not(feature = "send"), async_trait(?Send))]
10#[cfg_attr(feature = "send", async_trait)]
11pub trait PasskeyStore {
12    /// Save a new passkey credential to the database.
13    ///
14    /// - `user_id`: The ID of the owner.
15    /// - `cred_id`: The unique identifier for this credential (Base64url).
16    /// - `public_key`: The public key material (Base64url-encoded COSE key).
17    /// - `name`: A human-readable name for the passkey.
18    /// - `counter`: The initial signature counter.
19    /// - `created_at`: Creation timestamp in milliseconds.
20    async fn create_passkey(
21        &self,
22        user_id: String,
23        cred_id: &str,
24        public_key: &str,
25        name: &str,
26        counter: i64,
27        created_at: i64,
28    ) -> Result<()>;
29
30    /// Retrieve a passkey by its credential ID.
31    async fn get_passkey(&self, cred_id: &str) -> Result<Option<StoredPasskey>>;
32
33    /// List all passkeys associated with a specific user.
34    async fn list_passkeys(&self, user_id: String) -> Result<Vec<StoredPasskey>>;
35
36    /// Delete a passkey. Implementations should verify that `user_id` owns the `cred_id`.
37    async fn delete_passkey(&self, user_id: String, cred_id: &str) -> Result<()>;
38
39    /// Update the signature counter and last-used timestamp after a successful login.
40    async fn update_passkey_counter(
41        &self,
42        cred_id: &str,
43        new_counter: i64,
44        last_used_at: i64,
45    ) -> Result<()>;
46
47    /// Rename an existing passkey.
48    async fn update_passkey_name(&self, cred_id: &str, new_name: &str) -> Result<()>;
49
50    /// Save ephemeral registration or login state (challenges).
51    ///
52    /// The `state_json` contains internal session data and should be retrievable by `id`.
53    /// `expires_at` is the expiration timestamp in milliseconds.
54    async fn save_state(&self, id: &str, state_json: &str, expires_at: i64) -> Result<()>;
55
56    /// Retrieve ephemeral state by its ID. It should return `None` if expired.
57    async fn get_state(&self, id: &str) -> Result<Option<PasskeyState>>;
58
59    /// Delete ephemeral state (e.g., after the session is finished or fails).
60    async fn delete_state(&self, id: &str) -> Result<()>;
61}