diff --git a/.env b/.env
index d9901f4..94c1108 100644
--- a/.env
+++ b/.env
@@ -83,3 +83,9 @@ MERCURE_TOPIC_BASE=https://escapepage.dev
USER_ID=1000
GROUP_ID=1000
###< docker ###
+
+###> karser/karser-recaptcha3-bundle ###
+# Get your API key and secret from https://g.co/recaptcha/v3
+RECAPTCHA3_KEY=my_site_key
+RECAPTCHA3_SECRET=my_secret
+###< karser/karser-recaptcha3-bundle ###
diff --git a/.idea/escapepage.iml b/.idea/escapepage.iml
index 5dca623..f193a03 100644
--- a/.idea/escapepage.iml
+++ b/.idea/escapepage.iml
@@ -140,6 +140,7 @@
+
diff --git a/.idea/php.xml b/.idea/php.xml
index 662274d..8907eaa 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -153,6 +153,7 @@
+
@@ -177,4 +178,4 @@
-
+
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 62d0f03..003805e 100644
--- a/composer.json
+++ b/composer.json
@@ -11,6 +11,7 @@
"doctrine/doctrine-bundle": "^2.16",
"doctrine/doctrine-migrations-bundle": "^3.4",
"doctrine/orm": "^3.5",
+ "karser/karser-recaptcha3-bundle": "^0.3.0",
"phpdocumentor/reflection-docblock": "^5.6",
"phpstan/phpdoc-parser": "^2.3",
"symfony/asset": "7.3.*",
diff --git a/composer.lock b/composer.lock
index 05f4ca8..0c5a553 100644
--- a/composer.lock
+++ b/composer.lock
@@ -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": "8e2419832c0841e325a5b748bde61a48",
+ "content-hash": "22d46e70bd8246939c294d28ecfff13d",
"packages": [
{
"name": "composer/semver",
@@ -1271,6 +1271,88 @@
],
"time": "2025-03-06T22:45:56+00:00"
},
+ {
+ "name": "karser/karser-recaptcha3-bundle",
+ "version": "v0.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/karser/KarserRecaptcha3Bundle.git",
+ "reference": "3d194dab4c31115bebc073c866ff55afaaa9e276"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/karser/KarserRecaptcha3Bundle/zipball/3d194dab4c31115bebc073c866ff55afaaa9e276",
+ "reference": "3d194dab4c31115bebc073c866ff55afaaa9e276",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": ">=8.1",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/form": "^6.4|^7.0|^8.0",
+ "symfony/framework-bundle": "^6.4|^7.0|^8.0",
+ "symfony/twig-bundle": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0",
+ "twig/twig": "^3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9|^10|^11",
+ "symfony/http-client": "^6.4|^7.0|^8.0"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Karser\\Recaptcha3Bundle\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Dmitrii Poddubnyi",
+ "homepage": "https://github.com/karser"
+ }
+ ],
+ "description": "Google ReCAPTCHA v3 for Symfony",
+ "homepage": "http://github.com/karser/KarserRecaptcha3Bundle",
+ "keywords": [
+ "Forms",
+ "Google ReCaptcha",
+ "GoogleReCaptcha",
+ "Symfony Google ReCaptcha",
+ "anti-bot",
+ "anti-bots",
+ "anti-spam",
+ "captcha",
+ "contact",
+ "google",
+ "google recaptcha v3",
+ "no-captcha",
+ "recaptcha",
+ "recaptcha v3",
+ "recaptcha v3 symfony",
+ "security",
+ "spam",
+ "symfony",
+ "symfony google recaptcha v3",
+ "symfony recaptcha",
+ "symfony recaptcha v3",
+ "validation"
+ ],
+ "support": {
+ "issues": "https://github.com/karser/KarserRecaptcha3Bundle/issues",
+ "source": "https://github.com/karser/KarserRecaptcha3Bundle/tree/v0.3.0"
+ },
+ "time": "2025-12-08T11:25:16+00:00"
+ },
{
"name": "lcobucci/jwt",
"version": "5.6.0",
diff --git a/config/bundles.php b/config/bundles.php
index a28579b..8a71d75 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -17,4 +17,5 @@ return [
Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
SymfonyCasts\Bundle\VerifyEmail\SymfonyCastsVerifyEmailBundle::class => ['all' => true],
SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle::class => ['all' => true],
+ Karser\Recaptcha3Bundle\KarserRecaptcha3Bundle::class => ['all' => true],
];
diff --git a/config/packages/karser_recaptcha3.yaml b/config/packages/karser_recaptcha3.yaml
new file mode 100644
index 0000000..71f4fcd
--- /dev/null
+++ b/config/packages/karser_recaptcha3.yaml
@@ -0,0 +1,5 @@
+karser_recaptcha3:
+ site_key: '%env(RECAPTCHA3_KEY)%'
+ secret_key: '%env(RECAPTCHA3_SECRET)%'
+ score_threshold: 0.5
+ enabled: true
diff --git a/config/packages/test/karser_recaptcha3.yaml b/config/packages/test/karser_recaptcha3.yaml
new file mode 100644
index 0000000..431f54e
--- /dev/null
+++ b/config/packages/test/karser_recaptcha3.yaml
@@ -0,0 +1,2 @@
+karser_recaptcha3:
+ enabled: false
diff --git a/src/Tech/Form/RegistrationFormType.php b/src/Tech/Form/RegistrationFormType.php
index 8bee2ce..9f24c6e 100644
--- a/src/Tech/Form/RegistrationFormType.php
+++ b/src/Tech/Form/RegistrationFormType.php
@@ -3,6 +3,8 @@
namespace App\Tech\Form;
use App\Tech\Entity\User;
+use Karser\Recaptcha3Bundle\Form\Recaptcha3Type;
+use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
@@ -40,6 +42,10 @@ class RegistrationFormType extends AbstractType
),
],
])
+ ->add('captcha', Recaptcha3Type::class, [
+ 'constraints' => new Recaptcha3(),
+ 'action_name' => 'registration',
+ ])
;
}
diff --git a/symfony.lock b/symfony.lock
index ac5be9a..e4e8709 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -35,6 +35,18 @@
"migrations/.gitignore"
]
},
+ "karser/karser-recaptcha3-bundle": {
+ "version": "0.3",
+ "recipe": {
+ "repo": "github.com/symfony/recipes-contrib",
+ "branch": "main",
+ "version": "0.1",
+ "ref": "c51ce07c10331d506762efe25b6f5843c1a5ea17"
+ },
+ "files": [
+ "./config/packages/karser_recaptcha3.yaml"
+ ]
+ },
"phpunit/phpunit": {
"version": "11.5",
"recipe": {
diff --git a/templates/tech/registration/register.html.twig b/templates/tech/registration/register.html.twig
index 05752e4..4cbe4ae 100644
--- a/templates/tech/registration/register.html.twig
+++ b/templates/tech/registration/register.html.twig
@@ -11,6 +11,7 @@
{{ form_row(registrationForm.email) }}
{{ form_row(registrationForm.username) }}
{{ form_row(registrationForm.plainPassword) }}
+ {{ form_row(registrationForm.captcha) }}
{{ form_end(registrationForm) }}