passkey_server/lib.rs
1//! # Passkey
2//!
3//! A generic Rust implementation of the WebAuthn (Passkey) protocol, designed to be
4//! storage-agnostic and easy to integrate into any backend.
5//!
6//! ## Features
7//!
8//! - **Generic Storage**: Implement the [`PasskeyStore`] trait to use your own database.
9//! - **WASM Friendly**: Works well in WASM environments like Cloudflare Workers.
10//! - **Simple Protocol Handlers**: Provides high-level functions for the standard WebAuthn registration and login flows.
11//!
12//! ## Example usage
13//!
14//! For a complete, runnable example using Axum and an in-memory store, see [`examples/basic.rs`](https://github.com/Asutorufa/housou/blob/main/crates/passkey/examples/basic.rs).
15//!
16//! ```rust,no_run
17//! use passkey_server::{PasskeyConfig, PasskeyStore, start_registration, types::{StoredPasskey, PasskeyState}, error::Result};
18//! use async_trait::async_trait;
19//!
20//! // Example usage requires implementing the PasskeyStore trait
21//! struct MyDatabase;
22//!
23//! #[async_trait(?Send)]
24//! impl PasskeyStore for MyDatabase {
25//! async fn create_passkey(&self, _: String, _: &str, _: &str, _: &str, _: i64, _: i64) -> Result<()> { Ok(()) }
26//! async fn get_passkey(&self, _: &str) -> Result<Option<StoredPasskey>> { Ok(None) }
27//! async fn list_passkeys(&self, _: String) -> Result<Vec<StoredPasskey>> { Ok(vec![]) }
28//! async fn delete_passkey(&self, _: String, _: &str) -> Result<()> { Ok(()) }
29//! async fn update_passkey_counter(&self, _: &str, _: i64, _: i64) -> Result<()> { Ok(()) }
30//! async fn update_passkey_name(&self, _: &str, _: &str) -> Result<()> { Ok(()) }
31//! async fn save_state(&self, _: &str, _: &str, _: i64) -> Result<()> { Ok(()) }
32//! async fn get_state(&self, _: &str) -> Result<Option<PasskeyState>> { Ok(None) }
33//! async fn delete_state(&self, _: &str) -> Result<()> { Ok(()) }
34//! }
35//!
36//! #[tokio::main]
37//! async fn main() {
38//! let config = PasskeyConfig {
39//! rp_id: "example.com".to_string(),
40//! rp_name: "My App".to_string(),
41//! origin: "https://example.com".to_string(),
42//! state_ttl: 300,
43//! };
44//!
45//! let store = MyDatabase;
46//! let user_id = "123";
47//! let now_ms = 1708358400000;
48//!
49//! // 1. Start registration
50//! let options = start_registration(
51//! &store,
52//! user_id,
53//! "alice",
54//! "Alice Doe",
55//! &config,
56//! now_ms
57//! ).await.unwrap();
58//!
59//! println!("Send these options to the frontend: {:?}", options);
60//! }
61//! ```
62
63pub mod error;
64pub mod protocol;
65pub mod store;
66pub mod types;
67
68pub use error::{PasskeyError, Result};
69pub use protocol::{finish_login, finish_registration, start_login, start_registration};
70pub use store::PasskeyStore;
71pub use types::PasskeyConfig;
72
73#[cfg(test)]
74mod tests;