Skip to content
Snippets Groups Projects
Commit 294f8393 authored by Chris Hallberg's avatar Chris Hallberg Committed by Demian Katz
Browse files

ReCaptcha checking for user comments (#784)

parent c9aad91e
No related merge requests found
......@@ -1459,7 +1459,7 @@ treeSearchLimit = 100
;secretKey = "https://www.google.com/recaptcha/admin/create"
; Valid theme values: dark, light
;theme = light
; Valid forms values: changePassword, email, feedback, newAccount, passwordRecovery, sms
; Valid forms values: changePassword, email, feedback, newAccount, passwordRecovery, sms, userComments
; Use * for all supported forms
;forms = changePassword, email, newAccount, passwordRecovery, sms
......
......@@ -1086,6 +1086,16 @@ class AjaxController extends AbstractBase
);
}
$useCaptcha = $this->recaptcha()->active('userComments');
$this->recaptcha()->setErrorMode('none');
if (!$this->formWasSubmitted('comment', $useCaptcha)) {
return $this->output(
$this->translate('recaptcha_not_passed'),
self::STATUS_ERROR,
403
);
}
$table = $this->getTable('Resource');
$resource = $table->findResource(
$id, $this->params()->fromPost('source', DEFAULT_SEARCH_BACKEND)
......
......@@ -90,7 +90,7 @@ class Recaptcha extends AbstractPlugin
*/
public function setErrorMode($mode)
{
if (in_array($mode, ['flash', 'throw'])) {
if (in_array($mode, ['flash', 'throw', 'none'])) {
$this->errorMode = $mode;
return true;
}
......@@ -125,7 +125,7 @@ class Recaptcha extends AbstractPlugin
$response = false;
}
$captchaPassed = $response && $response->isValid();
if (!$captchaPassed) {
if (!$captchaPassed && $this->errorMode != 'none') {
if ($this->errorMode == 'flash') {
$this->getController()->flashMessenger()
->addMessage('recaptcha_not_passed', 'error');
......
......@@ -262,6 +262,13 @@ class Factory
public static function getUserComments(ServiceManager $sm)
{
$capabilities = $sm->getServiceLocator()->get('VuFind\AccountCapabilities');
return new UserComments('enabled' === $capabilities->getCommentSetting());
$config = $sm->getServiceLocator()->get('VuFind\Config')->get('config');
$useRecaptcha = isset($config->Captcha) && isset($config->Captcha->forms)
&& (trim($config->Captcha->forms) === '*'
|| strpos($config->Captcha->forms, 'userComments'));
return new UserComments(
'enabled' === $capabilities->getCommentSetting(),
$useRecaptcha
);
}
}
......@@ -45,14 +45,33 @@ class UserComments extends AbstractBase
*/
protected $enabled;
/**
* Is this tab enabled?
*
* @var bool
*/
protected $useRecaptcha;
/**
* Constructor
*
* @param bool $enabled is this tab enabled?
* @param bool $urc use recaptcha?
*/
public function __construct($enabled = true)
public function __construct($enabled = true, $urc = false)
{
$this->enabled = $enabled;
$this->useRecaptcha = $urc;
}
/**
* Is Recaptcha active?
*
* @return bool
*/
public function isRecaptchaActive()
{
return $this->useRecaptcha;
}
/**
......
......@@ -93,14 +93,18 @@ class Recaptcha extends AbstractHelper
* Generate <div> with ReCaptcha from render.
*
* @param boolean $useRecaptcha Boolean of active state, for compact templating
* @param boolean $wrapHtml Include prefix and suffix?
*
* @return string $html
*/
public function html($useRecaptcha = true)
public function html($useRecaptcha = true, $wrapHtml = true)
{
if (!isset($useRecaptcha) || !$useRecaptcha) {
return false;
}
if (!$wrapHtml) {
return $this->recaptcha->getHtml();
}
return $this->prefixHtml . $this->recaptcha->getHtml() . $this->suffixHtml;
}
......
/*global VuFind */
/*global grecaptcha, VuFind */
VuFind.register('lightbox', function Lightbox() {
// State
var _originalUrl = false;
......@@ -101,6 +101,11 @@ VuFind.register('lightbox', function Lightbox() {
$('#modal').find('.checkbox-select-item').change(function lbSelectAllDisable() {
$(this).closest('.modal-body').find('.checkbox-select-all').prop('checked', false);
});
// Recaptcha
var modalCaptcha = $('#modal .g-recaptcha');
if (modalCaptcha.length && typeof grecaptcha !== 'undefined' && modalCaptcha.is(':empty')) {
grecaptcha.render(modalCaptcha[0], modalCaptcha[0].dataset);
}
}
var _xhr = false;
......
/*global deparam, syn_get_widget, userIsLoggedIn, VuFind */
/*global deparam, grecaptcha, syn_get_widget, userIsLoggedIn, VuFind */
/*exported ajaxTagUpdate, recordDocReady */
/**
......@@ -78,6 +78,9 @@ function refreshCommentList($target, recordId, recordSource) {
return false;
});
$target.find('.comment-form input[type="submit"]').button('reset');
if (typeof grecaptcha !== 'undefined') {
grecaptcha.reset();
}
});
}
......@@ -93,6 +96,14 @@ function registerAjaxCommentRecord() {
id: id,
source: recordSource
};
if (typeof grecaptcha !== 'undefined') {
try {
data['g-recaptcha-response'] = grecaptcha.getResponse(0);
} catch (e) {
console.error('Expected errors: placeholder element full and Invalid client ID');
console.error(e);
}
}
$.ajax({
type: 'POST',
url: url,
......@@ -107,7 +118,7 @@ function registerAjaxCommentRecord() {
})
.fail(function addCommentFail(response, textStatus) {
if (textStatus === 'abort' || typeof response.responseJSON === 'undefined') { return; }
VuFind.lightbox.update(response.responseJSON.data);
VuFind.lightbox.alert(response.responseJSON.data, 'danger');
});
return false;
});
......
......@@ -6,7 +6,7 @@
<div class="comment-list">
<?=$this->render('record/comments-list.phtml')?>
</div>
<form class="comment-form row" name="commentRecord" action="<?=$this->recordLink()->getActionUrl($this->driver, 'AddComment')?>" method="post">
<form class="comment-form" name="commentRecord" action="<?=$this->recordLink()->getActionUrl($this->driver, 'AddComment')?>" method="post">
<div class="row">
<div class="col-sm-3 name">
<input type="hidden" name="id" value="<?=$this->escapeHtmlAttr($this->driver->getUniqueId())?>"/>
......@@ -17,6 +17,9 @@
<? $user = $this->auth()->isLoggedIn() ?>
<? if($user): ?>
<textarea name="comment" class="form-control" rows="3" required></textarea><br/>
<? if ($this->tab->isRecaptchaActive()): ?>
<?=$this->recaptcha()->html(true, false) ?><br/>
<? endif; ?>
<input class="btn btn-primary" data-loading-text="<?=$this->transEsc('Submitting') ?>..." type="submit" value="<?=$this->transEsc("Add your comment")?>"/>
<? else: ?>
<a href="<?=$this->url('myresearch-userlogin') ?>" class="btn btn-primary" data-lightbox title="Login"><i class="fa fa-sign-in" aria-hidden="true"></i> <?=$this->transEsc("You must be logged in first") ?></a>
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment