Skip to content

Commit

Permalink
Add Google reCaptcha feature
Browse files Browse the repository at this point in the history
  • Loading branch information
sonvnn committed Dec 8, 2024
1 parent 12647ea commit 8aea58c
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 19 deletions.
15 changes: 4 additions & 11 deletions framework/elements/formbuilder/ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
$mail = Factory::getContainer()->get(MailerFactoryInterface::class)->createMailer();
$message = $params->get('email_body', '');
$email_headers = $params->get('email_headers', '');
$gcaptcha = '';
$gcaptcha = $mainframe->input->post->get('g-recaptcha-response');

foreach ($asformbuilder as $field => $value) {
$message = str_replace('{{'.$field.'}}', $value, $message);
Expand All @@ -61,19 +61,12 @@
if (intval($params->get('enable_captcha', 0))) {
$captcha_type = $params->get('captcha_type', 'default');
if ($captcha_type == 'recaptcha' || $captcha_type == 'recaptcha_invisible') {

if($gcaptcha == ''){
throw new \Exception(Text::_('ASTROID_AJAX_ERROR_INVALID_CAPTCHA'));
} else {
if($captcha_type == 'recaptcha_invisible') {
PluginHelper::importPlugin('captcha', 'recaptcha_invisible');
} else {
PluginHelper::importPlugin('captcha', 'recaptcha');
}
$dispatcher = Factory::getApplication()->getDispatcher();
$event = new Joomla\Event\Event('onCheckAnswer', [$gcaptcha]);
$res = $dispatcher->dispatch('onCheckAnswer', $event);

if (!$res[0]) {
$res = Helper::verifyGoogleCaptcha($gcaptcha);
if (!$res) {
throw new \Exception(Text::_('ASTROID_AJAX_ERROR_INVALID_CAPTCHA'));
}
}
Expand Down
13 changes: 8 additions & 5 deletions framework/elements/formbuilder/formbuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Joomla\CMS\Uri\Uri;
use Astroid\Helper\Style;
use Astroid\Helper;
use Astroid\Framework;

extract($displayData);

Expand Down Expand Up @@ -53,6 +54,7 @@
}
}

$document = Framework::getDocument();
$show_label = $params->get('show_label', 1);

echo '<form class="as-form-builder mt-4" method="post" action="'.Uri::root().'index.php?option=com_ajax&astroid=ajax_widget">';
Expand Down Expand Up @@ -140,10 +142,11 @@
$captcha_type = $params->get('captcha_type', 'default');
echo '<div class="mt-2">';
if ($captcha_type == 'recaptcha') {
PluginHelper::importPlugin('captcha', 'recaptcha');
$recaptcha = Factory::getApplication()->triggerEvent('onDisplay', array(null, 'as_form_builder_recaptcha' , 'as-form-builder-recaptcha'));
echo (isset($recaptcha[0])) ? $recaptcha[0] : '<p class="uk-alert-danger">' . Text::_('ASTROID_RECAPTCHA_NOT_INSTALLED') . '</p>';
$document->loadGoogleReCaptcha();
$pluginParams = Helper::getPluginParams();
echo '<div id="'.$element->id.'-recaptcha" class="g-recaptcha" data-sitekey="'.$pluginParams->get('g_site_key', '').'"></div>';
} elseif ($captcha_type == 'invisible-recaptcha') {
$document->loadGoogleReCaptcha();
PluginHelper::importPlugin('captcha', 'recaptcha_invisible');
$recaptcha = Factory::getApplication()->triggerEvent('onDisplay', array(null, 'as_form_builder_invisible_recaptcha' , 'as-form-builder-invisible-recaptcha'));
echo (isset($recaptcha[0])) ? $recaptcha[0] : '<p class="uk-alert-danger">' . Text::_('ASTROID_RECAPTCHA_NOT_INSTALLED') . '</p>';
Expand All @@ -155,7 +158,7 @@
endif;

echo '<input type="hidden" name="form_id" value="'.$element->unqid.'">';
echo '<input type="hidden" name="template" value="'.Astroid\Framework::getTemplate()->id.'">';
echo '<input type="hidden" name="template" value="'.Framework::getTemplate()->id.'">';
echo '<input type="hidden" name="widget" value="formbuilder">';
if (isset($options['source']) && $options['source']) {
echo '<input type="hidden" name="source" value="'.$options['source'].'">';
Expand Down Expand Up @@ -185,4 +188,4 @@
echo '<div class="as-formbuilder-status mt-4"></div>';
echo '</form>';

Factory::getDocument()->getWebAssetManager()->registerAndUseScript('astroid.formbuilder', "astroid/formbuilder.min.js", ['relative' => true, 'version' => 'auto'], [], ['jquery']);
Factory::getApplication()->getDocument()->getWebAssetManager()->registerAndUseScript('astroid.formbuilder', "astroid/formbuilder.min.js", ['relative' => true, 'version' => 'auto'], [], ['jquery']);
6 changes: 6 additions & 0 deletions framework/library/astroid/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,12 @@ public function loadLenis(): void
}
}

public function loadGoogleReCaptcha(): void
{
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->registerAndUseScript('google.recaptcha', '//www.google.com/recaptcha/api.js', ['relative' => true, 'version' => 'auto']);
}

public function moveFile(&$array, $a, $b): void
{
$out = array_splice($array, $a, 1);
Expand Down
32 changes: 32 additions & 0 deletions framework/library/astroid/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,38 @@ public static function getCaptcha($context = '') {
return ( $value1 + $value2 == $value_result );
}

public static function verifyGoogleCaptcha($gRecaptchaResponse, $secretKey = '') {
if (empty($gRecaptchaResponse)) {
return false;
}
if (empty($secretKey)) {
$pluginParams = self::getPluginParams();
$secretKey = $pluginParams->get('g_secret_key', '');
}
if (empty($secretKey)) {
return false;
}
$url = 'https://www.google.com/recaptcha/api/siteverify';
$data = [
'secret' => $secretKey,
'response' => $gRecaptchaResponse
];

$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
],
];

$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);

return isset($response['success']) && $response['success'] === true;
}

public static function getPositions()
{
$template_name = defined('ASTROID_TEMPLATE_NAME') ? ASTROID_TEMPLATE_NAME : Framework::getTemplate()->template;
Expand Down
8 changes: 6 additions & 2 deletions js/formbuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ jQuery(function($){
data = $this.serializeArray();
let id = Date.now() * 1000 + Math.random() * 1000;
id = id.toString(16).replace(/\./g, "").padEnd(14, "0")+Math.trunc(Math.random() * 100000000);

for (let i = 0; i < data.length; i++) {
request[data[i]['name']] = data[i]['value'];
}
Expand All @@ -17,15 +16,20 @@ jQuery(function($){
url : $this.attr('action')+'&t='+id,
data : request,
beforeSend: function(){
$this.find('.as-formbuilder-status').empty()
$this.find('.as-formbuilder-status').empty();
$this.find('.as-form-builer-submit').attr('disabled', 'disabled');
},
success: function (response) {
if (response.status === 'success') {
$this.find('.as-formbuilder-status').append('<div class="alert alert-success" role="alert">'+response.message+'</div>');
$this.trigger("reset");
$this.find('.g-recaptcha').each(function(){
grecaptcha.reset(this);
})
} else {
$this.find('.as-formbuilder-status').append('<div class="alert alert-danger" role="alert">'+response.message+'</div>');
}
$this.find('.as-form-builer-submit').removeAttr('disabled');
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion js/formbuilder.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions language/en-GB/en-GB.astroid.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1182,10 +1182,18 @@ ASTROID_IMPORT_POPUP_OPTION="Download backup before importing"

COM_PLUGINS_ASTROID-TABS-VISIBILITY_FIELDSET_LABEL="Tabs Visibility"
ASTROID_TABS_FRONTEND_VISIBILTY="Frontend Visibility of Astroid tabs"
COM_PLUGINS_ASTROID_API_FIELDSET_LABEL="APIs"

TPL_ASTROID_MINIFYJS_EXCLUDES_LABEL="Exclude JS Files"
TPL_ASTROID_MINIFYJS_EXCLUDES_DESC="Add comma separated filesnames to exclude files from JS minification. You can add filename directly or use available filename patterns: <br/> <code>*.min.js</code><br/> <code>jquery.*</code><br/> <code>*bootstrap*</code>"

; ReCaptcha
ASTROID_RECAPTCHA_NOTE="Google ReCaptcha"
ASTROID_GOOGLE_SITE_KEY="Site Key"
ASTROID_GOOGLE_SITE_KEY_DESC="Use this site key in the HTML code your site serves to users."
ASTROID_GOOGLE_SECRET_KEY="Secret Key"
ASTROID_GOOGLE_SECRET_KEY_DESC="Use this secret key for communication between your site and reCAPTCHA."

; Widgets
ASTROID_ELEMENT_CATEGORY_SYSTEM="System"
ASTROID_ELEMENT_CATEGORY_ARTICLE="Article"
Expand Down
6 changes: 6 additions & 0 deletions plugins/astroid/astroid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
</fieldset>
<fieldset name="astroid_api">
<field name="gmap_api" type="text" default="" label="ASTROID_WIDGET_GMAP_API" description="ASTROID_WIDGET_GMAP_API_DESC"/>
<field type="spacer" name="recaptcha_spacer" hr="true"/>
<field name="recaptcha_note" type="note" label="ASTROID_RECAPTCHA_NOTE" />
<field name="g_site_key" type="text" default="" label="ASTROID_GOOGLE_SITE_KEY"/>
<field name="g_secret_key" type="text" default="" label="ASTROID_GOOGLE_SECRET_KEY"/>
</fieldset>
<fieldset name="astroid-tabs-visibility">
<field name="frontend_tabs_visibility" type="radio" default="1" label="ASTROID_TABS_FRONTEND_VISIBILTY" description="" class="btn-group btn-group-yesno">
Expand Down

0 comments on commit 8aea58c

Please sign in to comment.