diff --git a/README.md b/README.md index 8757149ac..93b6dbc37 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,9 @@ Though the experience is not that refined... # Start the stack in the background docker compose up -d +# Local Compose disables reCAPTCHA by default. Set RECAPTCHA_ENABLED=true +# only when both the UI site key and API secret are configured. + # Stop the stack and delete all volumes docker compose down --volumes ``` diff --git a/app/Rules/ReCaptchaValidation.php b/app/Rules/ReCaptchaValidation.php index b26437a7f..facaecd60 100644 --- a/app/Rules/ReCaptchaValidation.php +++ b/app/Rules/ReCaptchaValidation.php @@ -91,6 +91,10 @@ private function verify($token) { * @return bool */ public function passes($attribute, $value) { + if (config('app.env') === 'local' && config('recaptcha.enabled') === false) { + return true; + } + $recaptchaResponse = $this->verify($value); if ($this->verifyHostname($recaptchaResponse->getHostname()) === false) { diff --git a/config/recaptcha.php b/config/recaptcha.php index b7ba8ecdb..eaa7bcd4d 100644 --- a/config/recaptcha.php +++ b/config/recaptcha.php @@ -1,6 +1,7 @@ env('RECAPTCHA_ENABLED', true), 'secret_key' => env('RECAPTCHA_V3_SECRET_KEY', 'config/recaptcha.php: no-secret-key-set!'), 'min_score' => env('RECAPTCHA_V3_MIN_SCORE', 0.5), ]; diff --git a/docker-compose.yml b/docker-compose.yml index e14f0e183..072f3ea0d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,7 @@ services: - redis environment: - CONTAINER_ROLE=app + - RECAPTCHA_ENABLED=${RECAPTCHA_ENABLED:-false} sql: image: "${DOCKER_DATABASE_IMAGE_NAME}" environment: diff --git a/tests/Validation/ReCaptchaValidationTest.php b/tests/Validation/ReCaptchaValidationTest.php index b89bb5d69..9833a6557 100644 --- a/tests/Validation/ReCaptchaValidationTest.php +++ b/tests/Validation/ReCaptchaValidationTest.php @@ -66,6 +66,31 @@ public function testBypassFails() { ); } + public function testRecaptchaCanBeDisabledInLocalDevelopment() { + config([ + 'app.env' => 'local', + 'recaptcha.enabled' => false, + ]); + + $rule = $this->buildReCaptchaValidation(); + + $this->assertTrue($rule->passes('token', '')); + } + + public function testRecaptchaCannotBeDisabledOutsideLocalDevelopment() { + config([ + 'app.env' => 'production', + 'recaptcha.enabled' => false, + ]); + + $mockReCaptcha = $this->buildMockedReCaptcha( + $this->buildReCaptchaFakeResponse(['success' => false]) + ); + $rule = $this->buildReCaptchaValidation($mockReCaptcha); + + $this->assertFalse($rule->passes('token', 'someToken')); + } + public function testLowScore() { $fakeResponse = $this->buildReCaptchaFakeResponse([ 'score' => config('recaptcha.min_score') - 1,