diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b946b9..624ae8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.3 + +- Custom or third party form validation + ## 1.0.2 - Action option added diff --git a/README.md b/README.md index eac5864..652db57 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ - Login - Register - Reset password +- Custom or third-party forms ![Cloudflare Turnstile](screenshot.png) @@ -69,6 +70,35 @@ Override the default action name by adding an action option: | Login | themes/{themeName}/templates/customer/_partials/login-form.tpl | | Reset password | themes/{themeName}/templates/customer/password-email.tpl | +### Protect a custom or third-party form + +1. Add the Cloudflare Turnstile widget in the Smarty form template: + +```html +{widget name='pixel_cloudflare_turnstile' action='custom-form'} +``` + +2. In a module, add a new hook to call Turnstile validation on form post: + +```php +public function install(): bool +{ + return parent::install() && + $this->registerHook('actionFrontControllerInitBefore'); +} + +public function hookActionFrontControllerInitBefore(array $params): void +{ + $controllerClass = get_class($params['controller']); + + if ($controllerClass === 'MyFormController' && Tools::isSubmit('myForm')) { + Pixel_cloudflare_turnstile::turnstileValidation(); + } +} +``` + +If the validation fails, the customer is redirected to the previous page with an error message. + ### Testing Use the following sitekeys and secret keys for testing purposes: diff --git a/pixel_cloudflare_turnstile.php b/pixel_cloudflare_turnstile.php index 1618e3f..3159346 100644 --- a/pixel_cloudflare_turnstile.php +++ b/pixel_cloudflare_turnstile.php @@ -34,7 +34,7 @@ class Pixel_cloudflare_turnstile extends Module implements WidgetInterface public function __construct() { $this->name = 'pixel_cloudflare_turnstile'; - $this->version = '1.0.2'; + $this->version = '1.0.3'; $this->author = 'Pixel Open'; $this->tab = 'front_office_features'; $this->need_instance = 0; @@ -247,9 +247,6 @@ protected function canProcess(string $controllerClass, bool $validate = false): return true; } - // Custom - // Add a new test here. @TODO Find a way to extend in an other module - return false; } @@ -271,7 +268,7 @@ public function isAvailable(string $form): bool * @return void * @throws Exception */ - protected function turnstileValidation(): void + public static function turnstileValidation(): void { $referer = $_SERVER['HTTP_REFERER'] ?? 'index'; $cookie = Context::getContext()->cookie; @@ -280,7 +277,7 @@ protected function turnstileValidation(): void if (!$response) { $cookie->__set( self::TURNSTILE_SESSION_ERROR_KEY, - $this->trans( + Context::getContext()->getTranslator()->trans( 'Please validate the security field.', [], 'Modules.Pixelcloudflareturnstile.Shop' @@ -290,7 +287,7 @@ protected function turnstileValidation(): void } $data = [ - 'secret' => $this->getSecretKey(), + 'secret' => Configuration::get(self::CONFIG_CLOUDFLARE_TURNSTILE_SECRET_KEY), 'response' => $response, ]; @@ -307,11 +304,11 @@ protected function turnstileValidation(): void if (!($result['success'] ?? false)) { $errors = $result['error-codes'] ?? ['unavailable']; foreach ($errors as $key => $errorCode) { - $errors[$key] = $this->getErrorMessage($errorCode); + $errors[$key] = self::getErrorMessage($errorCode); } $cookie->__set( self::TURNSTILE_SESSION_ERROR_KEY, - $this->trans( + Context::getContext()->getTranslator()->trans( 'Security validation error:', [], 'Modules.Pixelcloudflareturnstile.Shop' @@ -328,7 +325,7 @@ protected function turnstileValidation(): void * * @return string */ - protected function getErrorMessage(string $code): string + protected static function getErrorMessage(string $code): string { $messages = [ 'missing-input-secret' => 'the secret parameter was not passed.', @@ -485,7 +482,6 @@ protected function getConfigFields(): array 'value' => self::FORM_PASSWORD, 'name' => $this->trans('Reset Password', [], 'Modules.Pixelcloudflareturnstile.Admin'), ], - // Add a new custom form here. @TODO Find a way to extend in an other module ], 'id' => 'value', 'name' => 'name',