captcha_concern.rb 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. # frozen_string_literal: true
  2. module CaptchaConcern
  3. extend ActiveSupport::Concern
  4. include Hcaptcha::Adapters::ViewMethods
  5. included do
  6. helper_method :render_captcha
  7. end
  8. def captcha_available?
  9. ENV['HCAPTCHA_SECRET_KEY'].present? && ENV['HCAPTCHA_SITE_KEY'].present?
  10. end
  11. def captcha_enabled?
  12. captcha_available? && Setting.captcha_enabled
  13. end
  14. def captcha_user_bypass?
  15. false
  16. end
  17. def captcha_required?
  18. captcha_enabled? && !captcha_user_bypass?
  19. end
  20. def check_captcha!
  21. return true unless captcha_required?
  22. if verify_hcaptcha
  23. true
  24. else
  25. if block_given?
  26. message = flash[:hcaptcha_error]
  27. flash.delete(:hcaptcha_error)
  28. yield message
  29. end
  30. false
  31. end
  32. end
  33. def extend_csp_for_captcha!
  34. policy = request.content_security_policy&.clone
  35. return unless captcha_required? && policy.present?
  36. %w(script_src frame_src style_src connect_src).each do |directive|
  37. values = policy.send(directive)
  38. values << 'https://hcaptcha.com' unless values.include?('https://hcaptcha.com') || values.include?('https:')
  39. values << 'https://*.hcaptcha.com' unless values.include?('https://*.hcaptcha.com') || values.include?('https:')
  40. policy.send(directive, *values)
  41. end
  42. request.content_security_policy = policy
  43. end
  44. def render_captcha
  45. return unless captcha_required?
  46. hcaptcha_tags
  47. end
  48. end