diff --git a/Cargo.toml b/Cargo.toml index cd3c903..f12ccb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "stytch" -version = "3.0.0" +version = "3.0.1" edition = "2021" license = "MIT" description = "Stytch Rust client" diff --git a/src/client.rs b/src/client.rs index 48e8cfb..aaf4d3d 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,6 @@ use base64::{engine::general_purpose, Engine as _}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::sync::{Arc, Mutex}; const LIVE_URL: &str = "https://api.stytch.com/"; const TEST_URL: &str = "https://test.stytch.com/"; @@ -13,7 +14,7 @@ pub struct Client { // This would be very natural as a OnceCell, but get_or_try_init is unstable // and would require marking this library as only usable with nightly rust. // When that feature is stabilized, we should switch to using OnceCell. - jwks: std::cell::RefCell>, + jwks: Arc>>, } impl std::fmt::Debug for Client { @@ -82,22 +83,34 @@ impl Client { project_id: project_id.to_string(), base_url, jwks_url, - jwks: std::cell::RefCell::new(None), + jwks: Arc::new(Mutex::new(None)), }) } async fn fetch_jwks(&self) -> crate::Result { - if self.jwks.borrow().is_none() { - self.jwks.replace( - self.send(crate::Request { - method: http::Method::GET, - path: self.jwks_url.clone(), - body: (), - }) - .await?, - ); + // First see if we already have the jwks cached + { + let guard = self.jwks.lock().map_err(|_| crate::Error::FetchJwks)?; + if let Some(jwks) = &*guard { + return Ok(jwks.clone()); + } } - Ok(self.jwks.borrow().clone().unwrap()) + + let fetched_jwks: Jwks = self + .send(crate::Request { + method: http::Method::GET, + path: self.jwks_url.clone(), + body: (), + }) + .await + .map_err(|_| crate::Error::FetchJwks)?; + + { + let mut guard = self.jwks.lock().map_err(|_| crate::Error::FetchJwks)?; + *guard = Some(fetched_jwks.clone()); + } + + Ok(fetched_jwks) } pub async fn fetch_jwk(&self, kid: &str) -> crate::Result { diff --git a/src/lib.rs b/src/lib.rs index 6869263..df9d9a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,9 @@ pub enum Error { #[error(transparent)] InvalidUrl(#[from] url::ParseError), + #[error("Failed to fetch JWKS")] + FetchJwks, + #[error("{0:?}")] JwkNotFound(String),