add mysql2postgres

This commit is contained in:
Ember Moth
2026-07-05 20:45:27 +08:00
parent 5d0b790aa1
commit 4f74e14fba
3 changed files with 121 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "turnstile"
version = "0.1.0"
edition = "2021"
description = "Cloudflare Turnstile token verification — port of pkg/turnstile"
[dependencies]
anyhow = "1"
reqwest = { version = "0.12", features = ["json"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["time"] }
uuid = { version = "1", features = ["v4"] }
+60
View File
@@ -0,0 +1,60 @@
//! Cloudflare Turnstile token verification.
//! Port of `server/pkg/turnstile`.
use serde::{Deserialize, Serialize};
const VERIFY_URL: &str = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
#[derive(Debug, Serialize)]
struct VerifyRequest<'a> {
secret: &'a str,
response: &'a str,
#[serde(skip_serializing_if = "str::is_empty")]
remoteip: &'a str,
#[serde(skip_serializing_if = "str::is_empty")]
idempotency_key: &'a str,
}
#[derive(Debug, Deserialize)]
struct VerifyResponse {
success: bool,
#[serde(rename = "error-codes", default)]
error_codes: Vec<String>,
}
/// Verify a Turnstile challenge token.
///
/// - `secret` — site secret key from Cloudflare dashboard
/// - `token` — value of `cf-turnstile-response` submitted by the browser
/// - `ip` — optional client IP (pass `""` to omit)
pub async fn verify(secret: &str, token: &str, ip: &str) -> anyhow::Result<bool> {
verify_with_key(secret, token, ip, "").await
}
/// Verify with idempotency key (prevents the same token being accepted twice).
pub async fn verify_with_key(
secret: &str,
token: &str,
ip: &str,
idempotency_key: &str,
) -> anyhow::Result<bool> {
let client = reqwest::Client::new();
let req = VerifyRequest { secret, response: token, remoteip: ip, idempotency_key };
let resp: VerifyResponse = client
.post(VERIFY_URL)
.json(&req)
.send()
.await?
.json()
.await?;
if !resp.success && !resp.error_codes.is_empty() {
tracing::warn!(codes = ?resp.error_codes, "turnstile verification failed");
}
Ok(resp.success)
}
/// Generate a random UUID suitable for use as an idempotency key.
pub fn random_uuid() -> String {
uuid::Uuid::new_v4().to_string()
}