101 lines
4.0 KiB
PHP
101 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace KupShop\ContentBundle\Util;
|
|
|
|
use KupShop\ContentBundle\View\Exception\ValidationException;
|
|
use KupShop\KupShopBundle\Context\DomainContext;
|
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
|
use KupShop\KupShopBundle\Util\Contexts;
|
|
use KupShop\RecaptchaBundle\Util\RecaptchaGCloudUtil;
|
|
use ReCaptcha\ReCaptcha;
|
|
use ReCaptcha\RequestMethod\Post;
|
|
|
|
class Captcha
|
|
{
|
|
/**
|
|
* @param null $data
|
|
* @param null $type One of null, 'shared', 'invisible', 'default'
|
|
*
|
|
* @throws ValidationException
|
|
*/
|
|
public static function checkCaptcha($data = null, $type = null)
|
|
{
|
|
if (isFunctionalTests()) {
|
|
return true;
|
|
}
|
|
|
|
if ($captcha = getVal('captcha', $data)) {
|
|
if ($captcha != generateCaptcha(getVal('captcha_id', $data))) {
|
|
throw new ValidationException(translate('errorCaptcha', 'form'));
|
|
}
|
|
} elseif ($captcha = getVal('g-recaptcha-response', $data)) {
|
|
if (findModule(\Modules::RECAPTCHA, \Modules::SUB_GCLOUD)) {
|
|
$util = ServiceContainer::getService(RecaptchaGCloudUtil::class);
|
|
if (!$util->validate(token: $captcha, type: $type ?: getVal('recaptcha', $data))) {
|
|
throw new ValidationException(translate('errorCaptcha', 'form'));
|
|
}
|
|
} else {
|
|
$key = self::getCaptchaType($type ?: getVal('recaptcha', $data));
|
|
$recaptcha = new ReCaptcha(findModule('recaptcha', $key));
|
|
$resp = $recaptcha->verify($captcha, $_SERVER['REMOTE_ADDR']);
|
|
if (!$resp->isSuccess()) {
|
|
throw new ValidationException(translate('errorCaptcha', 'form'));
|
|
}
|
|
if ($type == 'shared' && isProduction()) {
|
|
$domainContext = ServiceContainer::getService(DomainContext::class);
|
|
if (array_search($resp->getHostname(), $domainContext->getSupported()) === false) {
|
|
throw new ValidationException('Invalid CAPTCHA domain');
|
|
}
|
|
}
|
|
}
|
|
} elseif ($captcha = getVal('wpj-captcha-response', $data)) {
|
|
$requestMethod = new Post('https://challenges.cloudflare.com/turnstile/v0/siteverify');
|
|
$recaptcha = new ReCaptcha(findModule('recaptcha', 'secret_cloudflare'), $requestMethod);
|
|
|
|
$resp = $recaptcha->verify($captcha, $_SERVER['REMOTE_ADDR']);
|
|
|
|
if (!$resp->isSuccess()) {
|
|
throw new ValidationException(translate('errorCaptcha', 'form'));
|
|
}
|
|
|
|
if (isProduction()) {
|
|
$domains = Contexts::get(DomainContext::class)->getSupported();
|
|
if (!in_array($resp->getHostname(), $domains)) {
|
|
throw new ValidationException('Invalid CAPTCHA domain');
|
|
}
|
|
}
|
|
} elseif ($captcha = getVal('wpj-captcha-invisible-response', $data)) {
|
|
$requestMethod = new Post('https://challenges.cloudflare.com/turnstile/v0/siteverify');
|
|
$recaptcha = new ReCaptcha(findModule('recaptcha', 'secret_cloudflare_invisible'), $requestMethod);
|
|
|
|
$resp = $recaptcha->verify($captcha, $_SERVER['REMOTE_ADDR']);
|
|
|
|
if (!$resp->isSuccess()) {
|
|
throw new ValidationException(translate('errorCaptcha', 'form'));
|
|
}
|
|
|
|
if (isProduction()) {
|
|
$domains = Contexts::get(DomainContext::class)->getSupported();
|
|
if (!in_array($resp->getHostname(), $domains)) {
|
|
throw new ValidationException('Invalid CAPTCHA domain');
|
|
}
|
|
}
|
|
} else {
|
|
throw new ValidationException(translate('errorCaptcha', 'form'));
|
|
}
|
|
}
|
|
|
|
protected static function getCaptchaType($type)
|
|
{
|
|
switch ($type) {
|
|
case 'invisible':
|
|
return 'secret_invisible';
|
|
case 'shared':
|
|
return 'secret_shared';
|
|
|
|
default:
|
|
return 'secret';
|
|
}
|
|
}
|
|
}
|