KonstantinCodes / mautic-recaptcha

This Plugin brings reCAPTCHA integration to mautic.
GNU General Public License v3.0
50 stars 29 forks source link

Forms cannot be submitted after two minutes using v3 #36

Open coreyworrell opened 2 years ago

coreyworrell commented 2 years ago

According to the docs there is a 2 minute limit on a valid CAPTCHA, and it appears that this plugin executes the CAPTCHA on page load rather than when a form is actually submitted. If you load page, wait over 2 minutes, then try to submit, the CAPTCHA always fails.

coreyworrell commented 2 years ago

This seems to happen with the v2 invisible option as well.

godiez commented 2 years ago

Hi,

I run into this bug, but actually I got the first fail (timeout / duplicate), then a re-submit the form (without reload the page) and works fine.

remyPulse commented 2 years ago

https://developers.google.com/recaptcha/docs/v3

Note: reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action rather than on page load.

godiez commented 2 years ago

With this workaround

$onLoad = <<<JSELEMENT JSELEMENT; if ('v3' == $field['customParameters']['version']) { $onLoad = <<<JSELEMENT setInterval(function () { onLoad{$hashedFormName}(); }, 110000); JSELEMENT; }

I solved the two minutes expiring issue.

remyPulse commented 2 years ago

any hint about where you put this line ? thanks in advance :-)

godiez commented 2 years ago

Yeah, sure. On this file

Here's my full code on 'recaptcha.html.php' file:

<?php

$defaultInputClass = (isset($inputClass)) ? $inputClass : 'input';
$containerType     = 'div-wrapper';

include __DIR__.'/../../../../app/bundles/FormBundle/Views/Field/field_helper.php';

$action   = $app->getRequest()->get('objectAction');
$settings = $field['properties'];

$formName    = str_replace('_', '', $formName);
$hashedFormName = md5($formName);
$formButtons = (!empty($inForm)) ? $view->render(
    'MauticFormBundle:Builder:actions.html.php',
    [
        'deleted'        => false,
        'id'             => $id,
        'formId'         => $formId,
        'formName'       => $formName,
        'disallowDelete' => false,
    ]
) : '';

$label = (!$field['showLabel'])
    ? ''
    : <<<HTML
<label $labelAttr>{$view->escape($field['label'])}</label>
HTML;
$onLoad = <<<JSELEMENT
JSELEMENT;
if ('v3' == $field['customParameters']['version']) {
    $onLoad = <<<JSELEMENT
    setInterval(function () {
        onLoad{$hashedFormName}();
    }, 110000);
JSELEMENT;
}

$jsElement = <<<JSELEMENT
    <script type="text/javascript">
    $onLoad
    function verifyCallback_{$hashedFormName}( response ) {
        document.getElementById("mauticform_input_{$formName}_{$field['alias']}").value = response;
    }
    function onLoad{$hashedFormName}() { 
        grecaptcha.execute('{$field['customParameters']['site_key']}', {action: 'form'}).then(function(token) {
            verifyCallback_{$hashedFormName}(token);
         }); 
    }
</script>
JSELEMENT;

if($field['customParameters']['version'] == 'v2') {
$jsElement .= <<<JSELEMENT
<script src='https://www.google.com/recaptcha/api.js'></script>
JSELEMENT;
} else {
$jsElement .= <<<JSELEMENT
<script src='https://www.google.com/recaptcha/api.js?onload=onLoad{$hashedFormName}&render={$field['customParameters']['site_key']}'></script>
JSELEMENT;
}

$html = <<<HTML
    {$jsElement}
    <div $containerAttr>
        {$label}
HTML;

if($field['customParameters']['version'] == 'v2') {
$html .= <<<HTML
<div class="g-recaptcha" data-sitekey="{$field['customParameters']['site_key']}" data-callback="verifyCallback_{$hashedFormName}"></div>
HTML;
}

$html .= <<<HTML
        <input $inputAttr type="hidden">
        <span class="mauticform-errormsg" style="display: none;"></span>
    </div>
HTML;
?>

<?php
echo $html;
?>
kuzmany commented 1 year ago

I've create PR https://github.com/KonstantinCodes/mautic-recaptcha/pull/44