diff --git a/README.md b/README.md index 18acf3c..eb9da67 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ async fn main() -> Result<(), Box> { response: "my-widget-response".to_string(), ..Default::default() }, - Some(&["example.com"]), + ["example.com"], ) .await?; diff --git a/src/lib.rs b/src/lib.rs index a48920e..6fc98e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -127,7 +127,7 @@ impl TurnstileClient { /// `valid_hostnames` is an optional list of hostnames to verify against. The function /// will error if the hostname returned by the Turnstile API does not match any of the /// provided hostnames. - /// When it is None, the hostname is not verified. + /// To skip hostname verification, set it to `None::<&str>`. /// /// # Timeouts /// @@ -147,7 +147,7 @@ impl TurnstileClient { /// /// tokio::time::timeout( /// Duration::from_secs(5), - /// client.siteverify(request, Some(&["example.com"])) + /// client.siteverify(request, ["example.com"]) /// ).await.ok() /// # } /// ``` @@ -180,7 +180,7 @@ impl TurnstileClient { /// match client /// .siteverify( /// SiteVerifyRequest { response: token, ..Default::default() }, - /// Some(&["example.com"]), + /// ["example.com"], /// ) /// .await /// { @@ -201,7 +201,7 @@ impl TurnstileClient { pub async fn siteverify( &self, request: SiteVerifyRequest, - valid_hostnames: Option<&[&str]>, + valid_hostnames: impl IntoIterator>, ) -> Result { let body = SiteVerifyBody { secret: self.secret.expose_secret(), @@ -271,9 +271,12 @@ impl TurnstileClient { return Err(TokenRejection::Unverified.into()); } - if let Some(valid_hostnames) = valid_hostnames + // If peeking does not work, it means `None` was passed. + let mut valid_hostnames = valid_hostnames.into_iter().peekable(); + // Reject if none of the valid_hostnames matches the body's hostname field + if valid_hostnames.peek().is_some() && let Some(ref body_hostname) = body.hostname - && !valid_hostnames.contains(&body_hostname.as_str()) + && !valid_hostnames.any(|h| h.as_ref() == body_hostname.as_str()) { return Err(TokenRejection::HostnameMismatch(body_hostname.clone()).into()); } diff --git a/src/test.rs b/src/test.rs index c17ce47..8a56851 100644 --- a/src/test.rs +++ b/src/test.rs @@ -119,7 +119,7 @@ async fn test_success() -> Result<()> { response: "myresponse".to_string(), ..Default::default() }, - Some(&["example.com"]), + None::<&str>, ) .await?; @@ -141,7 +141,7 @@ async fn test_success_with_hostname() -> Result<()> { response: "myresponse".to_string(), ..Default::default() }, - Some(&["example.com"]), + ["example.com"], ) .await?; @@ -163,7 +163,7 @@ async fn test_reject_invalid_hostname() -> Result<()> { response: "myresponse".to_string(), ..Default::default() }, - Some(&["evil.com"]), + ["evil.com"], ) .await; @@ -188,7 +188,7 @@ async fn test_fail() -> Result<()> { response: "myresponse".to_string(), ..Default::default() }, - Some(&["example.com"]), + ["example.com"], ) .await; @@ -218,7 +218,7 @@ async fn test_error_codes_survive_http_400() -> Result<()> { response: "myresponse".to_string(), ..Default::default() }, - None, + None::<&str>, ) .await; @@ -244,7 +244,7 @@ async fn test_token_already_spent() -> Result<()> { response: "myresponse".to_string(), ..Default::default() }, - Some(&["example.com"]), + ["example.com"], ) .await; @@ -281,7 +281,7 @@ async fn test_integration() -> Result<()> { idempotency_key, ..Default::default() }, - Some(&["example.com"]), + ["example.com"], ) .await?;