https://cap.example.com/3c87a0e810/ * * @see https://github.com/oliweb-ch/laravel-cap */ class CapDriver implements CaptchaDriver { /** * Default @cap.js/widget version served from the CDN. "latest" tracks the * newest stable release; override via captcha.cap.widget_version. */ private const DEFAULT_WIDGET_VERSION = 'latest'; public function name(): string { return 'cap'; } public function isConfigured(): bool { return ! empty(config_cache('captcha.cap.endpoint')) && ! empty(config_cache('captcha.cap.sitekey')) && ! empty(config_cache('captcha.cap.secret')); } public function responseField(): string { return (string) config('captcha.cap.token_field', 'cap-token'); } /** * Compose the full Cap API endpoint: "{base}/{sitekey}/". * * The base URL is the instance origin without the site key. The site key is * appended as a path segment with a trailing slash (required by Cap). */ public function apiEndpoint(): string { $base = rtrim(trim((string) config_cache('captcha.cap.endpoint')), '/'); $sitekey = trim((string) config_cache('captcha.cap.sitekey'), '/ '); if ($base === '' || $sitekey === '') { return ''; } return $base.'/'.$sitekey.'/'; } public function verify(array $input): bool { $token = $input[$this->responseField()] ?? null; if (empty($token)) { return false; } $endpoint = $this->apiEndpoint(); if ($endpoint === '') { return false; } $cap = new Cap(app(HttpFactory::class), [ 'endpoint' => $endpoint, 'secret' => config_cache('captcha.cap.secret'), 'timeout' => (int) config('captcha.cap.timeout', 5), 'fail_open' => (bool) config('captcha.cap.fail_open', false), ]); return $cap->verify((string) $token); } public function render(array $attributes = []): string { $endpoint = e($this->apiEndpoint()); $field = e($this->responseField()); $attrs = ''; foreach ($attributes as $key => $value) { $attrs .= ' '.e($key).'="'.e($value).'"'; } return ''; } public function scripts(): string { // Load the widget from the jsDelivr CDN. Defaults to the "latest" // stable release; pin a specific version via captcha.cap.widget_version. $version = trim((string) config('captcha.cap.widget_version')) ?: self::DEFAULT_WIDGET_VERSION; $src = 'https://cdn.jsdelivr.net/npm/@cap.js/widget@'.$version; return ''; } }