diff --git a/Classes/Controller/FrontendUserController.php b/Classes/Controller/FrontendUserController.php index 0dd7d60..d7f1696 100644 --- a/Classes/Controller/FrontendUserController.php +++ b/Classes/Controller/FrontendUserController.php @@ -7,6 +7,7 @@ use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory; use TYPO3\CMS\Core\Crypto\Random; use TYPO3\CMS\Core\Mail\MailMessage; +use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Http\ForwardResponse; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; @@ -43,6 +44,16 @@ public function newAction(?FrontendUser $newFrontendUser = null): ResponseInterf public function createAction(FrontendUser $newFrontendUser): ResponseInterface { + if ($this->settings['captcha']['sitekey'] !== '' && $this->settings['captcha']['secretkey'] !== '') { + if ($this->verifyCaptcha() === false) { + $this->addFlashMessage( + LocalizationUtility::translate('error.captcha', 'newsletterregistration'), + '', + ContextualFeedbackSeverity::ERROR + ); + return new ForwardResponse('new'); + } + } /** @var FrontendUser $existingFrontendUser */ $existingFrontendUser = $this->frontendUserRepository->findOneByEmailAndStoragePageId( $newFrontendUser->getEmail(), @@ -292,6 +303,43 @@ protected function getRandomPassword(): string return $hashInstance->getHashedPassword($randomPassword); } + protected function verifyCaptcha(): bool + { + $sitekey = $this->settings['captcha']['sitekey'] ?? ''; + $secretkey = $this->settings['captcha']['secretkey'] ?? ''; + + if (empty($secretkey)) { + return true; + } + + $parsedBody = $this->request->getParsedBody(); + $parsedBody = is_array($parsedBody) ? $parsedBody : []; + $solution = $parsedBody['frc-captcha-solution'] ?? ''; + if (empty($solution) || $solution === '.UNSTARTED' || $solution === '.FETCHING') { + return false; + } + + try { + $requestFactory = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\RequestFactory::class); + $response = $requestFactory->request( + 'https://eu-api.friendlycaptcha.eu/api/v1/siteverify', + 'POST', + [ + 'headers' => ['Content-Type' => 'application/json; charset=UTF-8'], + 'body' => json_encode([ + 'solution' => $solution, + 'secret' => $secretkey, + 'sitekey' => $sitekey, + ]), + ] + ); + $data = json_decode((string)$response->getBody(), true); + return ($data['success'] ?? false) === true; + } catch (\Throwable $e) { + return false; + } + } + protected function getHashedPassword(string $password): string { $hashInstance = GeneralUtility::makeInstance(PasswordHashFactory::class)->getDefaultHashInstance('FE'); diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript index bc087a8..5837289 100644 --- a/Configuration/TypoScript/setup.typoscript +++ b/Configuration/TypoScript/setup.typoscript @@ -14,6 +14,10 @@ plugin.tx_newsletterregistration { skipDefaultArguments = 1 } settings { + captcha { + sitekey = + secretkey = + } sender { name = My organization email = no_reply@example.org diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf index 0f88b68..c299524 100644 --- a/Resources/Private/Language/de.locallang.xlf +++ b/Resources/Private/Language/de.locallang.xlf @@ -159,6 +159,10 @@ Organisation Organisation + + Captcha verification failed. Please try again. + Captcha-Überprüfung fehlgeschlagen. Bitte versuchen Sie es erneut. + diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index 92b6d9e..e5a4466 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -118,6 +118,9 @@ Organisation + + Captcha verification failed. Please try again. + diff --git a/Resources/Private/Templates/FrontendUser/New.html b/Resources/Private/Templates/FrontendUser/New.html index 5330e7c..147232a 100644 --- a/Resources/Private/Templates/FrontendUser/New.html +++ b/Resources/Private/Templates/FrontendUser/New.html @@ -13,6 +13,32 @@ + + + +
+
+
+
+