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.
+