Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[!!!]FEATURE] Release new major version to switch to v2 of Friendlycaptcha #33

Merged
merged 13 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Classes/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

class Configuration
{
public const DEFAULT_JS_PATH = 'EXT:friendlycaptcha_official/Resources/Public/JavaScript/lib/widget-0.9.12.min.js';
public const DEFAULT_JS_PATH = 'EXT:friendlycaptcha_official/Resources/Public/JavaScript/lib/[email protected].min.js';

protected string $siteKey = '';
protected string $siteSecretKey = '';
protected string $puzzleUrl = '';
protected bool $useEuPuzzleEndpoint = false;
protected string $verifyUrl = '';
protected string $jsPath = '';
protected bool $skipDevValidation = false;
Expand All @@ -31,15 +31,15 @@ public function __construct(Site $site = null)
$siteConfiguration = $site->getConfiguration();
$this->siteKey = trim($siteConfiguration['friendlycaptcha_site_key'] ?? '');
$this->siteSecretKey = trim($siteConfiguration['friendlycaptcha_secret_key'] ?? '');
$this->puzzleUrl = trim($siteConfiguration['friendlycaptcha_puzzle_url'] ?? '');
$this->useEuPuzzleEndpoint = (bool)($siteConfiguration['friendlycaptcha_use_eu_puzzle_endpoint'] ?? false);
$this->verifyUrl = trim($siteConfiguration['friendlycaptcha_verify_url'] ?? '');
$this->jsPath = trim($siteConfiguration['friendlycaptcha_js_path'] ?? '');
$this->skipDevValidation = (bool)($siteConfiguration['friendlycaptcha_skip_dev_validation'] ?? false);
}

public function isEnabled(): bool
{
return $this->siteKey !== '' && $this->siteSecretKey !== '' && $this->puzzleUrl !== '' && $this->verifyUrl !== '' && !$this->hasSkipHeaderValidation();
return $this->siteKey !== '' && $this->siteSecretKey !== '' && $this->verifyUrl !== '' && !$this->hasSkipHeaderValidation();
}

public function getSiteKey(): string
Expand All @@ -52,9 +52,9 @@ public function getSiteSecretKey(): string
return $this->siteSecretKey;
}

public function getPuzzleUrl(): string
public function useEuPuzzleEndpoint(): bool
{
return $this->puzzleUrl;
return $this->useEuPuzzleEndpoint;
}

public function getVerifyUrl(): string
Expand Down
18 changes: 10 additions & 8 deletions Classes/Service/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function __construct(
$this->configuration = new Configuration();
}

public function verify(string $solution = ''): bool
public function verify(string $response = ''): bool
{
if ($this->configuration->hasSkipDevValidation()) {
return true;
Expand All @@ -39,17 +39,19 @@ public function verify(string $solution = ''): bool
return true;
}

$solution = $solution ?: $this->getSolutionFromRequest();
if (!$solution || !$this->configuration->isEnabled()) {
$response = $response ?: $this->getResponseFromRequest();
if (!$response || !$this->configuration->isEnabled()) {
return false;
}

$options = [
'headers' => ['Cache-Control' => 'no-cache'],
'headers' => [
'Cache-Control' => 'no-cache',
'X-API-Key' => $this->configuration->getSiteSecretKey(),
],
'allow_redirects' => true,
'form_params' => [
'secret' => $this->configuration->getSiteSecretKey(),
'solution' => $solution,
'response' => $response,
],
];

Expand Down Expand Up @@ -86,13 +88,13 @@ protected function request(string $method, string $url, array $options = [])
return $result->getBody()->getContents();
}

protected function getSolutionFromRequest(): string
protected function getResponseFromRequest(): string
{
/** @var ServerRequest $request */
$request = $GLOBALS['TYPO3_REQUEST'] ?? null;
if (!$request) {
return '';
}
return $request->getParsedBody()['frc-captcha-solution'] ?? $request->getQueryParams()['frc-captcha-solution'] ?? '';
return $request->getParsedBody()['frc-captcha-response'] ?? $request->getQueryParams()['frc-captcha-response'] ?? '';
}
}
19 changes: 2 additions & 17 deletions Classes/ViewHelpers/ConfigurationViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,22 @@
namespace StudioMitte\FriendlyCaptcha\ViewHelpers;

use StudioMitte\FriendlyCaptcha\Configuration;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;

class ConfigurationViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;

public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
public static function render()
{
$configuration = new Configuration();
return [
'languageIsoCode' => self::getLanguageIsoCode(),
'siteKey' => $configuration->getSiteKey(),
'verifyUrl' => $configuration->getVerifyUrl(),
'puzzleUrl' => $configuration->getPuzzleUrl(),
'useEuPuzzleEndpoint' => $configuration->useEuPuzzleEndpoint(),
'jsPath' => $configuration->getJsPath(),
'enabled' => $configuration->isEnabled(),
];
}

protected static function getLanguageIsoCode(): string
{
$language = $GLOBALS['TYPO3_REQUEST']->getAttribute('language');
if (!$language) {
return '';
}
if ((new Typo3Version())->getMajorVersion() >= 12) {
return $language->getLocale()->getLanguageCode();
}
return $language->getTwoLetterIsoCode();
}
}
2 changes: 1 addition & 1 deletion Configuration/PageTsConfig/powermail.typoscript
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Add FriendlyCaptcha field to Powermail
tx_powermail.flexForm.type.addFieldOptions {
friendlycaptcha = FriendlyCaptcha
friendlycaptcha = FriendlyCaptcha V2
}
14 changes: 6 additions & 8 deletions Configuration/SiteConfiguration/Overrides/sites.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,18 @@ static function () {
'placeholder' => 'A16UE6NICBMVQKG1I1BFMLBD56K53D3CS0L5N00AJNBT1R41P8O7N1KFMH',
],
];
$GLOBALS['SiteConfiguration']['site']['columns']['friendlycaptcha_puzzle_url'] = [
'label' => $lll . 'site.configuration.puzzle_url',
$GLOBALS['SiteConfiguration']['site']['columns']['friendlycaptcha_use_eu_puzzle_endpoint'] = [
'label' => $lll . 'site.configuration.puzzle_endpoint',
'config' => [
'type' => 'input',
'placeholder' => 'https://eu-api.friendlycaptcha.eu/api/v1/puzzle',
'default' => 'https://eu-api.friendlycaptcha.eu/api/v1/puzzle',
'type' => 'check',
],
];
$GLOBALS['SiteConfiguration']['site']['columns']['friendlycaptcha_verify_url'] = [
'label' => $lll . 'site.configuration.verify_url',
'config' => [
'type' => 'input',
'placeholder' => 'https://api.friendlycaptcha.com/api/v1/siteverify',
'default' => 'https://eu-api.friendlycaptcha.eu/api/v1/siteverify',
'placeholder' => 'https://global.frcapi.com/api/v2/captcha/siteverify',
'default' => 'https://global.frcapi.com/api/v2/captcha/siteverify',
],
];
$GLOBALS['SiteConfiguration']['site']['columns']['friendlycaptcha_js_path'] = [
Expand All @@ -48,6 +46,6 @@ static function () {
'type' => 'check',
],
];
$GLOBALS['SiteConfiguration']['site']['types']['0']['showitem'] .= ',--div--;' . $lll . 'site.configuration.tab, friendlycaptcha_site_key,friendlycaptcha_secret_key,friendlycaptcha_puzzle_url,friendlycaptcha_verify_url,friendlycaptcha_js_path,friendlycaptcha_skip_dev_validation,';
$GLOBALS['SiteConfiguration']['site']['types']['0']['showitem'] .= ',--div--;' . $lll . 'site.configuration.tab, friendlycaptcha_site_key,friendlycaptcha_secret_key,friendlycaptcha_use_eu_puzzle_endpoint,friendlycaptcha_verify_url,friendlycaptcha_js_path,friendlycaptcha_skip_dev_validation,';
}
);
2 changes: 1 addition & 1 deletion Configuration/Yaml/FormSetup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ TYPO3:

# Headline (appears as a title in the overview and above the form)
formEditor:
label: 'Friendly Captcha'
label: 'Friendly Captcha V2'
group: custom
groupSorting: 1010

Expand Down
3 changes: 3 additions & 0 deletions Documentation/Configuration/General.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ After creating the account, you need to setup a so called *Application*

Creation of an application

.. note::
This version on the Plugin supports only FriendlyCaptcha V2. The V2 version has to be enabled in your Application

and afterwards you need to create new a new *API Key*. Please copy the generated key as you need it later!

.. figure:: /Images/setup/apikey.png
Expand Down
3 changes: 3 additions & 0 deletions Documentation/Configuration/Integration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ A new tab **Friendly Captcha** is available which includes all configuration opt
This is described in the :ref:`using` section!


By default, the global endpoint `https://global.frcapi.com/api/v2/captcha/siteverify` is used.
If you prefer to use the EU endpoint, enter `https://eu.frcapi.com/api/v2/captcha/siteverify` in `Verify URL` field and ensure that the `Use EU Puzzle Endpoint` option is checked.

Working with automated tests
============================
If you are using automated tests you might want to skip the captcha.
Expand Down
Binary file modified Documentation/Images/configuration_site.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions Documentation/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ TYPO3 Extension friendlycaptcha_official
Installation/Index
Configuration/Index
Using/Index
V2_Migration/Index

.. Meta Menu

Expand Down
2 changes: 1 addition & 1 deletion Documentation/Introduction/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ What does it do?
================

This extension integrates the service of **Friendly Captcha** into your site by using the
official API.
official API. This version only supports **Friendly Captcha V2**. For **V1** support, please install an earlier version of the plugin.

Currently it supports the following form solutions:

Expand Down
2 changes: 1 addition & 1 deletion Documentation/Using/Custom.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The puzzle needs to be integrated into the form. This can be done like this in y
<f:if condition="{captchaConfiguration.enabled}">
<f:then>
<f:asset.script defer="1" async="1" identifier="friendlycaptcha" src="{captchaConfiguration.jsPath}" />
<div class="frc-captcha" data-sitekey="{captchaConfiguration.siteKey}" data-lang="{captchaConfiguration.languageIsoCode}" data-puzzle-endpoint="{captchaConfiguration.puzzleUrl}"></div>
<div class="frc-captcha" data-sitekey="{captchaConfiguration.siteKey}" {f:if(condition: '{captchaConfiguration.useEuPuzzleEndpoint}', then: 'data-api-endpoint="eu"')}></div>
</f:then>
<f:else>
<p>{f:translate(key:'LLL:EXT:friendlycaptcha_official/Resources/Private/Language/locallang.xlf:configuration_missing')}</p>
Expand Down
16 changes: 16 additions & 0 deletions Documentation/V2_Migration/Index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. include:: /Includes.rst.txt

.. _v2_migration:

============
Migration to FriendlyCaptcha V2
============

If you’re currently using an earlier version of the plugin with **Friendly Captcha V1** and want to switch to **Friendly Captcha V2**:

* Enable **V2** in yout Application in the Panel at https://friendlycaptcha.com/
* Install the newest version of the plugin (min v1.0)
* In TYPO3 backend, go to the *Site Management*/*Sites* module and switch to the **FriendlyCaptcha** tab. You need to change the URLs
**Puzzle Endpoint** - check it if you want to use the EU Endpoint
**Verify URL** - `https://global.frcapi.com/api/v2/captcha/siteverify` or `https://eu.frcapi.com/api/v2/captcha/siteverify` if you prefer to use EU endpoint
**JavaScript Path** - `EXT:friendlycaptcha_official/Resources/Public/JavaScript/lib/[email protected]`
2 changes: 1 addition & 1 deletion Resources/Private/Form/Partials/Friendlycaptcha.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
value="1"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<div class="frc-captcha" data-sitekey="{captchaConfiguration.siteKey}" data-lang="{captchaConfiguration.languageIsoCode}" data-puzzle-endpoint="{captchaConfiguration.puzzleUrl}"></div>
<div class="frc-captcha" data-sitekey="{captchaConfiguration.siteKey}" {f:if(condition: '{captchaConfiguration.useEuPuzzleEndpoint}', then: 'data-api-endpoint="eu"')}></div>
</f:render>
</f:then>
<f:else>
Expand Down
4 changes: 2 additions & 2 deletions Resources/Private/Language/Configuration.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
<trans-unit id="site.configuration.verify_url">
<source>Verify URL</source>
</trans-unit>
<trans-unit id="site.configuration.puzzle_url">
<source>Puzzle URL</source>
<trans-unit id="site.configuration.puzzle_endpoint">
<source>Use EU Puzzle Endpoint</source>
</trans-unit>
<trans-unit id="site.configuration.js_path">
<source>JavaScript Path</source>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<f:if condition="{captchaConfiguration.enabled}">
<f:then>
<f:asset.script defer="1" async="1" identifier="friendlycaptcha" src="{captchaConfiguration.jsPath}" />
<div class="frc-captcha" data-sitekey="{captchaConfiguration.siteKey}" data-lang="{captchaConfiguration.languageIsoCode}" data-puzzle-endpoint="{captchaConfiguration.puzzleUrl}"></div>
<div class="frc-captcha" data-sitekey="{captchaConfiguration.siteKey}" {f:if(condition: '{captchaConfiguration.useEuPuzzleEndpoint}', then: 'data-api-endpoint="eu"')}></div>
</f:then>
<f:else>
<p>{f:translate(key:'LLL:EXT:friendlycaptcha_official/Resources/Private/Language/locallang.xlf:configuration_missing')}</p>
Expand Down
7 changes: 7 additions & 0 deletions Resources/Public/JavaScript/lib/[email protected]

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Resources/Public/JavaScript/lib/widget-0.9.12.min.js

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion Tests/Unit/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function configurationIsBuiltCorrectly(): void
$configuration = new Configuration();
self::assertEquals('12345', $configuration->getSiteKey());
self::assertEquals('ABCDEF', $configuration->getSiteSecretKey());
self::assertEquals('https://puzzle', $configuration->getPuzzleUrl());
self::assertFalse($configuration->useEuPuzzleEndpoint());
self::assertEquals('https://verify,https://verify2', $configuration->getVerifyUrl());
self::assertEquals('https://verify', $configuration->getFirstVerifyUrl());
self::assertTrue($configuration->isEnabled());
Expand Down
12 changes: 6 additions & 6 deletions Tests/Unit/Service/ApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function verifyUrlIsCalledWithProperData(): void
{
self::setupRequest();
$GLOBALS['TYPO3_REQUEST'] = $GLOBALS['TYPO3_REQUEST']
->withParsedBody(['frc-captcha-solution' => '1234']);
->withParsedBody(['frc-captcha-response' => '1234']);
$historyContainer = [];
$client = $this->createClientWithHistory(
[new Response(200, [], '{"success": true}')],
Expand All @@ -52,15 +52,15 @@ public function solutionIsRetrieved(): void
self::setupRequest();
$mockedApi = $this->getAccessibleMock(Api::class, null, [], '', false);

self::assertSame('', $mockedApi->_call('getSolutionFromRequest'));
self::assertSame('', $mockedApi->_call('getResponseFromRequest'));

$GLOBALS['TYPO3_REQUEST'] = $GLOBALS['TYPO3_REQUEST']
->withQueryParams(['frc-captcha-solution' => '12345']);
self::assertSame('12345', $mockedApi->_call('getSolutionFromRequest'));
->withQueryParams(['frc-captcha-response' => '12345']);
self::assertSame('12345', $mockedApi->_call('getResponseFromRequest'));

$GLOBALS['TYPO3_REQUEST'] = $GLOBALS['TYPO3_REQUEST']
->withParsedBody(['frc-captcha-solution' => '1234']);
self::assertSame('1234', $mockedApi->_call('getSolutionFromRequest'));
->withParsedBody(['frc-captcha-response' => '1234']);
self::assertSame('1234', $mockedApi->_call('getResponseFromRequest'));
}

private function createClientWithHistory(array $responses, array &$historyContainer): Client
Expand Down
12 changes: 4 additions & 8 deletions Tests/Unit/ViewHelpers/ConfigurationViewHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use StudioMitte\FriendlyCaptcha\Tests\RequestTrait;
use StudioMitte\FriendlyCaptcha\ViewHelpers\ConfigurationViewHelper;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
use TYPO3\TestingFramework\Core\BaseTestCase;

class ConfigurationViewHelperTest extends BaseTestCase
Expand All @@ -19,17 +18,14 @@ class ConfigurationViewHelperTest extends BaseTestCase
public function viewHelperReturnsProperConfiguration()
{
self::setupRequest();
$configurationViewHelper = new ConfigurationViewHelper();

$renderingContext = new class () extends RenderingContext {
public function __construct() {}
};
self::assertSame([
'languageIsoCode' => 'en',
'siteKey' => '1234',
'verifyUrl' => 'https://verify,https://verify2',
'puzzleUrl' => 'https://puzzle',
'jsPath' => 'EXT:friendlycaptcha_official/Resources/Public/JavaScript/lib/widget-0.9.12.min.js',
'useEuPuzzleEndpoint' => false,
'jsPath' => 'EXT:friendlycaptcha_official/Resources/Public/JavaScript/lib/[email protected].min.js',
'enabled' => true,
], ConfigurationViewHelper::renderStatic([], static fn() => '', $renderingContext));
], $configurationViewHelper->render());
}
}
2 changes: 1 addition & 1 deletion ext_emconf.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
],
],
'state' => 'beta',
'version' => '0.1.8',
'version' => '2.0.0',
];