Test Failed
Push — main ( 6435b1...db043e )
by Paul
16:23 queued 07:02
created

RecaptchaV3Validator::errors()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 11
rs 10
cc 4
nc 6
nop 1
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules\Validator;
4
5
use GeminiLabs\SiteReviews\Defaults\CaptchaConfigDefaults;
6
use GeminiLabs\SiteReviews\Modules\Captcha;
7
8
class RecaptchaV3Validator extends CaptchaValidatorAbstract
9
{
10
    /**
11
     * @see https://developers.google.com/recaptcha/docs/v3
12
     */
13
    public function config(): array
14
    {
15
        $language = $this->getLocale();
16
        $urlParameters = array_filter([
17
            'hl' => $language,
18
            'render' => 'explicit',
19
        ]);
20
        return glsr(CaptchaConfigDefaults::class)->merge([
21
            'badge' => glsr_get_option('forms.captcha.position'),
22
            'class' => 'glsr-g-recaptcha',
23
            'language' => $language,
24
            'sitekey' => $this->siteKey(),
25
            'size' => 'invisible',
26
            'theme' => glsr_get_option('forms.captcha.theme'),
27
            'type' => 'recaptcha_v3',
28
            'urls' => [
29
                'nomodule' => add_query_arg($urlParameters, 'https://www.google.com/recaptcha/api.js'),
30
            ],
31
        ]);
32
    }
33
34
    public function isEnabled(): bool
35
    {
36
        return glsr(Captcha::class)->isEnabled('recaptcha_v3');
37
    }
38
39
    public function isTokenValid(array $response): bool
40
    {
41
        $threshold = glsr_get_option('forms.recaptcha_v3.threshold');
42
        $isValid = $response['success']
43
            && $response['score'] >= $threshold
44
            && 'submit_review' === $response['action'];
45
        if ($isValid) {
46
            glsr_log()->debug('reCAPTCHA v3 passed with score: '.$response['score']);
47
        } else {
48
            glsr_log()->debug('reCAPTCHA v3 failed with score: '.$response['score']);
49
        }
50
        return $isValid;
51
    }
52
53
    protected function data(): array
54
    {
55
        $token = $this->token();
56
        if (array_key_exists($token, $this->errorCodes())) {
57
            $token = '';
58
        }
59
        return [
60
            'remoteip' => $this->request->ip_address,
61
            'response' => $token,
62
            'secret' => $this->siteSecret(),
63
        ];
64
    }
65
66
    protected function errorCodes(): array
67
    {
68
        return [
69
            'bad-request' => 'The request is invalid or malformed.',
70
            'invalid-input-response' => 'The response parameter is invalid or malformed.',
71
            'invalid-input-secret' => 'The secret key is invalid or malformed.',
72
            'missing-input-response' => 'The response parameter is missing.',
73
            'missing-input-secret' => 'Your secret key is missing.',
74
            'sitekey_invalid' => 'Your site key is invalid.',
75
            'sitekey_missing' => 'Your site key is missing.',
76
            'timeout-or-duplicate' => 'The response is no longer valid: either is too old or has been used previously.',
77
        ];
78
    }
79
80
    protected function errors(array $errors): array
81
    {
82
        if (empty($this->siteSecret())) {
83
            $errors[] = 'missing-input-secret';
84
        }
85
        if (empty($this->siteKey())) {
86
            $errors[] = 'sitekey_missing';
87
        } elseif ('sitekey_invalid' === $this->token()) {
88
            $errors[] = 'sitekey_invalid';
89
        }
90
        return parent::errors(array_unique($errors));
91
    }
92
93
    protected function siteKey(): string
94
    {
95
        return glsr_get_option('forms.recaptcha_v3.key');
96
    }
97
98
    protected function siteSecret(): string
99
    {
100
        return glsr_get_option('forms.recaptcha_v3.secret');
101
    }
102
103
    protected function siteVerifyUrl(): string
104
    {
105
        return 'https://www.google.com/recaptcha/api/siteverify';
106
    }
107
108
    protected function token(): string
109
    {
110
        return $this->request['_recaptcha'] ?? '';
111
    }
112
}
113