UndefinedOffset / silverstripe-nocaptcha

A spam protector and form field using Google's reCAPTCHA v2 or optionally a foundation v3 implementation
BSD 3-Clause "New" or "Revised" License
31 stars 37 forks source link

Add extension hook to validate()? #78

Open micschk opened 2 years ago

micschk commented 2 years ago

If an extension call would be added to validate, this would devs to tweak the validation result without having to duplicate/replace the existing validation logic.

Use case is a subsites setup (with reCaptcha v3) to which new hostnames may be added by the client. These hostnames should then also be added to the reCaptcha key in order to work. Instead, the reCaptcha key is marked as 'do not check origin' and we are required to check the hostname field ourselves.

Screenshot 2022-10-11 at 12 41 59

Currently we override the field with our own subclass (via Injector) but an extension hook would be better imo, eg just before return true in validate(): $this->extend('extendValidation', $validator); Note: get the response in an extension via $this->owner->getVerifyResponse(), no need to include that as argument.

Logic for hostname validation:

class NocaptchaField_ValidateSubsiteHostname
extends NocaptchaField {

    public function validate($validator)
    {
        $isValid = parent::validate($validator);

        // Extra check: validate hostname the recaptcha was solved on to be a valid subsite domain
        $response = $this->getVerifyResponse();
        if( isset($response['hostname']) && Subsite::getSubsiteIDForDomain($response['hostname']) !== SubsiteState::singleton()->getSubsiteId() ) {
            $validator->validationError($this->name, _t(__CLASS__.'.SPAM', 'Invalid hostname in validation response: SPAM'));

            return false;
        }

        return $isValid;
    }
}