http = $http; $this->secret = $secret; } public function responseField(): string { return 'g-recaptcha-response'; } public function verify(string $response, ?string $remote_ip): bool { $data = [ 'secret' => $this->secret, 'response' => $response ]; if ($remote_ip !== null) { $data['remoteip'] = $remote_ip; } $ret = $this->http->requestGet('https://www.google.com/recaptcha/api/siteverify', $data); $resp = json_decode($ret, true, 16, JSON_THROW_ON_ERROR); return isset($resp['success']) && $resp['success']; } } class HCaptchaQuery implements RemoteCaptchaQuery { private HttpDriver $http; private string $secret; private string $sitekey; /** * Creates a new HCaptchaQuery using the hCaptcha service. * * @param HttpDriver $http The http client. * @param string $secret Server side secret. * @return HCaptchaQuery A new hCaptcha query instance. */ public function __construct(HttpDriver $http, string $secret, string $sitekey) { $this->http = $http; $this->secret = $secret; $this->sitekey = $sitekey; } public function responseField(): string { return 'h-captcha-response'; } public function verify(string $response, ?string $remote_ip): bool { $data = [ 'secret' => $this->secret, 'response' => $response, 'sitekey' => $this->sitekey ]; if ($remote_ip !== null) { $data['remoteip'] = $remote_ip; } $ret = $this->http->requestGet('https://hcaptcha.com/siteverify', $data); $resp = json_decode($ret, true, 16, JSON_THROW_ON_ERROR); return isset($resp['success']) && $resp['success']; } } interface RemoteCaptchaQuery { /** * Name of the response field in the form data expected by the implementation. * * @return string The name of the field. */ public function responseField(): string; /** * Checks if the user at the remote ip passed the captcha. * * @param string $response User provided response. * @param ?string $remote_ip User ip. Leave to null to only check the response value. * @return bool Returns true if the user passed the captcha. * @throws RuntimeException|JsonException Throws on IO errors or if it fails to decode the answer. */ public function verify(string $response, ?string $remote_ip): bool; } class NativeCaptchaQuery { private HttpDriver $http; private string $domain; private string $provider_check; private string $extra; /** * @param HttpDriver $http The http client. * @param string $domain The server's domain. * @param string $provider_check Path to the endpoint. * @param string $extra Extra http parameters. */ function __construct(HttpDriver $http, string $domain, string $provider_check, string $extra) { $this->http = $http; $this->domain = $domain; $this->provider_check = $provider_check; $this->extra = $extra; } /** * Checks if the user at the remote ip passed the native vichan captcha. * * @param string $user_text Remote user's text input. * @param string $user_cookie Remote user cookie. * @return bool Returns true if the user passed the check. * @throws RuntimeException Throws on IO errors. */ public function verify(string $user_text, string $user_cookie): bool { $data = [ 'mode' => 'check', 'text' => $user_text, 'extra' => $this->extra, 'cookie' => $user_cookie ]; $ret = $this->http->requestGet($this->domain . '/' . $this->provider_check, $data); return $ret === '1'; } }