from typing import Optional import httpx from ..runtime import get_runtime_settings async def verify_captcha(token: Optional[str], remote_ip: Optional[str] = None) -> bool: runtime = get_runtime_settings() provider = (runtime.captcha_provider or "none").strip().lower() if provider in {"", "none", "off", "disabled"}: return True if not token: return False if provider == "hcaptcha": secret = runtime.hcaptcha_secret_key url = "https://hcaptcha.com/siteverify" payload = {"secret": secret, "response": token} elif provider == "recaptcha": secret = runtime.recaptcha_secret_key url = "https://www.google.com/recaptcha/api/siteverify" payload = {"secret": secret, "response": token} elif provider == "turnstile": secret = runtime.turnstile_secret_key url = "https://challenges.cloudflare.com/turnstile/v0/siteverify" payload = {"secret": secret, "response": token} else: return False if not secret: return False if remote_ip: payload["remoteip"] = remote_ip try: async with httpx.AsyncClient(timeout=10.0) as client: response = await client.post(url, data=payload) response.raise_for_status() data = response.json() return bool(data.get("success")) except httpx.HTTPError: return False