diff options
Diffstat (limited to 'app/controllers/concerns')
-rw-r--r-- | app/controllers/concerns/captcha_concern.rb | 59 | ||||
-rw-r--r-- | app/controllers/concerns/theming_concern.rb | 89 | ||||
-rw-r--r-- | app/controllers/concerns/two_factor_authentication_concern.rb | 2 |
3 files changed, 150 insertions, 0 deletions
diff --git a/app/controllers/concerns/captcha_concern.rb b/app/controllers/concerns/captcha_concern.rb new file mode 100644 index 000000000..538c1ffb1 --- /dev/null +++ b/app/controllers/concerns/captcha_concern.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module CaptchaConcern + extend ActiveSupport::Concern + include Hcaptcha::Adapters::ViewMethods + + included do + helper_method :render_captcha + end + + def captcha_available? + ENV['HCAPTCHA_SECRET_KEY'].present? && ENV['HCAPTCHA_SITE_KEY'].present? + end + + def captcha_enabled? + captcha_available? && Setting.captcha_enabled + end + + def captcha_user_bypass? + false + end + + def captcha_required? + captcha_enabled? && !captcha_user_bypass? + end + + def check_captcha! + return true unless captcha_required? + + if verify_hcaptcha + true + else + if block_given? + message = flash[:hcaptcha_error] + flash.delete(:hcaptcha_error) + yield message + end + false + end + end + + def extend_csp_for_captcha! + policy = request.content_security_policy + return unless captcha_required? && policy.present? + + %w(script_src frame_src style_src connect_src).each do |directive| + values = policy.send(directive) + values << 'https://hcaptcha.com' unless values.include?('https://hcaptcha.com') || values.include?('https:') + values << 'https://*.hcaptcha.com' unless values.include?('https://*.hcaptcha.com') || values.include?('https:') + policy.send(directive, *values) + end + end + + def render_captcha + return unless captcha_required? + + hcaptcha_tags + end +end diff --git a/app/controllers/concerns/theming_concern.rb b/app/controllers/concerns/theming_concern.rb new file mode 100644 index 000000000..f993a81d7 --- /dev/null +++ b/app/controllers/concerns/theming_concern.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +module ThemingConcern + extend ActiveSupport::Concern + + def use_pack(pack_name) + @core = resolve_pack_with_common(Themes.instance.core, pack_name) + @theme = resolve_pack_with_common(Themes.instance.flavour(current_flavour), pack_name, current_skin) + end + + private + + def current_flavour + [current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) } + end + + def current_skin + skins = Themes.instance.skins_for(current_flavour) + [current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } + end + + def valid_pack_data?(data, pack_name) + data['pack'].is_a?(Hash) && data['pack'][pack_name].present? + end + + def nil_pack(data) + { + use_common: true, + flavour: data['name'], + pack: nil, + preload: nil, + skin: nil, + supported_locales: data['locales'], + } + end + + def pack(data, pack_name, skin) + pack_data = { + use_common: true, + flavour: data['name'], + pack: pack_name, + preload: nil, + skin: nil, + supported_locales: data['locales'], + } + + return pack_data unless data['pack'][pack_name].is_a?(Hash) + + pack_data[:use_common] = false if data['pack'][pack_name]['use_common'] == false + pack_data[:pack] = nil unless data['pack'][pack_name]['filename'] + + preloads = data['pack'][pack_name]['preload'] + pack_data[:preload] = [preloads] if preloads.is_a?(String) + pack_data[:preload] = preloads if preloads.is_a?(Array) + + if skin != 'default' && data['skin'][skin] + pack_data[:skin] = skin if data['skin'][skin].include?(pack_name) + elsif data['pack'][pack_name]['stylesheet'] + pack_data[:skin] = 'default' + end + + pack_data + end + + def resolve_pack(data, pack_name, skin) + return pack(data, pack_name, skin) if valid_pack_data?(data, pack_name) + return if data['name'].blank? + + fallbacks = [] + if data.key?('fallback') + fallbacks = data['fallback'] if data['fallback'].is_a?(Array) + fallbacks = [data['fallback']] if data['fallback'].is_a?(String) + elsif data['name'] != Setting.default_settings['flavour'] + fallbacks = [Setting.default_settings['flavour']] + end + + fallbacks.each do |fallback| + return resolve_pack(Themes.instance.flavour(fallback), pack_name) if Themes.instance.flavour(fallback) + end + + nil + end + + def resolve_pack_with_common(data, pack_name, skin = 'default') + result = resolve_pack(data, pack_name, skin) || nil_pack(data) + result[:common] = resolve_pack(data, 'common', skin) if result.delete(:use_common) + result + end +end diff --git a/app/controllers/concerns/two_factor_authentication_concern.rb b/app/controllers/concerns/two_factor_authentication_concern.rb index 27f2367a8..c9477a1d4 100644 --- a/app/controllers/concerns/two_factor_authentication_concern.rb +++ b/app/controllers/concerns/two_factor_authentication_concern.rb @@ -77,6 +77,8 @@ module TwoFactorAuthenticationConcern def prompt_for_two_factor(user) set_attempt_session(user) + use_pack 'auth' + @body_classes = 'lighter' @webauthn_enabled = user.webauthn_enabled? @scheme_type = begin |