-
-
Notifications
You must be signed in to change notification settings - Fork 825
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24860 from colemanw/formbuilder-recaptcha2
Afform - Add support for ReCaptcha v2
- Loading branch information
Showing
14 changed files
with
187 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?php | ||
|
||
namespace Civi; | ||
|
||
use CRM_Recaptcha_ExtensionUtil as E; | ||
use Civi\Afform\AHQ; | ||
use Civi\Afform\Event\AfformValidateEvent; | ||
use Civi\Core\Event\GenericHookEvent; | ||
use Civi\Core\Service\AutoService; | ||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
|
||
/** | ||
* Provides ReCaptcha2 validation element to Afform | ||
* @internal | ||
* @service | ||
*/ | ||
class AfformReCaptcha2 extends AutoService implements EventSubscriberInterface { | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public static function getSubscribedEvents() { | ||
return [ | ||
'civi.afform_admin.metadata' => ['onAfformGetMetadata'], | ||
'hook_civicrm_alterAngular' => ['alterAngular'], | ||
'civi.afform.validate' => ['onAfformValidate'], | ||
]; | ||
} | ||
|
||
public static function onAfformGetMetadata(GenericHookEvent $event) { | ||
$event->elements['recaptcha2'] = [ | ||
'title' => E::ts('ReCaptcha2'), | ||
'afform_type' => ['form'], | ||
'directive' => 'crm-recaptcha2', | ||
'admin_tpl' => '~/afGuiRecaptcha2/afGuiRecaptcha2.html', | ||
'element' => [ | ||
'#tag' => 'crm-recaptcha2', | ||
], | ||
]; | ||
} | ||
|
||
public static function alterAngular(GenericHookEvent $event) { | ||
$changeSet = \Civi\Angular\ChangeSet::create('reCaptcha2') | ||
->alterHtml(';\\.aff\\.html$;', function($doc, $path) { | ||
// Add publicKey to recaptcha elements | ||
foreach (pq('crm-recaptcha2') as $captcha) { | ||
$recaptchaPublicKey = \Civi\Api4\Setting::get(FALSE) | ||
->addSelect('recaptchaPublicKey') | ||
->execute()->first()['value']; | ||
pq($captcha)->attr('recaptchakey', $recaptchaPublicKey ?: 'foo'); | ||
} | ||
}); | ||
$event->angular->add($changeSet); | ||
} | ||
|
||
public static function onAfformValidate(AfformValidateEvent $event) { | ||
$layout = AHQ::makeRoot($event->getAfform()['layout']); | ||
if (AHQ::getTags($layout, 'crm-recaptcha2')) { | ||
$response = $event->getApiRequest()->getValues()['extra']['recaptcha2'] ?? NULL; | ||
if (!isset($response) || !\CRM_Utils_ReCAPTCHA::checkResponse($response)) { | ||
$event->setError(E::ts('Please go back and complete the CAPTCHA at the bottom of this form.')); | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
// Module for editing ReCaptcha2 element in the AfformAdmin GUI | ||
return [ | ||
'js' => [ | ||
'ang/afGuiRecaptcha2.module.js', | ||
'ang/afGuiRecaptcha2/*.js', | ||
], | ||
'partials' => [ | ||
'ang/afGuiRecaptcha2', | ||
], | ||
'css' => ['ang/css/afGuiRecaptcha2.css'], | ||
// Ensure module is loaded on the afform_admin GUI page | ||
'basePages' => ['civicrm/admin/afform'], | ||
'requires' => [], | ||
'bundles' => [], | ||
'exports' => [], | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(function(angular, $, _) { | ||
angular.module('afGuiRecaptcha2', CRM.angRequires('afGuiRecaptcha2')); | ||
})(angular, CRM.$, CRM._); |
10 changes: 10 additions & 0 deletions
10
ext/recaptcha/ang/afGuiRecaptcha2/afGuiRecaptcha2-menu.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<li> | ||
<a href ng-click="$ctrl.node.recaptchatheme = ($ctrl.node.recaptchatheme === 'dark' ? 'light' : 'dark'); $event.stopPropagation();"> | ||
{{:: ts('Light') }} | ||
<i class="crm-i fa-toggle-{{ $ctrl.node.recaptchatheme === 'dark' ? 'on' : 'off' }}"></i> | ||
{{:: ts('Dark') }} | ||
</a> | ||
</li> | ||
<li role="separator" class="divider"> | ||
</li> | ||
<li><a href ng-click="$ctrl.deleteThis()"><span class="text-danger"><i class="crm-i fa-trash"></i> {{:: ts('Remove ReCaptcha') }}</span></a></li> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<div class="af-gui-element"> | ||
<div class="af-gui-bar"> | ||
<div class="form-inline pull-right"> | ||
<div class="btn-group pull-right" af-gui-menu> | ||
<button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-element-button" data-toggle="dropdown" title="{{:: ts('Configure') }}"> | ||
<span><i class="crm-i fa-gear"></i></span> | ||
</button> | ||
<ul class="dropdown-menu" ng-if="menu.open" ng-include="'~/afGuiRecaptcha2/afGuiRecaptcha2-menu.html'"></ul> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="af-gui-recaptcha2-placeholder" ng-class="{rc2dark: $ctrl.node.recaptchatheme === 'dark'}"></div> | ||
</div> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
// Module for recaptcha2 Afform element | ||
return [ | ||
'js' => [ | ||
'ang/crmRecaptcha2.module.js', | ||
'ang/crmRecaptcha2/*.js', | ||
], | ||
'partials' => [ | ||
'ang/crmRecaptcha2', | ||
], | ||
'css' => [], | ||
'basePages' => [], | ||
'requires' => [], | ||
'bundles' => [], | ||
'exports' => [ | ||
// This triggers Afform to automatically require this module on forms using recaptcha2 | ||
'crm-recaptcha2' => 'E', | ||
], | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(function(angular, $, _) { | ||
angular.module('crmRecaptcha2', CRM.angRequires('crmRecaptcha2')); | ||
})(angular, CRM.$, CRM._); |
28 changes: 28 additions & 0 deletions
28
ext/recaptcha/ang/crmRecaptcha2/crmRecaptcha2.component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
(function(angular, $, _) { | ||
angular.module('crmRecaptcha2').component('crmRecaptcha2', { | ||
templateUrl: '~/crmRecaptcha2/crmRecaptcha2.html', | ||
bindings: { | ||
recaptchakey: '@', | ||
recaptchatheme: '@', | ||
}, | ||
require: { | ||
afForm: '^^', | ||
}, | ||
controller: function($scope, $element) { | ||
var ctrl = this; | ||
|
||
this.$onInit = function() { | ||
this.recaptchatheme = this.recaptchatheme || 'light'; | ||
|
||
// Global callback because recaptcha can't directly call angular functions | ||
window.crmRecaptcha2Change = function(response) { | ||
$scope.$apply(function() { | ||
// Add response to form data | ||
var extra = ctrl.afForm.getData('extra'); | ||
extra.recaptcha2 = response; | ||
}); | ||
}; | ||
}; | ||
} | ||
}); | ||
})(angular, CRM.$, CRM._); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<script src="https://www.google.com/recaptcha/api.js" async defer></script> | ||
<div class="g-recaptcha" data-sitekey="{{:: $ctrl.recaptchakey }}" data-theme="{{:: $ctrl.recaptchatheme }}" data-callback="crmRecaptcha2Change"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
div.af-gui-recaptcha2-placeholder { | ||
width: 305px; | ||
height: 76px; | ||
opacity: .85; | ||
background-image: url('rc2-light.png'); | ||
background-size: contain; | ||
background-repeat: no-repeat; | ||
background-position: center; | ||
} | ||
div.af-gui-recaptcha2-placeholder.rc2dark { | ||
background-image: url('rc2-dark.png'); | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters