feat: captcha protection for ep-events

This commit is contained in:
Björn Fromme
2024-08-19 11:11:09 +02:00
parent e6c4948644
commit e2bc3f72da
14 changed files with 200 additions and 64 deletions
+1
View File
@@ -28,6 +28,7 @@
"league/csv": "^9.2",
"league/period": "^4.9",
"lochmueller/staticfilecache": "^12.5",
"sjbr/sr-freecap": "^2.6",
"ssch/typo3-encore": "^3.0",
"symfony/http-client": "^4.3",
"symfony/options-resolver": "^4.2",
Generated
+103 -61
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "81e82ebeb975c1f1a71ab3938cc49b02",
"content-hash": "f4b99aa9b07e56210c516195545a1d40",
"packages": [
{
"name": "b13/container",
@@ -2896,6 +2896,48 @@
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "sjbr/sr-freecap",
"version": "v2.6.2",
"source": {
"type": "git",
"url": "https://codeberg.org/sjbr/sr-freecap",
"reference": "cbdc34f79c9d18a5fb88080a07b4fc99589c490c"
},
"require": {
"typo3/cms-core": "^10.4"
},
"replace": {
"typo3-ter/sr-freecap": "self.version"
},
"type": "typo3-cms-extension",
"autoload": {
"psr-4": {
"SJBR\\SrFreecap\\": "Classes/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-or-later"
],
"authors": [
{
"name": "Stanislas Rolland",
"homepage": "http://www.sjbr.ca",
"role": "Developer"
}
],
"description": "A TYPO3 integration of freeCap CAPTCHA.",
"homepage": "https://forge.typo3.org/projects/extension-sr_freecap",
"keywords": [
"captcha",
"typo3"
],
"support": {
"issues": "https://forge.typo3.org/projects/extension-sr_freecap/issues"
},
"time": "2020-12-26T16:51:50+00:00"
},
{
"name": "ssch/typo3-encore",
"version": "v3.0.9",
@@ -3045,16 +3087,16 @@
},
{
"name": "symfony/cache",
"version": "v5.4.40",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/cache.git",
"reference": "89005bc368ca02ed0433c592e4d27670d0844a66"
"reference": "6f5f750692bd5a212e01a4f1945fd856bceef89e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/cache/zipball/89005bc368ca02ed0433c592e4d27670d0844a66",
"reference": "89005bc368ca02ed0433c592e4d27670d0844a66",
"url": "https://api.github.com/repos/symfony/cache/zipball/6f5f750692bd5a212e01a4f1945fd856bceef89e",
"reference": "6f5f750692bd5a212e01a4f1945fd856bceef89e",
"shasum": ""
},
"require": {
@@ -3122,7 +3164,7 @@
"psr6"
],
"support": {
"source": "https://github.com/symfony/cache/tree/v5.4.40"
"source": "https://github.com/symfony/cache/tree/v5.4.42"
},
"funding": [
{
@@ -3138,7 +3180,7 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-07-10T06:02:18+00:00"
},
{
"name": "symfony/cache-contracts",
@@ -3300,16 +3342,16 @@
},
{
"name": "symfony/console",
"version": "v5.4.41",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "6473d441a913cb997123b59ff2dbe3d1cf9e11ba"
"reference": "cef62396a0477e94fc52e87a17c6e5c32e226b7f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/6473d441a913cb997123b59ff2dbe3d1cf9e11ba",
"reference": "6473d441a913cb997123b59ff2dbe3d1cf9e11ba",
"url": "https://api.github.com/repos/symfony/console/zipball/cef62396a0477e94fc52e87a17c6e5c32e226b7f",
"reference": "cef62396a0477e94fc52e87a17c6e5c32e226b7f",
"shasum": ""
},
"require": {
@@ -3379,7 +3421,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v5.4.41"
"source": "https://github.com/symfony/console/tree/v5.4.42"
},
"funding": [
{
@@ -3395,20 +3437,20 @@
"type": "tidelift"
}
],
"time": "2024-06-28T07:48:55+00:00"
"time": "2024-07-26T12:21:55+00:00"
},
{
"name": "symfony/dependency-injection",
"version": "v5.4.40",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "408b33326496030c201b8051b003e9e8cdb2efc9"
"reference": "c8409889fdbf48b99271930ea0ebcf3ee5e1ceae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/408b33326496030c201b8051b003e9e8cdb2efc9",
"reference": "408b33326496030c201b8051b003e9e8cdb2efc9",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/c8409889fdbf48b99271930ea0ebcf3ee5e1ceae",
"reference": "c8409889fdbf48b99271930ea0ebcf3ee5e1ceae",
"shasum": ""
},
"require": {
@@ -3468,7 +3510,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.40"
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.42"
},
"funding": [
{
@@ -3484,7 +3526,7 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-07-25T13:57:40+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -3849,16 +3891,16 @@
},
{
"name": "symfony/finder",
"version": "v5.4.40",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "f51cff4687547641c7d8180d74932ab40b2205ce"
"reference": "0724c51fa067b198e36506d2864e09a52180998a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/f51cff4687547641c7d8180d74932ab40b2205ce",
"reference": "f51cff4687547641c7d8180d74932ab40b2205ce",
"url": "https://api.github.com/repos/symfony/finder/zipball/0724c51fa067b198e36506d2864e09a52180998a",
"reference": "0724c51fa067b198e36506d2864e09a52180998a",
"shasum": ""
},
"require": {
@@ -3892,7 +3934,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v5.4.40"
"source": "https://github.com/symfony/finder/tree/v5.4.42"
},
"funding": [
{
@@ -3908,7 +3950,7 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-07-22T08:53:29+00:00"
},
{
"name": "symfony/http-client",
@@ -4072,16 +4114,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v5.4.40",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "cf4893ca4eca3fac4ae06da1590afdbbb4217847"
"reference": "9c375b2abef0b657aa0b7612b763df5c12a465ab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/cf4893ca4eca3fac4ae06da1590afdbbb4217847",
"reference": "cf4893ca4eca3fac4ae06da1590afdbbb4217847",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/9c375b2abef0b657aa0b7612b763df5c12a465ab",
"reference": "9c375b2abef0b657aa0b7612b763df5c12a465ab",
"shasum": ""
},
"require": {
@@ -4128,7 +4170,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-foundation/tree/v5.4.40"
"source": "https://github.com/symfony/http-foundation/tree/v5.4.42"
},
"funding": [
{
@@ -4144,7 +4186,7 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-07-26T11:59:59+00:00"
},
{
"name": "symfony/inflector",
@@ -5380,16 +5422,16 @@
},
{
"name": "symfony/property-info",
"version": "v5.4.41",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/property-info.git",
"reference": "2c96c24961cab73bdc9020809bd82bdadd1a10f2"
"reference": "825aa937f6e8cd63dcc118d0af84d7d4979cddf4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/property-info/zipball/2c96c24961cab73bdc9020809bd82bdadd1a10f2",
"reference": "2c96c24961cab73bdc9020809bd82bdadd1a10f2",
"url": "https://api.github.com/repos/symfony/property-info/zipball/825aa937f6e8cd63dcc118d0af84d7d4979cddf4",
"reference": "825aa937f6e8cd63dcc118d0af84d7d4979cddf4",
"shasum": ""
},
"require": {
@@ -5451,7 +5493,7 @@
"validator"
],
"support": {
"source": "https://github.com/symfony/property-info/tree/v5.4.41"
"source": "https://github.com/symfony/property-info/tree/v5.4.42"
},
"funding": [
{
@@ -5467,20 +5509,20 @@
"type": "tidelift"
}
],
"time": "2024-06-09T07:25:10+00:00"
"time": "2024-07-22T18:03:36+00:00"
},
{
"name": "symfony/routing",
"version": "v5.4.40",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "6df1dd8b306649303267a760699cf04cf39b1f7b"
"reference": "f8dd6f80c96aeec9b13fc13757842342e05c4878"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/6df1dd8b306649303267a760699cf04cf39b1f7b",
"reference": "6df1dd8b306649303267a760699cf04cf39b1f7b",
"url": "https://api.github.com/repos/symfony/routing/zipball/f8dd6f80c96aeec9b13fc13757842342e05c4878",
"reference": "f8dd6f80c96aeec9b13fc13757842342e05c4878",
"shasum": ""
},
"require": {
@@ -5541,7 +5583,7 @@
"url"
],
"support": {
"source": "https://github.com/symfony/routing/tree/v5.4.40"
"source": "https://github.com/symfony/routing/tree/v5.4.42"
},
"funding": [
{
@@ -5557,7 +5599,7 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-07-09T20:57:15+00:00"
},
{
"name": "symfony/serializer",
@@ -5738,16 +5780,16 @@
},
{
"name": "symfony/string",
"version": "v5.4.41",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "065a9611e0b1fd2197a867e1fb7f2238191b7096"
"reference": "909cec913edea162a3b2836788228ad45fcab337"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/065a9611e0b1fd2197a867e1fb7f2238191b7096",
"reference": "065a9611e0b1fd2197a867e1fb7f2238191b7096",
"url": "https://api.github.com/repos/symfony/string/zipball/909cec913edea162a3b2836788228ad45fcab337",
"reference": "909cec913edea162a3b2836788228ad45fcab337",
"shasum": ""
},
"require": {
@@ -5804,7 +5846,7 @@
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v5.4.41"
"source": "https://github.com/symfony/string/tree/v5.4.42"
},
"funding": [
{
@@ -5820,20 +5862,20 @@
"type": "tidelift"
}
],
"time": "2024-06-28T09:20:55+00:00"
"time": "2024-07-20T18:38:32+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v5.4.40",
"version": "v5.4.42",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "af8868a6e9d6082dfca11f1a1f205ae93a8b6d93"
"reference": "0c17c56d8ea052fc33942251c75d0e28936e043d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/af8868a6e9d6082dfca11f1a1f205ae93a8b6d93",
"reference": "af8868a6e9d6082dfca11f1a1f205ae93a8b6d93",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/0c17c56d8ea052fc33942251c75d0e28936e043d",
"reference": "0c17c56d8ea052fc33942251c75d0e28936e043d",
"shasum": ""
},
"require": {
@@ -5893,7 +5935,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v5.4.40"
"source": "https://github.com/symfony/var-dumper/tree/v5.4.42"
},
"funding": [
{
@@ -5909,7 +5951,7 @@
"type": "tidelift"
}
],
"time": "2024-05-31T14:33:22+00:00"
"time": "2024-07-26T12:23:09+00:00"
},
{
"name": "symfony/var-exporter",
@@ -6551,16 +6593,16 @@
},
{
"name": "typo3/cms-composer-installers",
"version": "v3.1.3",
"version": "v3.1.4",
"source": {
"type": "git",
"url": "https://github.com/TYPO3/CmsComposerInstallers.git",
"reference": "613d82075650ba846d287e20941e8a0e04ad0444"
"reference": "29fb214976fe05f39c7d0619ce1d648d59c50a08"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/TYPO3/CmsComposerInstallers/zipball/613d82075650ba846d287e20941e8a0e04ad0444",
"reference": "613d82075650ba846d287e20941e8a0e04ad0444",
"url": "https://api.github.com/repos/TYPO3/CmsComposerInstallers/zipball/29fb214976fe05f39c7d0619ce1d648d59c50a08",
"reference": "29fb214976fe05f39c7d0619ce1d648d59c50a08",
"shasum": ""
},
"require": {
@@ -6620,9 +6662,9 @@
"support": {
"general": "https://typo3.org/support/",
"issues": "https://github.com/TYPO3/CmsComposerInstallers/issues",
"source": "https://github.com/TYPO3/CmsComposerInstallers/tree/v3.1.3"
"source": "https://github.com/TYPO3/CmsComposerInstallers/tree/v3.1.4"
},
"time": "2022-08-05T19:06:26+00:00"
"time": "2024-08-13T14:56:37+00:00"
},
{
"name": "typo3/cms-core",
@@ -136,8 +136,7 @@ class AjaxFormController extends ActionController implements LoggerAwareInterfac
];
if ($this->arguments->validate()->hasErrors()) {
foreach ($this->arguments->validate()->getFlattenedErrors() as $key => $errors)
{
foreach ($this->arguments->validate()->getFlattenedErrors() as $key => $errors) {
$key = str_replace('.', '', $key);
$errorsRaw = [];
foreach ($errors as $error)
@@ -33,6 +33,13 @@ class Inquiry extends AbstractValueObject
{
public const TOKEN_KEY = 'inquiry_form';
/**
* @var string
*
* @TYPO3\CMS\Extbase\Annotation\Validate("SJBR\SrFreecap\Validation\Validator\CaptchaValidator")
*/
protected $captchaResponse;
/**
* @var string
*/
@@ -226,6 +233,22 @@ class Inquiry extends AbstractValueObject
$this->token = $token;
}
/**
* @return string
*/
public function getCaptchaResponse()
{
return $this->captchaResponse;
}
/**
* @param string $captchaResponse
*/
public function setCaptchaResponse(string $captchaResponse)
{
$this->captchaResponse = $captchaResponse;
}
/**
* @return string
*/
@@ -0,0 +1 @@
@import 'EXT:sr_freecap/Configuration/TypoScript/setup.typoscript'
@@ -68,3 +68,4 @@ plugin.tx_epevents {
@import 'EXT:fluid_styled_content/Configuration/TypoScript/constants.typoscript'
@import 'EXT:seo/Configuration/TypoScript/XmlSitemap/constants.typoscript'
@import 'EXT:news/Configuration/TypoScript/constants.txt'
@import 'EXT:sr_freecap/Configuration/TypoScript/constants.typoscript'
@@ -160,6 +160,7 @@
this.processing = false;
if (response.status === 'validation') {
this.formErrors = response.errors;
$('.tx-srfreecap-cant-read > a').click();
} else {
this.success = true;
this.$session.remove('formData');
@@ -38,6 +38,7 @@
this.processing = false;
if (response.status === 'validation') {
this.formErrors = response.errors;
$('.tx-srfreecap-cant-read > a').click();
} else {
this.success = true;
this.trackConversion();
@@ -88,6 +88,7 @@
.form__item__error {
padding: 8px;
font-size: 90%;
color: $color-formerror;
}
.form__field {
@@ -252,3 +253,12 @@
color: white;
}
}
.tx-srfreecap-cant-read {
color: white;
font-size: 80%;
}
img.tx-srfreecap-image {
margin: 0 16px 16px 0;
}
@@ -91,6 +91,9 @@
<trans-unit id="tx_epevents.message.email.1221559976">
<target>Ungültige E-Mail Adresse</target>
</trans-unit>
<trans-unit id="tx_epevents.message.captchaResponse.9221561048">
<target>Die eingegebenen Zeichen stimmen nicht mit der Grafik überein</target>
</trans-unit>
<trans-unit id="tx_epevents_domain_model_traveltype">
<target>Reiseart</target>
</trans-unit>
@@ -106,6 +109,9 @@
<trans-unit id="tx_epevents.message.inquiryemail.1221559976">
<target>Ungültige E-Mail Adresse</target>
</trans-unit>
<trans-unit id="tx_epevents.message.inquirycaptchaResponse.9221561048">
<target>Die eingegebenen Zeichen stimmen nicht mit der Grafik überein</target>
</trans-unit>
<trans-unit id="tx_epevents.label.ask_our_expert">
<target>Frag unseren Profi</target>
</trans-unit>
@@ -91,6 +91,9 @@
<trans-unit id="tx_epevents.message.email.1221559976">
<source>The email address is invalid</source>
</trans-unit>
<trans-unit id="tx_epevents.message.captchaResponse.9221561048">
<source>The entered characters dont match</source>
</trans-unit>
<trans-unit id="tx_epevents_domain_model_traveltype">
<source>Type of travel</source>
</trans-unit>
@@ -106,6 +109,9 @@
<trans-unit id="tx_epevents.message.inquiryemail.1221559976">
<source>The email address is invalid</source>
</trans-unit>
<trans-unit id="tx_epevents.message.inquirycaptchaResponse.9221561048">
<source>The entered characters dont match</source>
</trans-unit>
<trans-unit id="tx_epevents.label.ask_our_expert">
<source>Ask our expert</source>
</trans-unit>
@@ -1,6 +1,7 @@
<html data-namespace-typo3-fluid="true" lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
xmlns:freeCap="http://typo3.org/ns/SJBR/SrFreecap/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:layout name="Default"/>
@@ -169,7 +170,7 @@
</div>
<div class="form__item form__item--button form__item--tablet">
<button class="button button--configurator"
@click.prevent="submitForm">&raquo; {f:translate(key: 'tx_epevents.label.inquire_now', extensionName: 'ep_events') -> f:format.raw())}</button>
@click.prevent="submitForm">&raquo; {f:translate(key: 'tx_epevents.label.inquire_now', extensionName: 'ep_events') -> f:format.raw()}</button>
</div>
<f:if condition="{settings.feedbackPageUid}">
<div class="form__item form__item--link form__item--tablet">
@@ -210,6 +211,20 @@
placeholder="{f:translate(key: 'tx_epevents.label.contact_form_message', extensionName: 'ep_events') -> f:format.raw()}"
additionalAttributes="{v-model: 'formData.message'}"/>
</div>
<div class="form__item">
<span class="form__text">Bitte geben Sie die Zeichen aus der nachfolgenden Grafik ein.</span>
</div>
<div class="form__item" :class="{ 'has-errors': formErrors.inquirycaptchaResponse }">
<f:form.textfield class="form__field form__field--configurator form__field--text"
property="captchaResponse" size="15"
placeholder="Spamschutz"
additionalAttributes="{v-model: 'formData.captchaResponse'}"
title="{freeCap:translate(key: 'notice')}{freeCap:translate(key: 'explain')}" />
<div class="form__item__error" v-show="formErrors.inquirycaptchaResponse" v-html="formErrors.inquirycaptchaResponse"></div>
</div>
<div class="form__item">
<freeCap:image />
</div>
<div class="form__item form__item--mobile">
<span class="form__text">
{f:translate(key: 'tx_epevents.label.privacy_text', arguments: '{0: \'{f:uri.typolink(parameter: settings.dataProtectionPageUid)}\'}', extensionName: 'ep_events') -> f:format.raw()}
@@ -1,6 +1,7 @@
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:freeCap="http://typo3.org/ns/SJBR/SrFreecap/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpEvents/ViewHelpers">
<f:layout name="Default"/>
@@ -92,6 +93,20 @@
placeholder="{f:translate(key: 'tx_epevents.label.contact_form_message', extensionName: 'ep_events') -> f:format.raw()}"
additionalAttributes="{v-model: 'formData.message'}"/>
</div>
<div class="form__item">
<f:form.textfield class="form__field form__field--text"
property="captchaResponse" size="15"
placeholder="Spamschutz"
additionalAttributes="{v-model: 'formData.captchaResponse'}"
title="{freeCap:translate(key: 'notice')}{freeCap:translate(key: 'explain')}" />
<div class="form__item__error" v-show="formErrors.inquirycaptchaResponse" v-html="formErrors.inquirycaptchaResponse"></div>
</div>
<div class="form__item form__item--text">
<span class="form__text">Bitte geben Sie die Zeichen aus der nachfolgenden Grafik ein.</span>
</div>
<div class="form__item">
<freeCap:image />
</div>
<div class="form__item">
<span class="form__text">{f:translate(key: 'tx_epevents.label.privacy_text', arguments: '{0: \'{f:uri.typolink(parameter: settings.dataProtectionPageUid)}\'}', extensionName: 'ep_events') -> f:format.raw()}</span>
</div>
@@ -1,5 +1,6 @@
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:freeCap="http://typo3.org/ns/SJBR/SrFreecap/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpEvents/ViewHelpers">
<f:layout name="Default"/>
@@ -78,6 +79,20 @@
placeholder="{f:translate(key: 'tx_epevents.label.contact_form_message', extensionName: 'ep_events') -> f:format.raw()}"
additionalAttributes="{v-model: 'formData.message'}"/>
</div>
<div class="form__item">
<f:form.textfield class="form__field form__field--text"
property="captchaResponse" size="15"
placeholder="Spamschutz"
additionalAttributes="{v-model: 'formData.captchaResponse'}"
title="{freeCap:translate(key: 'notice')}{freeCap:translate(key: 'explain')}" />
<div class="form__item__error" v-show="formErrors.inquirycaptchaResponse" v-html="formErrors.inquirycaptchaResponse"></div>
</div>
<div class="form__item form__item--text">
<span class="form__text">Bitte geben Sie die Zeichen aus der nachfolgenden Grafik ein.</span>
</div>
<div class="form__item">
<freeCap:image />
</div>
<div class="form__item">
<span class="form__text">{f:translate(key: 'tx_epevents.label.privacy_text', arguments: '{0: \'{f:uri.typolink(parameter: settings.dataProtectionPageUid)}\'}', extensionName: 'ep_events') -> f:format.raw()}</span>
</div>