Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't apply recaptcha requirements when it's not configured #48

Merged
merged 3 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@
->post('/fof/recaptcha/test', 'fof-recaptcha.test', Api\Controller\TestReCaptchaController::class),

(new Extend\ApiSerializer(ForumSerializer::class))
->attribute('postWithoutCaptcha', function (ForumSerializer $serializer) {
return $serializer->getActor()->hasPermission('fof-recaptcha.postWithoutCaptcha');
}),
->attributes(ForumAttributes::class),

(new Extend\Validator(RecaptchaValidator::class))
->configure(AddValidatorRule::class),
Expand Down
434 changes: 224 additions & 210 deletions js/package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
"@flarum/prettier-config": "^1.0.0",
"external-load": "^1.0.0",
"flarum-tsconfig": "^1.0.2",
"flarum-webpack-config": "^2.0.0",
"webpack": "^5.80.0",
"webpack-cli": "^5.0.1"
"flarum-webpack-config": "^2.0.2",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4"
},
"devDependencies": {
"prettier": "^3.0.3"
"prettier": "^3.2.5"
},
"scripts": {
"dev": "webpack --mode development --watch",
Expand Down
7 changes: 7 additions & 0 deletions js/src/@types/shims.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from 'flarum/forum/ForumApplication';

declare module 'flarum/forum/ForumApplication' {
export default interface ForumApplication {
recaptchaLoaded: boolean;
}
}
6 changes: 5 additions & 1 deletion js/src/forum/extendAuthModals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const addRecaptchaToAuthModal = <T extends typeof ForgotPasswordModal | t
const isEnabled = () => !!app.forum.attribute(`fof-recaptcha.${type}`);

extend(modal.prototype, 'oninit', function () {
if (!app.forum.attribute('fof-recaptcha.configured')) return;
if (!isEnabled()) return;

this.recaptcha = new RecaptchaState(
Expand All @@ -40,18 +41,21 @@ export const addRecaptchaToAuthModal = <T extends typeof ForgotPasswordModal | t
});

extend(modal.prototype, dataMethod, function (data) {
if (!app.forum.attribute('fof-recaptcha.configured')) return;
if (!isEnabled()) return;

data['g-recaptcha-response'] = this.recaptcha.getResponse();
});

extend(modal.prototype, 'fields', function (fields) {
if (!app.forum.attribute('fof-recaptcha.configured')) return;
if (!isEnabled()) return;

fields.add('recaptcha', <Recaptcha state={this.recaptcha} />, -5);
});

extend(modal.prototype, 'onerror', function (_, error) {
if (!app.forum.attribute('fof-recaptcha.configured')) return;
if (!isEnabled()) return;

this.recaptcha.reset();
Expand All @@ -63,7 +67,7 @@ export const addRecaptchaToAuthModal = <T extends typeof ForgotPasswordModal | t
});

override(modal.prototype, 'onsubmit', function (original, e) {
if (isEnabled() && this.recaptcha.isInvisible() && !e.isRecaptchaSecondStep) {
if (app.forum.attribute('fof-recaptcha.configured') && isEnabled() && this.recaptcha.isInvisible() && !e.isRecaptchaSecondStep) {
// When recaptcha is invisible, onsubmit will be called two times
// First time with normal event, we will call recaptcha.execute
// Second time is called from recaptcha callback with a special isRecaptcha attribute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Recaptcha from '../common/components/Recaptcha';

export default function (Composer) {
extend(Composer.prototype, 'oninit', function () {
if (app.forum.attribute('postWithoutCaptcha')) {
if (!app.forum.attribute('fof-recaptcha.configured') || app.forum.attribute('postWithoutCaptcha')) {
return;
}

Expand All @@ -19,15 +19,15 @@ export default function (Composer) {
});

extend(Composer.prototype, 'data', function (data) {
if (app.forum.attribute('postWithoutCaptcha')) {
if (!app.forum.attribute('fof-recaptcha.configured') || app.forum.attribute('postWithoutCaptcha')) {
return;
}

data['g-recaptcha-response'] = this.recaptcha.getResponse();
});

extend(Composer.prototype, 'headerItems', function (fields) {
if (app.forum.attribute('postWithoutCaptcha')) {
if (!app.forum.attribute('fof-recaptcha.configured') || app.forum.attribute('postWithoutCaptcha')) {
return;
}

Expand All @@ -42,15 +42,18 @@ export default function (Composer) {

// There's no onerror handler on composer classes, but we can react to loaded which is called after errors
extend(Composer.prototype, 'loaded', function () {
if (app.forum.attribute('postWithoutCaptcha')) {
if (!app.forum.attribute('fof-recaptcha.configured') || app.forum.attribute('postWithoutCaptcha')) {
return;
}

this.recaptcha.reset();
});

override(Composer.prototype, 'onsubmit', function (original, argument1) {
if (!app.forum.attribute('postWithoutCaptcha') && this.recaptcha.isInvisible() && argument1 !== 'recaptchaSecondStep') {
if (
app.forum.attribute('fof-recaptcha.configured') ||
(!app.forum.attribute('postWithoutCaptcha') && this.recaptcha.isInvisible() && argument1 !== 'recaptchaSecondStep')
) {
this.loading = true;
this.recaptcha.execute();
return;
Expand Down
File renamed without changes.
26 changes: 12 additions & 14 deletions js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
{
// Use Flarum's tsconfig as a starting point
"extends": "flarum-tsconfig",
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
// and also tells your Typescript server to read core's global typings for
// access to `dayjs` and `$` in the global namespace.
"include": ["src/**/*", "../vendor/flarum/core/js/dist-typings/@types/**/*"],
"compilerOptions": {
// This will output typings to `dist-typings`
"declarationDir": "./dist-typings",
"baseUrl": ".",
"paths": {
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"]
}
// Use Flarum's tsconfig as a starting point
"extends": "flarum-tsconfig",
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
// and also tells your Typescript server to read core's global typings for
// access to `dayjs` and `$` in the global namespace.
"include": ["src/**/*", "../vendor/flarum/core/js/dist-typings/@types/**/*"],
"compilerOptions": {
// This will output typings to `dist-typings`
"declarationDir": "./dist-typings",
"paths": {
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"]
}
}
}
36 changes: 36 additions & 0 deletions src/ForumAttributes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* This file is part of fof/recaptcha.
*
* Copyright (c) FriendsOfFlarum.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FoF\ReCaptcha;

use Flarum\Api\Serializer\ForumSerializer;
use Flarum\Settings\SettingsRepositoryInterface;

class ForumAttributes
{
/**
* @var SettingsRepositoryInterface
*/
protected $settings;

public function __construct(SettingsRepositoryInterface $settings)
{
$this->settings = $settings;
}

public function __invoke(ForumSerializer $serializer, $model, array $attributes): array
{
$attributes['fof-recaptcha.configured'] = Utils::isExtensionSetup($this->settings);
$attributes['postWithoutCaptcha'] = $serializer->getActor()->hasPermission('fof-recaptcha.postWithoutCaptcha');

return $attributes;
}
}
8 changes: 7 additions & 1 deletion src/Listeners/AddValidatorRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Flarum\Foundation\AbstractValidator;
use Flarum\Settings\SettingsRepositoryInterface;
use FoF\ReCaptcha\ReCaptcha\GuzzleRequestMethod;
use FoF\ReCaptcha\Utils;
use Illuminate\Validation\Validator;
use ReCaptcha\ReCaptcha;

Expand All @@ -36,6 +37,10 @@ public function __construct(SettingsRepositoryInterface $settings)

public function __invoke(AbstractValidator $flarumValidator, Validator $validator)
{
if (!Utils::isExtensionSetup($this->settings)) {
return;
}

$secret = $this->settings->get('fof-recaptcha.credentials.secret');

$validator->addExtension(
Expand All @@ -50,7 +55,8 @@ function ($attribute, $value, $parameters) use ($validator, $secret) {
if (!empty($verification->getErrorCodes())) {
$validator->setCustomMessages(
[
'recaptcha' => resolve('translator')->trans('validation.recaptcha-unknown', ['errors' => implode(', ', $verification->getErrorCodes())])]
'recaptcha' => resolve('translator')->trans('validation.recaptcha-unknown', ['errors' => implode(', ', $verification->getErrorCodes())]),
]
);
}

Expand Down
5 changes: 5 additions & 0 deletions src/Listeners/RegisterValidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\Event\Saving;
use FoF\ReCaptcha\Utils;
use FoF\ReCaptcha\Validators\RecaptchaValidator;
use Illuminate\Support\Arr;

Expand All @@ -39,6 +40,10 @@ public function __construct(RecaptchaValidator $validator, SettingsRepositoryInt

public function handle(Saving $event)
{
if (!Utils::isExtensionSetup($this->settings)) {
return;
}

// We also check for the actor's admin status, so that we can allow admins to create users from the admin panel without recaptcha blocking the action.
if (!$event->user->exists && $this->settings->get('fof-recaptcha.signup') && !$event->actor->isAdmin()) {
$this->validator->assertValid([
Expand Down
13 changes: 11 additions & 2 deletions src/Listeners/ReplyPostValidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
namespace FoF\ReCaptcha\Listeners;

use Flarum\Post\Event\Saving;
use Flarum\Settings\SettingsRepositoryInterface;
use FoF\ReCaptcha\Utils;
use FoF\ReCaptcha\Validators\RecaptchaValidator;
use Illuminate\Support\Arr;

Expand All @@ -23,15 +25,22 @@ class ReplyPostValidate
protected $validator;

/**
* @param RecaptchaValidator $validator
* @var SettingsRepositoryInterface
*/
public function __construct(RecaptchaValidator $validator)
protected $settings;

public function __construct(RecaptchaValidator $validator, SettingsRepositoryInterface $settings)
{
$this->validator = $validator;
$this->settings = $settings;
}

public function handle(Saving $event)
{
if (!Utils::isExtensionSetup($this->settings)) {
return;
}

if (!$event->post->exists) {
// If it's a new discussion, the reCAPTCHA is already validated in discussion saving event
// When this code runs, the discussion already exists, and the number has not been assigned to the post yet
Expand Down
13 changes: 11 additions & 2 deletions src/Listeners/StartDiscussionValidate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
namespace FoF\ReCaptcha\Listeners;

use Flarum\Discussion\Event\Saving;
use Flarum\Settings\SettingsRepositoryInterface;
use FoF\ReCaptcha\Utils;
use FoF\ReCaptcha\Validators\RecaptchaValidator;
use Illuminate\Support\Arr;

Expand All @@ -23,15 +25,22 @@ class StartDiscussionValidate
protected $validator;

/**
* @param RecaptchaValidator $validator
* @var SettingsRepositoryInterface
*/
public function __construct(RecaptchaValidator $validator)
protected $settings;

public function __construct(RecaptchaValidator $validator, SettingsRepositoryInterface $settings)
{
$this->validator = $validator;
$this->settings = $settings;
}

public function handle(Saving $event)
{
if (!Utils::isExtensionSetup($this->settings)) {
return;
}

if (!$event->discussion->exists) {
if ($event->actor->hasPermission('fof-recaptcha.postWithoutCaptcha')) {
return;
Expand Down
22 changes: 22 additions & 0 deletions src/Utils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of fof/recaptcha.
*
* Copyright (c) FriendsOfFlarum.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FoF\ReCaptcha;

use Flarum\Settings\SettingsRepositoryInterface;

class Utils
{
public static function isExtensionSetup(SettingsRepositoryInterface $settings): bool
{
return trim($settings->get('fof-recaptcha.credentials.site', '')) !== '' && trim($settings->get('fof-recaptcha.credentials.secret', '')) !== '';
}
}
Loading