diff --git a/Cargo.toml b/Cargo.toml index 0cdd6b4..df9f1a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ clap = { version = "4.6", features = ["derive", "env"] } data-encoding = "2" http = "1.5" jacquard = "0.12" -jacquard-axum = { version = "0.12", features = ["service-auth"] } +jacquard-axum = { version = "0.12", features = ["service-auth", "service-auth-replay"] } k256 = { version = "0.14", features = ["ecdsa"] } miette = { version = "7.6", features = ["fancy"] } mime_guess = "2.0.5" diff --git a/crates/knotty-knot/src/state.rs b/crates/knotty-knot/src/state.rs index 78e9761..226edf8 100644 --- a/crates/knotty-knot/src/state.rs +++ b/crates/knotty-knot/src/state.rs @@ -1,11 +1,12 @@ use std::path::Path; +use std::sync::Arc; use jacquard::SmolStr; use jacquard::identity::PublicResolver; use jacquard::types::did_doc::{DidDocument, Service, VerificationMethod, default_context}; use jacquard::types::string::Did; use jacquard::types::value::Data; -use jacquard_axum::service_auth::{NoopReplayStore, ReplayStore, ServiceAuth}; +use jacquard_axum::service_auth::{InMemoryReplayStore, ReplayStore, ServiceAuth}; use sqlx::SqlitePool; use crate::keypair; @@ -20,6 +21,9 @@ pub struct KnotState { pub plc_url: &'static str, pub http_client: reqwest::Client, pub db: SqlitePool, + /// Shared across every `KnotState` clone: a per-clone store would accept + /// each replayed token once per handler. + replay: Arc, } impl KnotState { @@ -44,6 +48,7 @@ impl KnotState { plc_url: plc_url.to_owned().leak(), http_client: reqwest::Client::new(), db, + replay: Arc::new(InMemoryReplayStore::default()), } } } @@ -68,11 +73,11 @@ impl ServiceAuth for KnotState { } fn replay_protection_enabled(&self) -> bool { - false + true } fn replay_store(&self) -> &dyn ReplayStore { - &NoopReplayStore + self.replay.as_ref() } }