1mod challenge;
23mod challenge_rate_limit;
24mod cookies;
25mod errors;
26mod openapi;
27mod options;
28mod response;
29mod routes;
30mod schema;
31mod session;
32mod store;
33mod webauthn;
34
35pub use errors::PASSKEY_ERROR_CODES;
36pub use options::{
37 AfterAuthenticationVerificationInput, AfterRegistrationVerificationInput,
38 AuthenticatorAttachment, AuthenticatorSelection, PasskeyAdvancedOptions,
39 PasskeyAuthenticationOptions, PasskeyAuthenticationRejected, PasskeyChallengeRateLimit,
40 PasskeyExtensionsInput, PasskeyManagementOptions, PasskeyOptions, PasskeyRateLimit,
41 PasskeyRegistrationOptions, PasskeyRegistrationUser, PasskeySchemaOptions,
42 RegistrationWebAuthnOptions, ResidentKeyRequirement, ResolveRegistrationUserInput,
43 UserVerificationRequirement,
44};
45pub use store::Passkey;
46pub use webauthn::{
47 PasskeyAuthenticationStart, PasskeyRegistrationStart, VerifiedAuthentication,
48 VerifiedPasskeyCredential, WebAuthnConfig,
49};
50
51#[cfg(feature = "test-util")]
52pub use webauthn::{PasskeyWebAuthnBackend, RealPasskeyWebAuthnBackend};
53
54use rustauth_core::plugin::{AuthPlugin, PluginRateLimitRule};
55
56pub const UPSTREAM_PLUGIN_ID: &str = "passkey";
57
58pub const RATE_LIMITED_CEREMONY_PATHS: &[&str] = &[
60 "/passkey/generate-authenticate-options",
61 "/passkey/verify-authentication",
62 "/passkey/generate-register-options",
63 "/passkey/verify-registration",
64];
65
66#[must_use]
68pub fn passkey(options: PasskeyOptions) -> AuthPlugin {
69 let rate_limit_rule = options.rate_limit_rule();
70 let options = std::sync::Arc::new(options);
71 let mut plugin = AuthPlugin::new(UPSTREAM_PLUGIN_ID).with_version(env!("CARGO_PKG_VERSION"));
72 for path in RATE_LIMITED_CEREMONY_PATHS {
73 plugin = plugin.with_rate_limit(PluginRateLimitRule::new(*path, rate_limit_rule.clone()));
74 }
75 for contribution in schema::contributions(&options) {
76 plugin = plugin.with_schema(contribution);
77 }
78 for code in errors::plugin_error_codes() {
79 plugin = plugin.with_error_code(code);
80 }
81 for endpoint in routes::endpoints(options) {
82 plugin = plugin.with_endpoint(endpoint);
83 }
84 plugin
85}