siteKey() !== '' && (string) config('services.turnstile.secret_key', '') !== ''; } public function siteKey(): string { return (string) config('services.turnstile.site_key', ''); } public function inputName(): string { return 'cf-turnstile-response'; } public function scriptUrl(): string { return (string) config('services.turnstile.script_url', self::DEFAULT_SCRIPT_URL); } public function verify(string $token, ?string $ip = null): bool { if (! $this->isEnabled()) { return true; } if (trim($token) === '') { return false; } try { $response = Http::asForm() ->timeout((int) config('services.turnstile.timeout', 5)) ->post((string) config('services.turnstile.verify_url', self::DEFAULT_VERIFY_URL), [ 'secret' => (string) config('services.turnstile.secret_key', ''), 'response' => $token, ]); if ($response->failed()) { Log::info('turnstile verification rejected registration attempt', [ 'ip' => $ip, 'hostname' => data_get($response->json(), 'hostname'), 'error_codes' => data_get($response->json(), 'error-codes', []), ]); return false; } $success = (bool) data_get($response->json(), 'success', false); if (! $success) { Log::info('turnstile verification rejected registration attempt', [ 'ip' => $ip, 'hostname' => data_get($response->json(), 'hostname'), 'error_codes' => data_get($response->json(), 'error-codes', []), ]); } return $success; } catch (\Throwable $exception) { Log::warning('turnstile verification request failed', [ 'message' => $exception->getMessage(), 'ip' => $ip, ]); return (bool) config('services.turnstile.fail_open', false); } } }