Skip to content

Commit

Permalink
Add support for reCaptcha v3
Browse files Browse the repository at this point in the history
  • Loading branch information
ajibarra committed Apr 5, 2024
1 parent 1d93a14 commit 2f5cc10
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 4 deletions.
1 change: 1 addition & 0 deletions Docs/Documentation/Configuration.md
Expand Up @@ -54,6 +54,7 @@ and add this to your config/users.php file:
```php
'Users.reCaptcha.key' => 'YOUR RECAPTCHA KEY',
'Users.reCaptcha.secret' => 'YOUR RECAPTCHA SECRET',
'Users.reCaptcha.version' => '2', //defaults to version 2 (backward compatibility) but you can use version 3 which is recommended
'Users.reCaptcha.registration' => true, //enable on registration
'Users.reCaptcha.login' => true, //enable on login
```
Expand Down
2 changes: 2 additions & 0 deletions config/users.php
Expand Up @@ -71,6 +71,8 @@
'key' => null,
// reCaptcha secret
'secret' => null,
// reCaptcha version. keep 2 for backward compatibility
'version' => 2,
// use reCaptcha in registration
'registration' => false,
// use reCaptcha in login, valid values are false, true
Expand Down
50 changes: 47 additions & 3 deletions src/View/Helper/UserHelper.php
Expand Up @@ -167,11 +167,26 @@ public function addReCaptcha()
);
}
$this->addReCaptchaScript();
try {
$this->Form->unlockField('g-recaptcha-response');
} catch (\Exception $e) {
$version = Configure::read('Users.reCaptcha.version',2);
$method = "addReCaptchaV$version";
if (method_exists($this, $method)) {
try {
$this->Form->unlockField('g-recaptcha-response');
} catch (\Exception $e) {
}
return $this->{$method}();
}
throw new \InvalidArgumentException(__d('cake_d_c/users', 'reCaptcha version is wrong. Please configure Users.reCaptcha.version as 2 or 3'));

}

/**
* Add required element for reCaptcha v2
*
* @return string
*/
private function addReCaptchaV2()
{
return $this->Html->tag('div', '', [
'class' => 'g-recaptcha',
'data-sitekey' => Configure::read('Users.reCaptcha.key'),
Expand All @@ -181,6 +196,35 @@ public function addReCaptcha()
]);
}

/**
* Add required script for reCaptcha v3
*/
private function addReCaptchaV3()

Check failure on line 202 in src/View/Helper/UserHelper.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Method CakeDC\Users\View\Helper\UserHelper::addReCaptchaV3() has no return type specified.

Check failure on line 202 in src/View/Helper/UserHelper.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Method CakeDC\Users\View\Helper\UserHelper::addReCaptchaV3() has no return type specified.
{
$this->Html->script('CakeDC/Users.reCaptchaV3', [
'block' => 'script',
]);
}

/**
* Add required options for reCaptcha v3
*
* @return string
*/
public function button($title, $options = [])

Check failure on line 214 in src/View/Helper/UserHelper.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Method CakeDC\Users\View\Helper\UserHelper::button() has parameter $options with no type specified.

Check failure on line 214 in src/View/Helper/UserHelper.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Method CakeDC\Users\View\Helper\UserHelper::button() has parameter $title with no type specified.

Check failure on line 214 in src/View/Helper/UserHelper.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Method CakeDC\Users\View\Helper\UserHelper::button() has parameter $options with no type specified.

Check failure on line 214 in src/View/Helper/UserHelper.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Method CakeDC\Users\View\Helper\UserHelper::button() has parameter $title with no type specified.
{
if (($key = Configure::read('Users.reCaptcha.key')) && Configure::read('Users.reCaptcha.version', 2) === 3) {
$options = array_merge($options, [
'class' => 'g-recaptcha',
'data-sitekey' => $key,
'data-callback' => 'onSubmit',
'data-action' => 'submit',
]);
}

return $button = $this->Form->button($title, $options);
}

/**
* Generate a link if the target url is authorized for the logged in user
*
Expand Down
2 changes: 1 addition & 1 deletion templates/Users/register.php
Expand Up @@ -35,6 +35,6 @@
}
?>
</fieldset>
<?= $this->Form->button(__d('cake_d_c/users', 'Submit')) ?>
<?= $this->User->button(__d('cake_d_c/users', 'Submit')) ?>
<?= $this->Form->end() ?>
</div>
54 changes: 54 additions & 0 deletions tests/TestCase/View/Helper/UserHelperTest.php
Expand Up @@ -51,6 +51,15 @@ class UserHelperTest extends TestCase
*/
private $AuthLink;

/**
* @var (\Cake\View\View&\PHPUnit\Framework\MockObject\MockObject)|\PHPUnit\Framework\MockObject\MockObject
*/
private $View;

/**
* @var ServerRequest
*/
private $request;
/**
* setUp method
*
Expand Down Expand Up @@ -236,6 +245,51 @@ public function testAddReCaptcha()
$result = $this->User->addReCaptcha();
$this->assertEquals('<div class="g-recaptcha" data-sitekey="testKey" data-theme="light" data-size="normal" data-tabindex="3"></div>', $result);
}
/**
* Test add ReCaptcha V3
*
* @return void
*/
public function testAddReCaptchaV3()
{
$this->View->expects($this->exactly(2))
->method('append')
->willReturnMap([
['https://www.google.com/recaptcha/api.js', null],
['CakeDC/Users.reCaptchaV3', null]
]
);
Configure::write('Users.reCaptcha.key', 'testKey');
Configure::write('Users.reCaptcha.version', 3);
Configure::write('Users.reCaptcha.theme', 'light');
Configure::write('Users.reCaptcha.size', 'normal');
Configure::write('Users.reCaptcha.tabindex', '3');
$this->User->Form->create();
$result = $this->User->addReCaptcha();
}

public function testButton()
{
$title = 'test';
$options = ['test' => 'test'];
$this->assertEquals($this->User->Form->button($title, $options), $this->User->button($title, $options));

}

public function testButtonReCaptchaV3()
{
Configure::write('Users.reCaptcha.key', 'testKey');
Configure::write('Users.reCaptcha.version', 3);
$title = 'test';
$options = ['test' => 'test'];
$reCaptchaOptions = [
'class' => 'g-recaptcha',
'data-sitekey' => 'testKey',
'data-callback' => 'onSubmit',
'data-action' => 'submit',
];
$this->assertEquals($this->User->Form->button($title, array_merge($options, $reCaptchaOptions)), $this->User->button($title, $options));
}

/**
* Test add ReCaptcha field
Expand Down
3 changes: 3 additions & 0 deletions webroot/js/reCaptchaV3.js
@@ -0,0 +1,3 @@
function onSubmit(token) {
document.forms[0].submit()
}

0 comments on commit 2f5cc10

Please sign in to comment.