mod/recaptcha/set/all/recaptcha.rb
RECAPTCHA_ERROR_CODES = { # LOCALIZE
"missing-input-secret" => "secret parameter is missing",
"invalid-input-secret" => "secret parameter is invalid or malformed",
"missing-input-response" => "response parameter is missing",
"invalid-input-response" => "response parameter is invalid or malformed",
"bad-request" => "request is invalid or malformed"
}
def human?
result = JSON.parse recaptcha_response
return if recaptcha_success?(result)
add_recaptcha_errors result["error-codes"]
end
def recaptcha_on?
recaptcha_keys? &&
Env.controller &&
!Auth.signed_in? &&
!Auth.always_ok? &&
!Auth.needs_setup? &&
Card::Rule.toggle(rule(:captcha))
end
def add_recaptcha_errors error_codes
if error_codes.present?
error_codes.each do |code|
errors.add :recaptcha, RECAPTCHA_ERROR_CODES.fetch(code, code)
end
else
errors.add :recaptcha, "Looks like you are not a human" # LOCALIZE
end
end
def recaptcha_success? result
result["success"] &&
(result["score"].to_f >= Cardio.config.recaptcha_minimum_score) &&
(result["action"].to_sym == action.to_sym)
end
def recaptcha_response
::Recaptcha.get({ secret: Card.config.recaptcha_secret_key,
response: Env.params[:recaptcha_token] }, {})
end
def recaptcha_keys?
Card.config.recaptcha_site_key && Card.config.recaptcha_secret_key
end
event :recaptcha, :validate, when: :validate_recaptcha? do
handle_recaptcha_config_errors do
:captcha.card.captcha_used!
human?
end
end
def handle_recaptcha_config_errors
case Env.params[:recaptcha_token]
when "grecaptcha-undefined"
errors.add "recaptcha", "needs correct v3 configuration" # LOCALILZE
when "recaptcha-token-field-missing"
raise Card::Error, "recaptcha token field missing" # LOCALILZE
else
yield
end
end
def validate_recaptcha?
return unless Card::Codename.exist? :captcha
!@supercard && !:captcha.card.captcha_used? && recaptcha_on?
end
format :html do
def recaptcha_token action
output [
javascript_include_tag(recaptcha_script_url),
hidden_field_tag("recaptcha_token", "",
"data-site-key": Card.config.recaptcha_site_key,
"data-action": action,
class: "_recaptcha-token")
]
end
def recaptcha_script_url
"https://www.google.com/recaptcha/api.js?render=#{Card.config.recaptcha_site_key}"
end
def hidden_form_tags action, opts
return super unless recaptcha?(opts)
super + recaptcha_token(action)
end
def card_form_html_opts action, opts={}
super
opts["data-recaptcha"] ||= "on" if recaptcha?(opts)
opts
end
def recaptcha? opts
card.recaptcha_on? && opts[:recaptcha] != :off
end
end