Files
conservatorio-tomadini/plugins/captcha/hcaptcha/hcaptcha.php
2024-12-17 17:34:10 +01:00

181 lines
5.3 KiB
PHP

<?php
/**
* @package Joomla.Plugin
* @subpackage Captcha
*
* @author Peter Martin
* @copyright Copyright 2016-2024 Peter Martin. All rights reserved.
* @license GNU General Public License version 2 or later
* @link https://data2site.com
*/
defined('_JEXEC') or die;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Factory;
use Joomla\CMS\Http\HttpFactory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Utilities\IpHelper;
/**
* hCaptcha Plugin
* Using the https://www.hcaptcha.com/ CAPTCHA service
*
* @since 1.0.0
*/
class PlgCaptchaHcaptcha extends CMSPlugin
{
/**
* Load the language file on instantiation.
*
* @var boolean
* @since 1.0.0
*/
protected $autoloadLanguage = true;
/**
* Application object.
*
* @var CMSApplication
* @since 4.0.0
*/
protected $app;
/**
* Reports the privacy related capabilities for this plugin to site administrators.
*
* @return array
*
* @since 1.0.0
*/
public function onPrivacyCollectAdminCapabilities()
{
$this->loadLanguage();
return [
Text::_('PLG_CAPTCHA_HCAPTCHA') => [
Text::_('PLG_CAPTCHA_HCAPTCHA_PRIVACY_CAPABILITY_IP_ADDRESS'),
]
];
}
/**
* Initialise the captcha
*
* @return boolean True on success, false otherwise
*
* @throws Exception
* @since 1.0.0
*/
public function onInit()
{
// If there is no Public Key set, then this plugin is no use, so exit
if ($this->params->get('publicKey', '') === '') {
throw new \RuntimeException(Text::_('PLG_CAPTCHA_HCAPTCHA_ERROR_NO_PUBLIC_KEY'));
}
// Load the JavaScript from hCaptcha
$this->app->getDocument()->getWebAssetManager()
->registerAndUseScript('plg_captcha_hcaptcha.api', 'https://hcaptcha.com/1/api.js', [], ['defer' => true]);
return true;
}
/**
* Gets the challenge HTML
*
* @param string $name The name of the field. Not Used.
* @param string $id The id of the field.
* @param string $class The class of the field.
*
* @return string The HTML to be embedded in the form.
* @throws Exception
* @since 1.0.0
*/
public function onDisplay($name = null, $id = 'hcaptcha', $class = '')
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$ele = $dom->createElement('div');
$ele->setAttribute('id', $id);
$ele->setAttribute('class', 'h-captcha required');
$ele->setAttribute('data-sitekey', $this->params->get('publicKey', ''));
$ele->setAttribute('data-theme', $this->params->get('theme', 'light'));
$ele->setAttribute('data-size', $this->params->get('size', 'normal'));
$dom->appendChild($ele);
return $dom->saveHTML($ele);
}
/**
* Calls an HTTP POST function to verify if the user's guess was correct
*
* @param string $code Answer provided by user. Not needed for the Hcaptcha implementation
*
* @return boolean
* @throws Exception
* @since 1.0.0
*/
public function onCheckAnswer($code = null)
{
$input = Factory::getApplication()->input;
$privateKey = $this->params->get('privateKey');
$remoteIp = IpHelper::getIp();
$hCaptchaResponse = $code ?? $input->get('h-captcha-response', '', 'cmd');
// Check for Private Key
if (empty($privateKey)) {
throw new \RuntimeException(Text::_('PLG_CAPTCHA_HCAPTCHA_ERROR_NO_PRIVATE_KEY'));
}
// Check for IP
if (empty($remoteIp)) {
throw new \RuntimeException(Text::_('PLG_CAPTCHA_HCAPTCHA_ERROR_NO_IP'));
}
if (empty($hCaptchaResponse)) {
throw new \RuntimeException(Text::_('PLG_CAPTCHA_HCAPTCHA_ERROR_EMPTY_SOLUTION'));
}
return $this->getResponse($privateKey, $remoteIp, $hCaptchaResponse);
}
/**
* Get the hCaptcha response.
*
* @param string $privateKey The private key for authentication.
* @param string $remoteIp The remote IP of the visitor.
* @param string $hCaptchaResponse The response received from Google.
*
* @return bool True if response is good | False if response is bad.
*
* @throws \RuntimeException
* @since 1.4.0
*/
private function getResponse(string $privateKey, string $remoteIp, string $hCaptchaResponse)
{
try {
$verifyResponse = HttpFactory::getHttp()->get(
'https://hcaptcha.com/siteverify?secret=' . $privateKey .
'&response=' . $hCaptchaResponse .
'&remoteip=' . $remoteIp
);
} catch (RuntimeException $e) {
throw new \RuntimeException(Text::_('PLG_CAPTCHA_HCAPTCHA_ERROR_CANT_CONNECT_TO_HCAPTCHA_SERVERS'));
}
if ($verifyResponse->code !== 200 || $verifyResponse->body === '') {
throw new \RuntimeException(Text::_('PLG_CAPTCHA_HCAPTCHA_ERROR_INVALID_RESPONSE'));
}
$responseData = json_decode($verifyResponse->body);
if ($responseData->success) {
return true;
}
throw new \RuntimeException(Text::_('PLG_CAPTCHA_HCAPTCHA_ERROR_INCORRECT_CAPTCHA'));
}
}