From 5406b0576ea7d6b6f7f38a98c34cb138a5f9ed76 Mon Sep 17 00:00:00 2001 From: Michael Kohl Date: Mon, 12 Apr 2021 14:41:09 +0700 Subject: [PATCH] Split Settings::Authentication from SiteConfig (#13095) * Split Settings::Authentication from SiteConfig * Move specs * Sort fields * Update settings usages * Update recaptcha usages * Add data update script * Update spec * Rename SiteConfigParams concern * Fixes, new route, new controller * Controller and service refactoring * More controller and service updates * Spec updates * More spec fixes * Move file * Fix FeedbackMessagesController * Update admin/configs_spec * Fix remaining specs in admin/configs_spec * Fix configs API * Formatting * Clean up old service object * Various fixes * Update DUS * Add model argument to admin_config_label * Fix key name * Fix specs * Add distinct request caches for settings classes * Fix e2e tests * Fix remaining system spec * Make DUS idempotent * Move routes block * Cleanup * Switch to ActiveSupport::CurrentAttributes * Pinned rails-settings-cached * Update e2e test * Update lib/data_update_scripts/20210316091354_move_authentication_settings.rb Co-authored-by: rhymes * Add guard to DUS * Temporarily re-add two SiteConfig fields * Fix config show view Co-authored-by: rhymes --- Gemfile | 3 +- Gemfile.lock | 20 +- .../javascripts/initializers/runtime.js | 2 +- app/controllers/admin/configs_controller.rb | 43 +- .../settings/authentications_controller.rb | 22 + app/controllers/admin/settings_controller.rb | 30 + .../api/v0/admin/configs_controller.rb | 24 +- ...te_config_params.rb => settings_params.rb} | 22 +- .../feedback_messages_controller.rb | 2 +- app/controllers/registrations_controller.rb | 7 +- app/helpers/application_helper.rb | 7 +- app/helpers/authentication_helper.rb | 5 +- .../admin/controllers/config_controller.js | 8 +- app/javascript/analytics/dashboard.js | 4 +- .../shared/components/useKeyboardShortcuts.js | 4 +- app/lib/constants/settings/authentication.rb | 82 + app/lib/constants/site_config.rb | 74 - app/models/settings/authentication.rb | 44 + app/models/site_config.rb | 33 +- app/services/authentication/providers.rb | 4 +- .../authentication/settings_upsert.rb | 68 + app/services/github/oauth_client.rb | 4 +- app/services/re_captcha/check_enabled.rb | 3 +- .../re_captcha/check_registration_enabled.rb | 7 +- .../{site_configs => settings}/upsert.rb | 27 +- app/services/twitter_client/client.rb | 4 +- .../_apple_auth_provider_settings.html.erb | 24 +- .../configs/_auth_provider_settings.html.erb | 12 +- app/views/admin/configs/show.html.erb | 1405 ++++++++--------- .../registrations/_registration_form.html.erb | 2 +- app/views/devise/registrations/new.html.erb | 2 +- app/views/feedback_messages/_form.html.erb | 2 +- .../_email_registration_form.html.erb | 12 +- .../_providers_registration_form.html.erb | 2 +- config/initializers/devise.rb | 20 +- config/initializers/rails_settings.rb | 44 + config/routes.rb | 3 + .../config/authenticationSection.spec.js | 5 +- cypress/support/commands.js | 12 +- db/migrate/20210316091102_create_settings.rb | 16 + db/schema.rb | 8 + db/seeds.rb | 2 +- ...0316091354_move_authentication_settings.rb | 42 + spec/helpers/authentication_helper_spec.rb | 10 +- spec/models/settings/authentication_spec.rb | 19 + spec/models/site_config_spec.rb | 14 - spec/models/user_spec.rb | 4 +- spec/policies/github_repo_policy_spec.rb | 2 +- spec/requests/admin/configs_spec.rb | 111 +- spec/requests/admin/users_spec.rb | 2 +- spec/requests/api/v0/admin/configs_spec.rb | 8 +- spec/requests/editor_spec.rb | 2 +- spec/requests/feedback_messages_spec.rb | 8 +- spec/requests/github_repos_spec.rb | 2 +- spec/requests/registrations_spec.rb | 43 +- spec/requests/user/user_settings_spec.rb | 2 +- .../authentication/authenticator_spec.rb | 2 +- .../services/authentication/providers_spec.rb | 10 +- .../welcome_notification/generator_spec.rb | 2 +- .../services/re_captcha/check_enabled_spec.rb | 8 +- .../check_registration_enabled_spec.rb | 12 +- spec/services/twitter_client/client_spec.rb | 2 +- spec/services/users/delete_spec.rb | 2 +- .../beta_access_providers_spec.rb | 2 +- .../creator_config_edit_spec.rb | 2 +- .../omniauth_redirect_uri_spec.rb | 2 +- .../redirects_using_referer_spec.rb | 2 +- .../user_logs_in_with_apple_spec.rb | 2 +- .../user_logs_in_with_email_spec.rb | 6 +- .../user_logs_in_with_facebook_spec.rb | 4 +- .../user_logs_in_with_github_spec.rb | 4 +- .../user_logs_in_with_twitter_spec.rb | 4 +- .../user_with_suspended_username_spec.rb | 4 +- .../system/user_logs_in_with_password_spec.rb | 2 +- .../acts_as_follower.gemspec | 3 +- vendor/cache/ahoy_email-2.0.2.gem | Bin 16384 -> 0 bytes vendor/cache/ahoy_email-2.0.3.gem | Bin 0 -> 16384 bytes vendor/cache/chartkick-3.4.2.gem | Bin 167424 -> 0 bytes vendor/cache/chartkick-4.0.2.gem | Bin 0 -> 163840 bytes .../cache/devise-0cd72a56f984/devise.gemspec | 2 +- vendor/cache/loofah-2.9.0.gem | Bin 29696 -> 0 bytes vendor/cache/loofah-2.9.1.gem | Bin 0 -> 29696 bytes vendor/cache/marcel-1.0.0.gem | Bin 39424 -> 0 bytes vendor/cache/marcel-1.0.1.gem | Bin 0 -> 39424 bytes vendor/cache/oauth-0.5.5.gem | Bin 28672 -> 0 bytes vendor/cache/oauth-0.5.6.gem | Bin 0 -> 28672 bytes vendor/cache/parser-3.0.0.0.gem | Bin 626176 -> 0 bytes vendor/cache/parser-3.0.1.0.gem | Bin 0 -> 626688 bytes 88 files changed, 1345 insertions(+), 1125 deletions(-) create mode 100644 app/controllers/admin/settings/authentications_controller.rb create mode 100644 app/controllers/admin/settings_controller.rb rename app/controllers/concerns/{site_config_params.rb => settings_params.rb} (61%) create mode 100644 app/lib/constants/settings/authentication.rb create mode 100644 app/models/settings/authentication.rb create mode 100644 app/services/authentication/settings_upsert.rb rename app/services/{site_configs => settings}/upsert.rb (63%) create mode 100644 config/initializers/rails_settings.rb create mode 100644 db/migrate/20210316091102_create_settings.rb create mode 100644 lib/data_update_scripts/20210316091354_move_authentication_settings.rb create mode 100644 spec/models/settings/authentication_spec.rb delete mode 100644 vendor/cache/ahoy_email-2.0.2.gem create mode 100644 vendor/cache/ahoy_email-2.0.3.gem delete mode 100644 vendor/cache/chartkick-3.4.2.gem create mode 100644 vendor/cache/chartkick-4.0.2.gem delete mode 100644 vendor/cache/loofah-2.9.0.gem create mode 100644 vendor/cache/loofah-2.9.1.gem delete mode 100644 vendor/cache/marcel-1.0.0.gem create mode 100644 vendor/cache/marcel-1.0.1.gem delete mode 100644 vendor/cache/oauth-0.5.5.gem create mode 100644 vendor/cache/oauth-0.5.6.gem delete mode 100644 vendor/cache/parser-3.0.0.0.gem create mode 100644 vendor/cache/parser-3.0.1.0.gem diff --git a/Gemfile b/Gemfile index f246c1e76..acc098082 100644 --- a/Gemfile +++ b/Gemfile @@ -75,7 +75,8 @@ gem "rack-attack", "~> 6.5.0" # Used to throttle requests to prevent brute force gem "rack-cors", "~> 1.1" # Middleware that will make Rack-based apps CORS compatible gem "rack-timeout", "~> 0.6" # Rack middleware which aborts requests that have been running for longer than a specified timeout gem "rails", "~> 6.1" # Ruby on Rails -gem "rails-settings-cached", ">= 2.1.1" # Settings plugin for Rails that makes managing a table of global key, value pairs easy. +# Pinned since we have a monkey-patch against this version +gem "rails-settings-cached", "= 2.5.2" # Settings plugin for Rails that makes managing a table of global key, value pairs easy. gem "ransack", "~> 2.4" # Searching and sorting gem "recaptcha", "~> 5.7", require: "recaptcha/rails" # Helpers for the reCAPTCHA API gem "redcarpet", "~> 3.5" # A fast, safe and extensible Markdown to (X)HTML parser diff --git a/Gemfile.lock b/Gemfile.lock index 1c90fcdef..290ea0870 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -86,7 +86,7 @@ GEM activerecord (>= 5.0, < 6.2) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) - ahoy_email (2.0.2) + ahoy_email (2.0.3) actionmailer (>= 5) addressable (>= 2.3.2) nokogiri @@ -168,7 +168,7 @@ GEM activesupport (>= 3.2.0) carrierwave fastimage - chartkick (3.4.2) + chartkick (4.0.2) childprocess (3.0.0) cloudinary (1.20.0) aws_cf_signer @@ -424,13 +424,13 @@ GEM listen (3.5.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.9.0) + loofah (2.9.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) lumberjack (1.2.8) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (1.0.0) + marcel (1.0.1) memoizable (0.4.2) thread_safe (~> 0.3, >= 0.3.1) memory_profiler (1.0.0) @@ -462,16 +462,12 @@ GEM http-2 (~> 0.11) netrc (0.11.0) nio4r (2.5.7) - nokogiri (1.11.3-arm64-darwin) - racc (~> 1.4) - nokogiri (1.11.3-x86_64-darwin) - racc (~> 1.4) nokogiri (1.11.3-x86_64-linux) racc (~> 1.4) notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) - oauth (0.5.5) + oauth (0.5.6) oauth2 (1.4.7) faraday (>= 0.8, < 2.0) jwt (>= 1.0, < 3.0) @@ -508,7 +504,7 @@ GEM rack orm_adapter (0.5.0) parallel (1.20.1) - parser (3.0.0.0) + parser (3.0.1.0) ast (~> 2.4.1) patron (0.13.3) pg (1.2.3) @@ -843,8 +839,6 @@ GEM zonebie (0.6.1) PLATFORMS - arm64-darwin - x86_64-darwin x86_64-linux DEPENDENCIES @@ -940,7 +934,7 @@ DEPENDENCIES rack-host-redirect (~> 1.3) rack-timeout (~> 0.6) rails (~> 6.1) - rails-settings-cached (>= 2.1.1) + rails-settings-cached (= 2.5.2) ransack (~> 2.4) recaptcha (~> 5.7) redcarpet (~> 3.5) diff --git a/app/assets/javascripts/initializers/runtime.js b/app/assets/javascripts/initializers/runtime.js index 3defd6f6d..b23fae7dd 100644 --- a/app/assets/javascripts/initializers/runtime.js +++ b/app/assets/javascripts/initializers/runtime.js @@ -56,7 +56,7 @@ class Runtime { } else if (/Android/i.test(window.navigator.userAgent)) { return 'Android'; } else if (/Linux/i.test(window.navigator.platform)) { - return 'Linux'; + return 'Linux'; } return 'Unsupported'; diff --git a/app/controllers/admin/configs_controller.rb b/app/controllers/admin/configs_controller.rb index 742a0b291..2c21106b3 100644 --- a/app/controllers/admin/configs_controller.rb +++ b/app/controllers/admin/configs_controller.rb @@ -1,31 +1,9 @@ module Admin - class ConfigsController < Admin::ApplicationController - include SiteConfigParams - - EMOJI_ONLY_FIELDS = %w[community_emoji].freeze - IMAGE_FIELDS = - %w[ - main_social_image - logo_png - secondary_logo_url - campaign_sidebar_image - mascot_image_url - mascot_footer_image_url - onboarding_background_image - ].freeze - - VALID_URL = %r{\A(http|https)://([/|.\w\s-])*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?\z}.freeze - - layout "admin" - - before_action :extra_authorization_and_confirmation, only: [:create] - - def show - @confirmation_text = confirmation_text - end + class ConfigsController < Admin::SettingsController + include SettingsParams def create - result = SiteConfigs::Upsert.call(site_config_params) + result = ::Settings::Upsert.call(settings_params) if result.success? Audit::Logger.log(:internal, current_user, params.dup) bust_content_change_caches @@ -34,20 +12,5 @@ module Admin redirect_to admin_config_path, alert: "😭 #{result.errors.to_sentence}" end end - - private - - def confirmation_text - "My username is @#{current_user.username} and this action is 100% safe and appropriate." - end - - def raise_confirmation_mismatch_error - raise ActionController::BadRequest.new, "The confirmation key does not match" - end - - def extra_authorization_and_confirmation - not_authorized unless current_user.has_role?(:super_admin) - raise_confirmation_mismatch_error if params.require(:confirmation) != confirmation_text - end end end diff --git a/app/controllers/admin/settings/authentications_controller.rb b/app/controllers/admin/settings/authentications_controller.rb new file mode 100644 index 000000000..f99f16f56 --- /dev/null +++ b/app/controllers/admin/settings/authentications_controller.rb @@ -0,0 +1,22 @@ +module Admin + module Settings + class AuthenticationsController < Admin::ApplicationController + def create + result = ::Authentication::SettingsUpsert.call(settings_params) + + if result.success? + Audit::Logger.log(:internal, current_user, params.dup) + redirect_to admin_config_path, notice: "Site configuration was successfully updated." + else + redirect_to admin_config_path, alert: "😭 #{result.errors.to_sentence}" + end + end + + def settings_params + params + .require(:settings_authentication) + .permit(*::Settings::Authentication.keys, :auth_providers_to_enable) + end + end + end +end diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb new file mode 100644 index 000000000..6cd297df6 --- /dev/null +++ b/app/controllers/admin/settings_controller.rb @@ -0,0 +1,30 @@ +module Admin + class SettingsController < Admin::ApplicationController + MISMATCH_ERROR = "The confirmation key does not match".freeze + + before_action :extra_authorization_and_confirmation, only: [:create] + + layout "admin" + + def create; end + + def show + @confirmation_text = confirmation_text + end + + private + + def extra_authorization_and_confirmation + not_authorized unless current_user.has_role?(:super_admin) + raise_confirmation_mismatch_error if params.require(:confirmation) != confirmation_text + end + + def confirmation_text + "My username is @#{current_user.username} and this action is 100% safe and appropriate." + end + + def raise_confirmation_mismatch_error + raise ActionController::BadRequest.new, MISMATCH_ERROR + end + end +end diff --git a/app/controllers/api/v0/admin/configs_controller.rb b/app/controllers/api/v0/admin/configs_controller.rb index f85376f82..9ab9ffdf8 100644 --- a/app/controllers/api/v0/admin/configs_controller.rb +++ b/app/controllers/api/v0/admin/configs_controller.rb @@ -2,7 +2,7 @@ module Api module V0 module Admin class ConfigsController < ApiController - include SiteConfigParams + include SettingsParams before_action :authenticate_with_api_key_or_current_user! before_action :authorize_super_admin @@ -13,16 +13,30 @@ module Api end def update - result = SiteConfigs::Upsert.call(site_config_params) - if result.success? - @site_configs = SiteConfig.all + # NOTE: citizen428 - this is not going to scale but I want to wait + # until we extract at least one more settings model before deciding + # how to change this. + settings_result = ::Settings::Upsert.call(settings_params) + auth_settings_result = ::Authentication::SettingsUpsert.call(auth_settings_params) + + if settings_result.success? && auth_settings_result.success? + @site_configs = SiteConfig.all + Settings::Authentication.all Audit::Logger.log(:internal, @user, params.dup) bust_content_change_caches render "show" else - render json: { error: result.errors.to_sentence, status: 422 }, status: :unprocessable_entity + errors = settings_result.errors + auth_settings_result.errors + render json: { error: errors.to_sentence, status: 422 }, status: :unprocessable_entity end end + + private + + def auth_settings_params + params + .require(:site_config) + .permit(*::Settings::Authentication.keys, :providers_to_enable) + end end end end diff --git a/app/controllers/concerns/site_config_params.rb b/app/controllers/concerns/settings_params.rb similarity index 61% rename from app/controllers/concerns/site_config_params.rb rename to app/controllers/concerns/settings_params.rb index 2ab5e060d..bb4e8cd83 100644 --- a/app/controllers/concerns/site_config_params.rb +++ b/app/controllers/concerns/settings_params.rb @@ -1,16 +1,26 @@ -module SiteConfigParams - SPECIAL_PARAMS_TO_ADD = - %w[authentication_providers email_addresses meta_keywords credit_prices_in_cents auth_providers_to_enable].freeze - def site_config_params +module SettingsParams + SPECIAL_PARAMS_TO_ADD = %w[ + credit_prices_in_cents + email_addresses + meta_keywords + ].freeze + + def settings_params has_emails = params.dig(:site_config, :email_addresses).present? params[:site_config][:email_addresses][:default] = ApplicationConfig["DEFAULT_EMAIL"] if has_emails + params.require(:site_config)&.permit( - (SiteConfig.keys + SPECIAL_PARAMS_TO_ADD).map(&:to_sym), - authentication_providers: [], + settings_keys.map(&:to_sym), social_media_handles: SiteConfig.social_media_handles.keys, email_addresses: SiteConfig.email_addresses.keys, meta_keywords: SiteConfig.meta_keywords.keys, credit_prices_in_cents: SiteConfig.credit_prices_in_cents.keys, ) end + + private + + def settings_keys + SiteConfig.keys + SPECIAL_PARAMS_TO_ADD + end end diff --git a/app/controllers/feedback_messages_controller.rb b/app/controllers/feedback_messages_controller.rb index 8d512a32f..e9bcf01e2 100644 --- a/app/controllers/feedback_messages_controller.rb +++ b/app/controllers/feedback_messages_controller.rb @@ -51,7 +51,7 @@ class FeedbackMessagesController < ApplicationController private def recaptcha_verified? - recaptcha_params = { secret_key: SiteConfig.recaptcha_secret_key } + recaptcha_params = { secret_key: Settings::Authentication.recaptcha_secret_key } params["g-recaptcha-response"] && verify_recaptcha(recaptcha_params) end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 7852342e9..afa7db257 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -13,7 +13,8 @@ class RegistrationsController < Devise::RegistrationsController end def create - not_authorized unless SiteConfig.allow_email_password_registration || SiteConfig.waiting_on_first_user + not_authorized unless Settings::Authentication.allow_email_password_registration || + SiteConfig.waiting_on_first_user not_authorized if SiteConfig.waiting_on_first_user && ENV["FOREM_OWNER_SECRET"].present? && ENV["FOREM_OWNER_SECRET"] != params[:user][:forem_owner_secret] @@ -51,13 +52,13 @@ class RegistrationsController < Devise::RegistrationsController end def recaptcha_verified? - recaptcha_params = { secret_key: SiteConfig.recaptcha_secret_key } + recaptcha_params = { secret_key: Settings::Authentication.recaptcha_secret_key } params["g-recaptcha-response"] && verify_recaptcha(recaptcha_params) end def check_allowed_email(resource) domain = resource.email.split("@").last - allow_list = SiteConfig.allowed_registration_email_domains + allow_list = Settings::Authentication.allowed_registration_email_domains return if allow_list.empty? || allow_list.include?(domain) resource.email = nil diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e1f426cf5..3855c64a5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -96,7 +96,7 @@ module ApplicationHelper end def invite_only_mode? - SiteConfig.invite_only_mode? + Settings::Authentication.invite_only_mode? end def any_enabled_auth_providers? @@ -274,7 +274,7 @@ module ApplicationHelper estimated_user_count > LARGE_USERBASE_THRESHOLD end - def admin_config_label(method, content = nil) + def admin_config_label(method, content = nil, model: SiteConfig) content ||= tag.span(method.to_s.humanize) if method.to_sym.in?(VerifySetupCompleted::MANDATORY_CONFIGS) @@ -282,7 +282,8 @@ module ApplicationHelper content = safe_join([content, required]) end - tag.label(content, class: "site-config__label crayons-field__label", for: "site_config_#{method}") + label_prefix = model.name.split("::").map(&:underscore).join("_") + tag.label(content, class: "site-config__label crayons-field__label", for: "#{label_prefix}_#{method}") end def admin_config_description(content) diff --git a/app/helpers/authentication_helper.rb b/app/helpers/authentication_helper.rb index abd35d7e3..f04c72a5f 100644 --- a/app/helpers/authentication_helper.rb +++ b/app/helpers/authentication_helper.rb @@ -46,8 +46,9 @@ module AuthenticationHelper end def invite_only_mode_or_no_enabled_auth_options - SiteConfig.invite_only_mode || - (authentication_enabled_providers.none? && !SiteConfig.allow_email_password_registration) + Settings::Authentication.invite_only_mode || + (authentication_enabled_providers.none? && + !Settings::Authentication.allow_email_password_registration) end def tooltip_class_on_auth_provider_enablebtn diff --git a/app/javascript/admin/controllers/config_controller.js b/app/javascript/admin/controllers/config_controller.js index a04b05ebe..e4c7c1b0e 100644 --- a/app/javascript/admin/controllers/config_controller.js +++ b/app/javascript/admin/controllers/config_controller.js @@ -293,8 +293,12 @@ export default class ConfigController extends Controller { .forEach((provider) => { const { providerName } = provider.dataset; if ( - !document.getElementById(`site_config_${providerName}_key`).value || - !document.getElementById(`site_config_${providerName}_secret`).value + !document.getElementById( + `settings_authentication_${providerName}_key`, + ).value || + !document.getElementById( + `settings_authentication_${providerName}_secret`, + ).value ) { providersWithMissingKeys.push(providerName); } diff --git a/app/javascript/analytics/dashboard.js b/app/javascript/analytics/dashboard.js index b4365fd64..c078c8805 100644 --- a/app/javascript/analytics/dashboard.js +++ b/app/javascript/analytics/dashboard.js @@ -1,7 +1,9 @@ import { callHistoricalAPI, callReferrersAPI } from './client'; function resetActive(activeButton) { - const buttons = document.querySelectorAll('.crayons-tabs--analytics .crayons-tabs__item'); + const buttons = document.querySelectorAll( + '.crayons-tabs--analytics .crayons-tabs__item', + ); for (let i = 0; i < buttons.length; i += 1) { const button = buttons[i]; button.classList.remove('crayons-tabs__item--current'); diff --git a/app/javascript/shared/components/useKeyboardShortcuts.js b/app/javascript/shared/components/useKeyboardShortcuts.js index 28e40a626..2037ffc45 100644 --- a/app/javascript/shared/components/useKeyboardShortcuts.js +++ b/app/javascript/shared/components/useKeyboardShortcuts.js @@ -27,7 +27,7 @@ function isFormField(element) { /** * Function to handle converting key presses to callback functions - * + * * @param {KeyboardEvent} e Keyboard event * @param {String} keys special keys formatted in a string * @param {Array} chain array of past keys @@ -96,7 +96,7 @@ export function useKeyboardShortcuts( const [keyChain, setKeyChain] = useState([]); const [mergedOptions, setMergedOptions] = useState({ ...defaultOptions, - ...options + ...options, }); // update mergedOptions if options prop changes diff --git a/app/lib/constants/settings/authentication.rb b/app/lib/constants/settings/authentication.rb new file mode 100644 index 000000000..017cf5f6f --- /dev/null +++ b/app/lib/constants/settings/authentication.rb @@ -0,0 +1,82 @@ +module Constants + module Settings + module Authentication + DETAILS = { + allowed_registration_email_domains: { + description: "Restrict registration to only certain emails? (comma-separated list)", + placeholder: "dev.to, forem.com, codenewbie.org" + }, + apple_client_id: { + description: + "The \"App Bundle\" code for the Authentication Service configured in the Apple Developer Portal", + placeholder: "com.example.app" + }, + apple_team_id: { + description: + "The \"Team ID\" of your Apple Developer Account", + placeholder: "" + }, + apple_key_id: { + description: + "The \"Key ID\" from the Authentication Service configured in the Apple Developer Portal", + placeholder: "" + }, + apple_pem: { + description: + "The \"PEM\" key from the Authentication Service configured in the Apple Developer Portal", + placeholder: "-----BEGIN PRIVATE KEY-----\nMIGTAQrux...QPe8Yb\n-----END PRIVATE KEY-----\\n" + }, + display_email_domain_allow_list_publicly: { + description: "Do you want to display the list of allowed domains, or keep it private?" + }, + facebook_key: { + description: + "The \"App ID\" portion of the Basic Settings section of the App page on the Facebook Developer Portal", + placeholder: "" + }, + facebook_secret: { + description: + "The \"App Secret\" portion of the Basic Settings section of the App page on the Facebook Developer Portal", + placeholder: "" + }, + github_key: { + description: "The \"Client ID\" portion of the GitHub Oauth Apps portal", + placeholder: "" + }, + github_secret: { + description: "The \"Client Secret\" portion of the GitHub Oauth Apps portal", + placeholder: "" + }, + invite_only_mode: { + description: "Only users invited by email can join this community.", + placeholder: "" + }, + recaptcha_site_key: { + description: "Add the site key for Google reCAPTCHA, which is used for reporting abuse", + placeholder: "What is the Google reCAPTCHA site key?" + }, + recaptcha_secret_key: { + description: "Add the secret key for Google reCAPTCHA, which is used for reporting abuse", + placeholder: "What is the Google reCAPTCHA secret key?" + }, + require_captcha_for_email_password_registration: { + description: "People will be required to fill out a captcha when + they're creating a new account in your community", + placeholder: "" + }, + twitter_key: { + description: "The \"API key\" portion of consumer keys in the Twitter developer portal.", + placeholder: "" + }, + twitter_secret: { + description: "The \"API secret key\" portion of consumer keys in the Twitter developer portal.", + placeholder: "" + }, + providers: { + description: "How can users sign in?", + placeholder: "" + } + }.freeze + end + end +end diff --git a/app/lib/constants/site_config.rb b/app/lib/constants/site_config.rb index 14d73bdc7..be0a4fd80 100644 --- a/app/lib/constants/site_config.rb +++ b/app/lib/constants/site_config.rb @@ -4,19 +4,6 @@ module Constants SVG_PLACEHOLDER = "".freeze DETAILS = { - require_captcha_for_email_password_registration: { - description: "People will be required to fill out a captcha when - they're creating a new account in your community", - placeholder: "" - }, - allowed_registration_email_domains: { - description: "Restrict registration to only certain emails? (comma-separated list)", - placeholder: "dev.to, forem.com, codenewbie.org" - }, - authentication_providers: { - description: "How can users sign in?", - placeholder: "" - }, campaign_articles_require_approval: { description: "", placeholder: "Campaign stories show up on sidebar with approval?" @@ -90,9 +77,6 @@ module Constants default_font: { description: "Determines the default Base Reading Font (registered users can change this in their UX settings)" }, - display_email_domain_allow_list_publicly: { - description: "Do you want to display the list of allowed domains, or keep it private?" - }, display_jobs_banner: { description: "Display a jobs banner that points users to the jobs page when they type 'job'" \ "or 'jobs' in the search box", @@ -110,36 +94,6 @@ module Constants description: "The label for the top of the experience level range of a post", placeholder: "Senior Devs" }, - facebook_key: { - description: - "The \"App ID\" portion of the Basic Settings section of the App page on the Facebook Developer Portal", - placeholder: "" - }, - facebook_secret: { - description: - "The \"App Secret\" portion of the Basic Settings section of the App page on the Facebook Developer Portal", - placeholder: "" - }, - apple_client_id: { - description: - "The \"App Bundle\" code for the Authentication Service configured in the Apple Developer Portal", - placeholder: "com.example.app" - }, - apple_team_id: { - description: - "The \"Team ID\" of your Apple Developer Account", - placeholder: "" - }, - apple_key_id: { - description: - "The \"Key ID\" from the Authentication Service configured in the Apple Developer Portal", - placeholder: "" - }, - apple_pem: { - description: - "The \"PEM\" key from the Authentication Service configured in the Apple Developer Portal", - placeholder: "-----BEGIN PRIVATE KEY-----\nMIGTAQrux...QPe8Yb\n-----END PRIVATE KEY-----\\n" - }, favicon_url: { description: "Used as the site favicon", placeholder: IMAGE_PLACEHOLDER @@ -157,14 +111,6 @@ module Constants description: "Determines background/border of buttons etc. Must be dark enough to contrast with white text.", placeholder: "#0a0a0a" }, - github_key: { - description: "The \"Client ID\" portion of the GitHub Oauth Apps portal", - placeholder: "" - }, - github_secret: { - description: "The \"Client Secret\" portion of the GitHub Oauth Apps portal", - placeholder: "" - }, ga_tracking_id: { description: "Google Analytics Tracking ID, e.g. UA-71991000-1", placeholder: "" @@ -177,10 +123,6 @@ module Constants description: "Minimum score needed for a post to show up on the unauthenticated home page.", placeholder: "0" }, - invite_only_mode: { - description: "Only users invited by email can join this community.", - placeholder: "" - }, jobs_url: { description: "URL of the website where open positions are posted", placeholder: "Jobs URL" @@ -258,14 +200,6 @@ module Constants description: "Determines how often periodic email digests are sent", placeholder: 2 }, - recaptcha_site_key: { - description: "Add the site key for Google reCAPTCHA, which is used for reporting abuse", - placeholder: "What is the Google reCAPTCHA site key?" - }, - recaptcha_secret_key: { - description: "Add the secret key for Google reCAPTCHA, which is used for reporting abuse", - placeholder: "What is the Google reCAPTCHA secret key?" - }, secondary_logo_url: { description: "A place for an alternate logo, if you have one. Used throughout member onboarding and in some sign in forms.", placeholder: IMAGE_PLACEHOLDER @@ -327,14 +261,6 @@ module Constants description: "Used as the twitter hashtag of the community", placeholder: "#DEVCommunity" }, - twitter_key: { - description: "The \"API key\" portion of consumer keys in the Twitter developer portal.", - placeholder: "" - }, - twitter_secret: { - description: "The \"API secret key\" portion of consumer keys in the Twitter developer portal.", - placeholder: "" - }, user_considered_new_days: { description: "The number of days a user is considered new. The default is 3 days, but you can disable this entirely by inputting 0.", placeholder: ::SiteConfig.user_considered_new_days diff --git a/app/models/settings/authentication.rb b/app/models/settings/authentication.rb new file mode 100644 index 000000000..56db61652 --- /dev/null +++ b/app/models/settings/authentication.rb @@ -0,0 +1,44 @@ +module Settings + class Authentication < RailsSettings::Base + self.table_name = :settings_authentications + + # The configuration is cached, change this if you want to force update + # the cache, or call Settings::Authentication.clear_cache + cache_prefix { "v1" } + + field :allow_email_password_login, type: :boolean, default: true + field :allow_email_password_registration, type: :boolean, default: false + field :allowed_registration_email_domains, type: :array, default: %w[], validates: { + valid_domain_csv: true + } + field :apple_client_id, type: :string + field :apple_key_id, type: :string + field :apple_pem, type: :string + field :apple_team_id, type: :string + field :display_email_domain_allow_list_publicly, type: :boolean, default: false + field :facebook_key, type: :string + field :facebook_secret, type: :string + field :github_key, type: :string, default: ApplicationConfig["GITHUB_KEY"] + field :github_secret, type: :string, default: ApplicationConfig["GITHUB_SECRET"] + field :invite_only_mode, type: :boolean, default: false + field :providers, type: :array, default: %w[] + field :require_captcha_for_email_password_registration, type: :boolean, default: false + field :twitter_key, type: :string, default: ApplicationConfig["TWITTER_KEY"] + field :twitter_secret, type: :string, default: ApplicationConfig["TWITTER_SECRET"] + + # Google ReCATPCHA keys + field :recaptcha_site_key, type: :string, default: ApplicationConfig["RECAPTCHA_SITE"] + field :recaptcha_secret_key, type: :string, default: ApplicationConfig["RECAPTCHA_SECRET"] + + # Apple uses different keys than the usual `PROVIDER_NAME_key` or + # `PROVIDER_NAME_secret` so these will help the generalized authentication + # code to work, i.e. https://github.com/forem/forem/blob/master/app/helpers/authentication_helper.rb#L26-L29 + def self.apple_key + return unless apple_client_id.present? && apple_key_id.present? && + apple_pem.present? && apple_team_id.present? + + "present" + end + singleton_class.alias_method(:apple_secret, :apple_key) + end +end diff --git a/app/models/site_config.rb b/app/models/site_config.rb index b1bc480c0..57d9a873c 100644 --- a/app/models/site_config.rb +++ b/app/models/site_config.rb @@ -29,26 +29,12 @@ class SiteConfig < RailsSettings::Base field :health_check_token, type: :string field :video_encoder_key, type: :string - # Authentication - field :allow_email_password_registration, type: :boolean, default: false - field :allow_email_password_login, type: :boolean, default: true + # NOTE: @citizen428 These two values will be removed once we fully migrated + # to Settings::Authentication. Until then we need them for the data update script. field :allowed_registration_email_domains, type: :array, default: %w[], validates: { valid_domain_csv: true } - field :display_email_domain_allow_list_publicly, type: :boolean, default: false - field :require_captcha_for_email_password_registration, type: :boolean, default: false field :authentication_providers, type: :array, default: %w[] - field :invite_only_mode, type: :boolean, default: false - field :twitter_key, type: :string, default: ApplicationConfig["TWITTER_KEY"] - field :twitter_secret, type: :string, default: ApplicationConfig["TWITTER_SECRET"] - field :github_key, type: :string, default: ApplicationConfig["GITHUB_KEY"] - field :github_secret, type: :string, default: ApplicationConfig["GITHUB_SECRET"] - field :facebook_key, type: :string - field :facebook_secret, type: :string - field :apple_client_id, type: :string - field :apple_key_id, type: :string - field :apple_pem, type: :string - field :apple_team_id, type: :string # Campaign field :campaign_call_to_action, type: :string, default: "Share your project" @@ -98,10 +84,6 @@ class SiteConfig < RailsSettings::Base # Google Analytics Tracking ID, e.g. UA-71991000-1 field :ga_tracking_id, type: :string, default: ApplicationConfig["GA_TRACKING_ID"] - # Google ReCATPCHA keys - field :recaptcha_site_key, type: :string, default: ApplicationConfig["RECAPTCHA_SITE"] - field :recaptcha_secret_key, type: :string, default: ApplicationConfig["RECAPTCHA_SECRET"] - # Images field :main_social_image, type: :string, @@ -248,17 +230,6 @@ class SiteConfig < RailsSettings::Base app_domain == "dev.to" end - # Apple uses different keys than the usual `PROVIDER_NAME_key` or - # `PROVIDER_NAME_secret` so these will help the generalized authentication - # code to work, i.e. https://github.com/forem/forem/blob/master/app/helpers/authentication_helper.rb#L26-L29 - def self.apple_key - return unless apple_client_id.present? && apple_key_id.present? && - apple_pem.present? && apple_team_id.present? - - "present" - end - singleton_class.__send__(:alias_method, :apple_secret, :apple_key) - # To get default values def self.get_default(field) get_field(field)[:default] diff --git a/app/services/authentication/providers.rb b/app/services/authentication/providers.rb index 1275318d1..77550b89b 100644 --- a/app/services/authentication/providers.rb +++ b/app/services/authentication/providers.rb @@ -44,9 +44,9 @@ module Authentication # TODO: [@forem/oss] ideally this should be "available - disabled" # we can get there once we have feature flags def self.enabled - return [] if SiteConfig.invite_only_mode + return [] if Settings::Authentication.invite_only_mode - SiteConfig.authentication_providers.map(&:to_sym).sort + Settings::Authentication.providers.map(&:to_sym).sort end def self.enabled_for_user(user) diff --git a/app/services/authentication/settings_upsert.rb b/app/services/authentication/settings_upsert.rb new file mode 100644 index 000000000..e712e40be --- /dev/null +++ b/app/services/authentication/settings_upsert.rb @@ -0,0 +1,68 @@ +module Authentication + class SettingsUpsert + attr_reader :errors + + def self.call(configs) + new(configs).call + end + + def initialize(configs) + @configs = configs + @errors = [] + end + + def call + upsert_configs + self + end + + def success? + @errors.none? + end + + private + + # NOTE: @citizen428 - This was adapted from Settings::Upsert. I'll see if + # a pattern for refactoring emerges in the future, but for now I'll leave + # this as-is. + def upsert_configs + @configs.each do |key, value| + if key == "auth_providers_to_enable" + update_enabled_providers(value) unless value.class.name != "String" + elsif value.is_a?(Array) && value.any? + Settings::Authentication.public_send("#{key}=", value.reject(&:blank?)) + elsif value.present? + Settings::Authentication.public_send("#{key}=", value.strip) + end + rescue ActiveRecord::RecordInvalid => e + @errors << e.message + next + end + end + + def update_enabled_providers(value) + enabled_providers = value.split(",").filter_map do |entry| + entry unless invalid_provider_entry(entry) + end + return if email_login_disabled_with_one_or_less_auth_providers(enabled_providers) + + Settings::Authentication.providers = enabled_providers + end + + def invalid_provider_entry(entry) + entry.blank? || + Authentication::Providers.available.map(&:to_s).exclude?(entry) || + provider_keys_missing(entry) + end + + def provider_keys_missing(entry) + Settings::Authentication.public_send("#{entry}_key").blank? || + Settings::Authentication.public_send("#{entry}_secret").blank? + end + + def email_login_disabled_with_one_or_less_auth_providers(enabled_providers) + !Settings::Authentication.allow_email_password_login && + enabled_providers.count <= 1 + end + end +end diff --git a/app/services/github/oauth_client.rb b/app/services/github/oauth_client.rb index 1cdd53280..b629b58de 100644 --- a/app/services/github/oauth_client.rb +++ b/app/services/github/oauth_client.rb @@ -7,8 +7,8 @@ module Github # @param credentials [Hash] the OAuth credentials, {client_id:, client_secret:} or {access_token:} def initialize(credentials = nil) credentials ||= { - client_id: SiteConfig.github_key, - client_secret: SiteConfig.github_secret + client_id: Settings::Authentication.github_key, + client_secret: Settings::Authentication.github_secret } @credentials = check_credentials!(credentials) end diff --git a/app/services/re_captcha/check_enabled.rb b/app/services/re_captcha/check_enabled.rb index 2151b5393..03a42e558 100644 --- a/app/services/re_captcha/check_enabled.rb +++ b/app/services/re_captcha/check_enabled.rb @@ -31,7 +31,8 @@ module ReCaptcha private def keys_configured? - SiteConfig.recaptcha_site_key.present? && SiteConfig.recaptcha_secret_key.present? + Settings::Authentication.recaptcha_site_key.present? && + Settings::Authentication.recaptcha_secret_key.present? end end end diff --git a/app/services/re_captcha/check_registration_enabled.rb b/app/services/re_captcha/check_registration_enabled.rb index cace7f521..51a892b5a 100644 --- a/app/services/re_captcha/check_registration_enabled.rb +++ b/app/services/re_captcha/check_registration_enabled.rb @@ -1,13 +1,10 @@ module ReCaptcha class CheckRegistrationEnabled def self.call - new.call - end - - def call # ReCaptcha::CheckEnabled.call without a user parameter will return `true` # if the ReCaptcha SiteConfig keys are configured, and `false` otherwise - ReCaptcha::CheckEnabled.call && SiteConfig.require_captcha_for_email_password_registration + ReCaptcha::CheckEnabled.call && + Settings::Authentication.require_captcha_for_email_password_registration end end end diff --git a/app/services/site_configs/upsert.rb b/app/services/settings/upsert.rb similarity index 63% rename from app/services/site_configs/upsert.rb rename to app/services/settings/upsert.rb index 852beb399..7cc6526af 100644 --- a/app/services/site_configs/upsert.rb +++ b/app/services/settings/upsert.rb @@ -1,4 +1,4 @@ -module SiteConfigs +module Settings class Upsert EMOJI_ONLY_FIELDS = %w[community_emoji].freeze VALID_DOMAIN = /^[a-zA-Z0-9]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.freeze @@ -34,9 +34,7 @@ module SiteConfigs def upsert_configs @configs.each do |key, value| - if key == "auth_providers_to_enable" - update_enabled_auth_providers(value) unless value.class.name != "String" - elsif value.is_a?(Array) + if value.is_a?(Array) SiteConfig.public_send("#{key}=", value.reject(&:blank?)) unless value.empty? elsif value.respond_to?(:to_h) SiteConfig.public_send("#{key}=", value.to_h) unless value.empty? @@ -60,27 +58,6 @@ module SiteConfigs @configs[:credit_prices_in_cents]&.transform_values!(&:to_i) end - def update_enabled_auth_providers(value) - enabled_providers = value.split(",").filter_map do |entry| - entry unless invalid_provider_entry(entry) - end - SiteConfig.public_send("authentication_providers=", enabled_providers) unless - email_login_disabled_with_one_or_less_auth_providers(enabled_providers) - end - - def email_login_disabled_with_one_or_less_auth_providers(enabled_providers) - !SiteConfig.allow_email_password_login && enabled_providers.count <= 1 - end - - def invalid_provider_entry(entry) - entry.blank? || Authentication::Providers.available.map(&:to_s).exclude?(entry) || - provider_keys_missing(entry) - end - - def provider_keys_missing(entry) - SiteConfig.public_send("#{entry}_key").blank? || SiteConfig.public_send("#{entry}_secret").blank? - end - def create_tags_if_not_created # Bulk create tags if they should exist. # This is an acts-as-taggable-on as used on saving of an Article, etc. diff --git a/app/services/twitter_client/client.rb b/app/services/twitter_client/client.rb index c5c5d0fa8..fc03c6c4b 100644 --- a/app/services/twitter_client/client.rb +++ b/app/services/twitter_client/client.rb @@ -57,8 +57,8 @@ module TwitterClient def target Twitter::REST::Client.new( - consumer_key: SiteConfig.twitter_key.presence || ApplicationConfig["TWITTER_KEY"], - consumer_secret: SiteConfig.twitter_secret.presence || ApplicationConfig["TWITTER_SECRET"], + consumer_key: Settings::Authentication.twitter_key.presence || ApplicationConfig["TWITTER_KEY"], + consumer_secret: Settings::Authentication.twitter_secret.presence || ApplicationConfig["TWITTER_SECRET"], user_agent: "TwitterRubyGem/#{Twitter::Version} (#{URL.url})", timeouts: { connect: 5, diff --git a/app/views/admin/configs/_apple_auth_provider_settings.html.erb b/app/views/admin/configs/_apple_auth_provider_settings.html.erb index 51db996c0..ce5c858db 100644 --- a/app/views/admin/configs/_apple_auth_provider_settings.html.erb +++ b/app/views/admin/configs/_apple_auth_provider_settings.html.erb @@ -11,42 +11,42 @@ requires a custom partial
<%= admin_config_label :apple_client_id %>

- <%= Constants::SiteConfig::DETAILS[:apple_client_id][:description] %> + <%= Constants::Settings::Authentication::DETAILS[:apple_client_id][:description] %>

<%= f.text_field :apple_client_id, class: "crayons-textfield", - value: SiteConfig.apple_client_id, - placeholder: Constants::SiteConfig::DETAILS[:apple_client_id][:placeholder] %> + value: Settings::Authentication.apple_client_id, + placeholder: Constants::Settings::Authentication::DETAILS[:apple_client_id][:placeholder] %>
<%= admin_config_label :apple_key_id %>

- <%= Constants::SiteConfig::DETAILS[:apple_key_id][:description] %> + <%= Constants::Settings::Authentication::DETAILS[:apple_key_id][:description] %>

<%= f.text_field :apple_key_id, class: "crayons-textfield", - value: SiteConfig.apple_key_id, - placeholder: Constants::SiteConfig::DETAILS[:apple_key_id][:placeholder] %> + value: Settings::Authentication.apple_key_id, + placeholder: Constants::Settings::Authentication::DETAILS[:apple_key_id][:placeholder] %>

<%= admin_config_label :apple_pem %>

- <%= Constants::SiteConfig::DETAILS[:apple_pem][:description] %> + <%= Constants::Settings::Authentication::DETAILS[:apple_pem][:description] %>

<%= f.text_field :apple_pem, class: "crayons-textfield", - value: SiteConfig.apple_pem, - placeholder: Constants::SiteConfig::DETAILS[:apple_pem][:placeholder] %> + value: Settings::Authentication.apple_pem, + placeholder: Constants::Settings::Authentication::DETAILS[:apple_pem][:placeholder] %>

<%= admin_config_label :apple_team_id %>

- <%= Constants::SiteConfig::DETAILS[:apple_team_id][:description] %> + <%= Constants::Settings::Authentication::DETAILS[:apple_team_id][:description] %>

<%= f.text_field :apple_team_id, class: "crayons-textfield", - value: SiteConfig.apple_team_id, - placeholder: Constants::SiteConfig::DETAILS[:apple_team_id][:placeholder] %> + value: Settings::Authentication.apple_team_id, + placeholder: Constants::Settings::Authentication::DETAILS[:apple_team_id][:placeholder] %>

<% if authentication_provider_enabled?(provider) %> diff --git a/app/views/admin/configs/_auth_provider_settings.html.erb b/app/views/admin/configs/_auth_provider_settings.html.erb index 4f9698fdc..c79ac3c1e 100644 --- a/app/views/admin/configs/_auth_provider_settings.html.erb +++ b/app/views/admin/configs/_auth_provider_settings.html.erb @@ -2,22 +2,22 @@
<%= admin_config_label :"#{provider.provider_name}_key" %>

- <%= Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_key"][:description] %> + <%= Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_key"][:description] %>

<%= f.text_field :"#{provider.provider_name}_key", class: "crayons-textfield", - value: SiteConfig.public_send("#{provider.provider_name}_key"), - placeholder: Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_key"][:placeholder] %> + value: Settings::Authentication.public_send("#{provider.provider_name}_key"), + placeholder: Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_key"][:placeholder] %>
<%= admin_config_label :"#{provider.provider_name}_secret" %>

- <%= Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_secret"][:description] %> + <%= Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_secret"][:description] %>

<%= f.text_field :"#{provider.provider_name}_secret", class: "crayons-textfield", - value: SiteConfig.public_send("#{provider.provider_name}_secret"), - placeholder: Constants::SiteConfig::DETAILS[:"#{provider.provider_name}_secret"][:placeholder] %> + value: Settings::Authentication.public_send("#{provider.provider_name}_secret"), + placeholder: Constants::Settings::Authentication::DETAILS[:"#{provider.provider_name}_secret"][:placeholder] %>

<% if authentication_provider_enabled?(provider) %> diff --git a/app/views/admin/configs/show.html.erb b/app/views/admin/configs/show.html.erb index 17255a575..b5192c8ad 100644 --- a/app/views/admin/configs/show.html.erb +++ b/app/views/admin/configs/show.html.erb @@ -147,7 +147,7 @@
<% end %> - <%= form_for(SiteConfig.new, url: admin_config_path, html: { data: { action: "submit->config#configUpdatePrecheck", "config-target": "authSectionForm", testid: "authSectionForm" } }) do |f| %> + <%= form_for(Settings::Authentication.new, url: admin_settings_authentications_path, html: { data: { action: "submit->config#configUpdatePrecheck", "config-target": "authSectionForm", testid: "authSectionForm" } }) do |f| %>
<%= render partial: "admin/shared/card_header", locals: { @@ -166,11 +166,11 @@ data-tooltip="Unchecking this will enable Email Registration"> <%= f.check_box :invite_only_mode, checked: invite_only_mode_or_no_enabled_auth_options, - data: { action: "config#adjustAuthenticationOptions", target: "config.inviteOnlyMode" }, + data: { action: "config#adjustAuthenticationOptions", "config-target": "inviteOnlyMode" }, class: "crayons-checkbox" %>
- <%= admin_config_label :invite_only_mode, "Invite-only mode" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:invite_only_mode][:description] %> + <%= admin_config_label :invite_only_mode, "Invite-only mode", model: Settings::Authentication %> + <%= admin_config_description Constants::Settings::Authentication::DETAILS[:invite_only_mode][:description] %>
@@ -194,11 +194,11 @@ data-tooltip="<%= tooltip_text_email_or_auth_provider_btns %>">
-

"> +

"> Email address

" + class="enabled-indicator <%= Settings::Authentication.allow_email_password_registration ? "visible" : "" %>" data-config-target="enabledIndicator"> <%= inline_svg_tag("checkmark.svg", aria: true, class: "crayons-icon admin-config-checkmark", title: "Email enabled") %> Enabled @@ -208,11 +208,11 @@
@@ -220,67 +220,67 @@
- <%= admin_config_label :allowed_registration_email_domains, "Allowed email domains" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:allowed_registration_email_domains][:description] %> + <%= admin_config_label :allowed_registration_email_domains, "Allowed email domains", model: Settings::Authentication %> + <%= admin_config_description Constants::Settings::Authentication::DETAILS[:allowed_registration_email_domains][:description] %> <%= f.text_field :allowed_registration_email_domains, class: "crayons-textfield", - value: SiteConfig.allowed_registration_email_domains.join(","), - placeholder: Constants::SiteConfig::DETAILS[:allowed_registration_email_domains][:placeholder] %> + value: Settings::Authentication.allowed_registration_email_domains.join(","), + placeholder: Constants::Settings::Authentication::DETAILS[:allowed_registration_email_domains][:placeholder] %>
<%= f.check_box :display_email_domain_allow_list_publicly, - checked: SiteConfig.display_email_domain_allow_list_publicly, + checked: Settings::Authentication.display_email_domain_allow_list_publicly, id: "email-display-emails-publicly-checkbox", class: "crayons-checkbox mt-2" %>
- <%= admin_config_label :display_email_domain_allow_list_publicly %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:display_email_domain_allow_list_publicly][:description] %> + <%= admin_config_label :display_email_domain_allow_list_publicly, model: Settings::Authentication %> + <%= admin_config_description Constants::Settings::Authentication::DETAILS[:display_email_domain_allow_list_publicly][:description] %>
<%= f.check_box :require_captcha_for_email_password_registration, - checked: SiteConfig.require_captcha_for_email_password_registration, + checked: Settings::Authentication.require_captcha_for_email_password_registration, data: { action: "config#toggleGoogleRecaptchaFields", "config-target": "requireCaptchaForEmailPasswordRegistration" }, class: "crayons-checkbox mt-2" %>
- <%= admin_config_label :require_captcha_for_email_password_registration, "Enable Google reCAPTCHA for email password registration" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:require_captcha_for_email_password_registration][:description] %> + <%= admin_config_label :require_captcha_for_email_password_registration, "Enable Google reCAPTCHA for email password registration", model: Settings::Authentication %> + <%= admin_config_description Constants::Settings::Authentication::DETAILS[:require_captcha_for_email_password_registration][:description] %>
-
" aria-labelledby="recaptchaContainer"> +
" aria-labelledby="recaptchaContainer">
- <%= admin_config_label :recaptcha_site_key, "Google reCAPTCHA site key" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:recaptcha_site_key][:description] %> + <%= admin_config_label :recaptcha_site_key, "Google reCAPTCHA site key", model: Settings::Authentication %> + <%= admin_config_description Constants::Settings::Authentication::DETAILS[:recaptcha_site_key][:description] %> <%= f.text_field :recaptcha_site_key, class: "crayons-textfield", - value: SiteConfig.recaptcha_site_key, - placeholder: Constants::SiteConfig::DETAILS[:recaptcha_site_key][:placeholder] %> + value: Settings::Authentication.recaptcha_site_key, + placeholder: Constants::Settings::Authentication::DETAILS[:recaptcha_site_key][:placeholder] %>
- <%= admin_config_label :recaptcha_secret_key, "Google reCAPTCHA secret key" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:recaptcha_secret_key][:description] %> + <%= admin_config_label :recaptcha_secret_key, "Google reCAPTCHA secret key", model: Settings::Authentication %> + <%= admin_config_description Constants::Settings::Authentication::DETAILS[:recaptcha_secret_key][:description] %> <%= f.text_field :recaptcha_secret_key, class: "crayons-textfield", - value: SiteConfig.recaptcha_secret_key, - placeholder: Constants::SiteConfig::DETAILS[:recaptcha_secret_key][:placeholder] %> + value: Settings::Authentication.recaptcha_secret_key, + placeholder: Constants::Settings::Authentication::DETAILS[:recaptcha_secret_key][:placeholder] %>
- <% if SiteConfig.allow_email_password_registration %> + <% if Settings::Authentication.allow_email_password_registration %> -
<% authentication_available_providers.each do |provider| %> @@ -319,7 +319,7 @@ data-tooltip="<%= tooltip_text_email_or_auth_provider_btns %>">

"> - <%= provider.official_name %> + <%= provider.official_name %>

-
-
-
- <%= admin_config_label :campaign_hero_html_variant_name, "Campaign hero HTML variant name" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_hero_html_variant_name][:description] %> - <%= f.text_field :campaign_hero_html_variant_name, - class: "crayons-textfield", - value: SiteConfig.campaign_hero_html_variant_name, - placeholder: Constants::SiteConfig::DETAILS[:campaign_hero_html_variant_name][:placeholder] %> -
+
+
+
+ <%= admin_config_label :campaign_hero_html_variant_name, "Campaign hero HTML variant name" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_hero_html_variant_name][:description] %> + <%= f.text_field :campaign_hero_html_variant_name, + class: "crayons-textfield", + value: SiteConfig.campaign_hero_html_variant_name, + placeholder: Constants::SiteConfig::DETAILS[:campaign_hero_html_variant_name][:placeholder] %> +
-
- <%= f.check_box :campaign_articles_require_approval, checked: SiteConfig.campaign_articles_require_approval, class: "crayons-checkbox" %> - <%= admin_config_label :campaign_articles_require_approval %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_articles_require_approval][:description] %> -
+
+ <%= f.check_box :campaign_articles_require_approval, checked: SiteConfig.campaign_articles_require_approval, class: "crayons-checkbox" %> + <%= admin_config_label :campaign_articles_require_approval %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_articles_require_approval][:description] %> +
-
- <%= f.check_box :campaign_sidebar_enabled, checked: SiteConfig.campaign_sidebar_enabled, class: "crayons-checkbox" %> - <%= admin_config_label :campaign_sidebar_enabled %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_sidebar_enabled][:description] %> -
+
+ <%= f.check_box :campaign_sidebar_enabled, checked: SiteConfig.campaign_sidebar_enabled, class: "crayons-checkbox" %> + <%= admin_config_label :campaign_sidebar_enabled %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_sidebar_enabled][:description] %> +
-
- <%= admin_config_label :campaign_sidebar_image %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_sidebar_image][:description] %> - <% if SiteConfig.campaign_sidebar_image.present? %> -
-
- Campaign sidebar image -
+
+ <%= admin_config_label :campaign_sidebar_image %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_sidebar_image][:description] %> + <% if SiteConfig.campaign_sidebar_image.present? %> +
+
+ Campaign sidebar image
- <% end %> - <%= f.text_field :campaign_sidebar_image, +
+ <% end %> + <%= f.text_field :campaign_sidebar_image, + class: "crayons-textfield", + value: SiteConfig.campaign_sidebar_image, + placeholder: Constants::SiteConfig::DETAILS[:campaign_sidebar_image][:placeholder] %> +
+ +
+ <%= admin_config_label :campaign_url, "Campaign URL" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_url][:description] %> + <%= f.text_field :campaign_url, + class: "crayons-textfield", + value: SiteConfig.campaign_url, + placeholder: Constants::SiteConfig::DETAILS[:campaign_url][:placeholder] %> +
+ +
+ <%= admin_config_label :campaign_featured_tags %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_featured_tags][:description] %> + <%= f.text_field :campaign_featured_tags, + class: "crayons-textfield", + value: SiteConfig.campaign_featured_tags.join(","), + placeholder: Constants::SiteConfig::DETAILS[:campaign_featured_tags][:placeholder] %> +
+ +
+ <%= admin_config_label :campaign_call_to_action, "Campaign Call to Action" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_call_to_action][:description] %> + <%= f.text_field :campaign_call_to_action, + class: "crayons-textfield", + value: SiteConfig.campaign_call_to_action, + placeholder: Constants::SiteConfig::DETAILS[:campaign_call_to_action][:placeholder] %> +
+ +
+ <%= admin_config_label :campaign_articles_expiry_time, "Campaign article expiry time" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_articles_expiry_time][:description] %> + <%= f.number_field :campaign_articles_expiry_time, class: "crayons-textfield", - value: SiteConfig.campaign_sidebar_image, - placeholder: Constants::SiteConfig::DETAILS[:campaign_sidebar_image][:placeholder] %> -
+ value: SiteConfig.campaign_articles_expiry_time, + placeholder: Constants::SiteConfig::DETAILS[:campaign_articles_expiry_time][:placeholder] %> +
-
- <%= admin_config_label :campaign_url, "Campaign URL" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_url][:description] %> - <%= f.text_field :campaign_url, - class: "crayons-textfield", - value: SiteConfig.campaign_url, - placeholder: Constants::SiteConfig::DETAILS[:campaign_url][:placeholder] %> -
- -
- <%= admin_config_label :campaign_featured_tags %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_featured_tags][:description] %> - <%= f.text_field :campaign_featured_tags, - class: "crayons-textfield", - value: SiteConfig.campaign_featured_tags.join(","), - placeholder: Constants::SiteConfig::DETAILS[:campaign_featured_tags][:placeholder] %> -
- -
- <%= admin_config_label :campaign_call_to_action, "Campaign Call to Action" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_call_to_action][:description] %> - <%= f.text_field :campaign_call_to_action, - class: "crayons-textfield", - value: SiteConfig.campaign_call_to_action, - placeholder: Constants::SiteConfig::DETAILS[:campaign_call_to_action][:placeholder] %> -
- -
- <%= admin_config_label :campaign_articles_expiry_time, "Campaign article expiry time" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:campaign_articles_expiry_time][:description] %> - <%= f.number_field :campaign_articles_expiry_time, - class: "crayons-textfield", - value: SiteConfig.campaign_articles_expiry_time, - placeholder: Constants::SiteConfig::DETAILS[:campaign_articles_expiry_time][:placeholder] %> -
- - <%= render "form_submission", f: f %> -
-
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -462,91 +462,91 @@ target: "contentBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :community_name %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:community_name][:description] %> - <%= f.text_field :community_name, - class: "crayons-textfield", - value: SiteConfig.community_name, - placeholder: Constants::SiteConfig::DETAILS[:community_name][:placeholder] %> -
+
+
+
+ <%= admin_config_label :community_name %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:community_name][:description] %> + <%= f.text_field :community_name, + class: "crayons-textfield", + value: SiteConfig.community_name, + placeholder: Constants::SiteConfig::DETAILS[:community_name][:placeholder] %> +
-
- <%= admin_config_label :community_emoji %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:community_emoji][:description] %> - <%= f.text_field :community_emoji, - class: "crayons-textfield", - value: SiteConfig.community_emoji, - placeholder: Constants::SiteConfig::DETAILS[:community_emoji][:placeholder] %> -
+
+ <%= admin_config_label :community_emoji %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:community_emoji][:description] %> + <%= f.text_field :community_emoji, + class: "crayons-textfield", + value: SiteConfig.community_emoji, + placeholder: Constants::SiteConfig::DETAILS[:community_emoji][:placeholder] %> +
-
- <%= admin_config_label :tagline %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:tagline][:description] %> - <%= f.text_field :tagline, - class: "crayons-textfield", - value: SiteConfig.tagline, - placeholder: Constants::SiteConfig::DETAILS[:tagline][:placeholder] %> -
+
+ <%= admin_config_label :tagline %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:tagline][:description] %> + <%= f.text_field :tagline, + class: "crayons-textfield", + value: SiteConfig.tagline, + placeholder: Constants::SiteConfig::DETAILS[:tagline][:placeholder] %> +
-
- <%= admin_config_label :community_description %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:community_description][:description] %> - <%= f.text_field :community_description, - class: "crayons-textfield", - value: SiteConfig.community_description, - placeholder: Constants::SiteConfig::DETAILS[:community_description][:placeholder] %> -
+
+ <%= admin_config_label :community_description %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:community_description][:description] %> + <%= f.text_field :community_description, + class: "crayons-textfield", + value: SiteConfig.community_description, + placeholder: Constants::SiteConfig::DETAILS[:community_description][:placeholder] %> +
-
- <%= admin_config_label :community_member_label %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:community_member_label][:description] %> - <%= f.text_field :community_member_label, - class: "crayons-textfield", - value: SiteConfig.community_member_label, - placeholder: Constants::SiteConfig::DETAILS[:community_member_label][:placeholder] %> -
+
+ <%= admin_config_label :community_member_label %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:community_member_label][:description] %> + <%= f.text_field :community_member_label, + class: "crayons-textfield", + value: SiteConfig.community_member_label, + placeholder: Constants::SiteConfig::DETAILS[:community_member_label][:placeholder] %> +
-
- <%= admin_config_label :community_copyright_start_year %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:community_copyright_start_year][:description] %> - <%= f.text_field :community_copyright_start_year, - class: "crayons-textfield", - value: SiteConfig.community_copyright_start_year, - placeholder: Constants::SiteConfig::DETAILS[:community_copyright_start_year][:placeholder] %> -
+
+ <%= admin_config_label :community_copyright_start_year %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:community_copyright_start_year][:description] %> + <%= f.text_field :community_copyright_start_year, + class: "crayons-textfield", + value: SiteConfig.community_copyright_start_year, + placeholder: Constants::SiteConfig::DETAILS[:community_copyright_start_year][:placeholder] %> +
-
- <%= admin_config_label :staff_user_id %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:staff_user_id][:description] %> - <%= f.text_field :staff_user_id, - class: "crayons-textfield", - value: SiteConfig.staff_user_id, - placeholder: Constants::SiteConfig::DETAILS[:staff_user_id][:placeholder] %> -
+
+ <%= admin_config_label :staff_user_id %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:staff_user_id][:description] %> + <%= f.text_field :staff_user_id, + class: "crayons-textfield", + value: SiteConfig.staff_user_id, + placeholder: Constants::SiteConfig::DETAILS[:staff_user_id][:placeholder] %> +
-
- <%= admin_config_label :experience_low %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:experience_low][:description] %> - <%= f.text_field :experience_low, - class: "crayons-texfield", - value: SiteConfig.experience_low, - placeholder: Constants::SiteConfig::DETAILS[:experience_low][:placeholder] %> -
+
+ <%= admin_config_label :experience_low %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:experience_low][:description] %> + <%= f.text_field :experience_low, + class: "crayons-texfield", + value: SiteConfig.experience_low, + placeholder: Constants::SiteConfig::DETAILS[:experience_low][:placeholder] %> +
-
- <%= admin_config_label :experience_high %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:experience_high][:description] %> - <%= f.text_field :experience_high, - class: "crayons-texfield", - value: SiteConfig.experience_high, - placeholder: Constants::SiteConfig::DETAILS[:experience_high][:placeholder] %> -
- <%= render "form_submission", f: f %> -
-
+
+ <%= admin_config_label :experience_high %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:experience_high][:description] %> + <%= f.text_field :experience_high, + class: "crayons-texfield", + value: SiteConfig.experience_high, + placeholder: Constants::SiteConfig::DETAILS[:experience_high][:placeholder] %> +
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -560,44 +560,44 @@ expanded: false } %> -
-
- <%= f.fields_for :credit_prices_in_cents do |price_field| %> -
- <%= admin_config_label "Credit price in cents (S)" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:small][:description] %> - <%= price_field.number_field :small, - class: "crayons-textfield", - value: SiteConfig.credit_prices_in_cents[:small] %> -
+
+
+ <%= f.fields_for :credit_prices_in_cents do |price_field| %> +
+ <%= admin_config_label "Credit price in cents (S)" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:small][:description] %> + <%= price_field.number_field :small, + class: "crayons-textfield", + value: SiteConfig.credit_prices_in_cents[:small] %> +
-
- <%= admin_config_label "Credit price in cents (M)" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:medium][:description] %> - <%= price_field.number_field :medium, - class: "crayons-textfield", - value: SiteConfig.credit_prices_in_cents[:medium] %> -
-
- <%= admin_config_label "Credit price in cents (L)" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:large][:description] %> - <%= price_field.number_field :large, - class: "crayons-textfield", - value: SiteConfig.credit_prices_in_cents[:large] %> -
+
+ <%= admin_config_label "Credit price in cents (M)" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:medium][:description] %> + <%= price_field.number_field :medium, + class: "crayons-textfield", + value: SiteConfig.credit_prices_in_cents[:medium] %> +
+
+ <%= admin_config_label "Credit price in cents (L)" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:large][:description] %> + <%= price_field.number_field :large, + class: "crayons-textfield", + value: SiteConfig.credit_prices_in_cents[:large] %> +
-
- <%= admin_config_label "Credit price in cents (XL)" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:xlarge][:description] %> - <%= price_field.number_field :xlarge, - class: "crayons-textfield", - value: SiteConfig.credit_prices_in_cents[:xlarge] %> -
- <% end %> +
+ <%= admin_config_label "Credit price in cents (XL)" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:credit_prices_in_cents][:xlarge][:description] %> + <%= price_field.number_field :xlarge, + class: "crayons-textfield", + value: SiteConfig.credit_prices_in_cents[:xlarge] %> +
+ <% end %> - <%= render "form_submission", f: f %> -
-
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -610,59 +610,32 @@ target: "emailBodyContainer", expanded: false } %> -
-
-
- -
- Default (set via default_email environment variable) -
- " class="form-control" readonly> -
- <%= f.fields_for :email_addresses do |email_field| %> - <% SiteConfig.email_addresses.except(:default).each do |type, address| %> -
- <%= admin_config_label type %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:email_addresses][:description] %> - <%= email_field.text_field type, - class: "crayons-textfield", - value: SiteConfig.email_addresses[type], - placeholder: Constants::SiteConfig::DETAILS[:email_addresses][:placeholder] %> -
- <% end %> - <% end %> - - <%= render "form_submission", f: f %> -
-
-
- <% end %> - - <%= form_for(SiteConfig.new, url: admin_config_path) do |f| %> -
- <%= render partial: "admin/shared/card_header", - locals: { - header: "Email digest frequency", - state: "collapse", - target: "emailDigestBodyContainer", - expanded: false - } %> -
-
-
- <%= admin_config_label :periodic_email_digest %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:periodic_email_digest][:description] %> - <%= f.number_field :periodic_email_digest, - class: "crayons-textfield", - value: SiteConfig.periodic_email_digest, - placeholder: Constants::SiteConfig::DETAILS[:periodic_email_digest][:placeholder] %> +
+
+
+ +
+ Default (set via default_email environment variable)
+ " class="form-control" readonly> +
+ <%= f.fields_for :email_addresses do |email_field| %> + <% SiteConfig.email_addresses.except(:default).each do |type, address| %> +
+ <%= admin_config_label type %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:email_addresses][:description] %> + <%= email_field.text_field type, + class: "crayons-textfield", + value: SiteConfig.email_addresses[type], + placeholder: Constants::SiteConfig::DETAILS[:email_addresses][:placeholder] %> +
+ <% end %> + <% end %> - <%= render "form_submission", f: f %> -
-
+ <%= render "form_submission", f: f %> +
<% end %> @@ -675,27 +648,27 @@ target: "jobsBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :jobs_url, "Jobs URL" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:jobs_url][:description] %> - <%= f.text_field :jobs_url, - class: "crayons-textfield", - value: SiteConfig.jobs_url, - placeholder: Constants::SiteConfig::DETAILS[:jobs_url][:placeholder] %> -
-
- <%= f.check_box :display_jobs_banner, checked: SiteConfig.display_jobs_banner, class: "crayons-checkbox" %> -
- <%= admin_config_label :display_jobs_banner %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:display_jobs_banner][:description] %> -
+
+
+
+ <%= admin_config_label :jobs_url, "Jobs URL" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:jobs_url][:description] %> + <%= f.text_field :jobs_url, + class: "crayons-textfield", + value: SiteConfig.jobs_url, + placeholder: Constants::SiteConfig::DETAILS[:jobs_url][:placeholder] %> +
+
+ <%= f.check_box :display_jobs_banner, checked: SiteConfig.display_jobs_banner, class: "crayons-checkbox" %> +
+ <%= admin_config_label :display_jobs_banner %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:display_jobs_banner][:description] %>
+
- <%= render "form_submission", f: f %> -
-
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -708,19 +681,19 @@ target: "gaBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :ga_tracking_id, "View ID" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:ga_tracking_id][:description] %> - <%= f.text_field :ga_tracking_id, - class: "crayons-textfield", - value: SiteConfig.ga_tracking_id %> -
+
+
+
+ <%= admin_config_label :ga_tracking_id, "View ID" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:ga_tracking_id][:description] %> + <%= f.text_field :ga_tracking_id, + class: "crayons-textfield", + value: SiteConfig.ga_tracking_id %> +
- <%= render "form_submission", f: f %> -
-
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -733,72 +706,72 @@ target: "imagesBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :main_social_image %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:main_social_image][:description] %> - <%= f.text_field :main_social_image, - class: "crayons-textfield", - value: SiteConfig.main_social_image, - placeholder: Constants::SiteConfig::DETAILS[:main_social_image][:placeholder] %> - <% if SiteConfig.main_social_image.present? %> - main social image - <% end %> -
+
+
+
+ <%= admin_config_label :main_social_image %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:main_social_image][:description] %> + <%= f.text_field :main_social_image, + class: "crayons-textfield", + value: SiteConfig.main_social_image, + placeholder: Constants::SiteConfig::DETAILS[:main_social_image][:placeholder] %> + <% if SiteConfig.main_social_image.present? %> + main social image + <% end %> +
-
- <%= admin_config_label :favicon_url, "Favicon URL" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:favicon_url][:description] %> - <%= f.text_field :favicon_url, - class: "form-control", - value: SiteConfig.favicon_url, - placeholder: Constants::SiteConfig::DETAILS[:favicon_url][:placeholder] %> - favicon -
+
+ <%= admin_config_label :favicon_url, "Favicon URL" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:favicon_url][:description] %> + <%= f.text_field :favicon_url, + class: "form-control", + value: SiteConfig.favicon_url, + placeholder: Constants::SiteConfig::DETAILS[:favicon_url][:placeholder] %> + favicon +
-
- <%= admin_config_label :logo_png %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:logo_png][:description] %> - <%= f.text_field :logo_png, - class: "crayons-textfield", - value: SiteConfig.logo_png, - placeholder: Constants::SiteConfig::DETAILS[:logo_png][:placeholder] %> - <% if SiteConfig.logo_png.present? %> - - <% end %> -
+
+ <%= admin_config_label :logo_png %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:logo_png][:description] %> + <%= f.text_field :logo_png, + class: "crayons-textfield", + value: SiteConfig.logo_png, + placeholder: Constants::SiteConfig::DETAILS[:logo_png][:placeholder] %> + <% if SiteConfig.logo_png.present? %> + + <% end %> +
-
- <%= admin_config_label :logo_svg %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:logo_svg][:description] %> - <%= f.text_area :logo_svg, - class: "crayons-textfield", - value: SiteConfig.logo_svg, - rows: 6, - placeholder: Constants::SiteConfig::DETAILS[:logo_svg][:placeholder] %> - <% if SiteConfig.logo_svg.present? %> - - <% end %> -
+
+ <%= admin_config_label :logo_svg %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:logo_svg][:description] %> + <%= f.text_area :logo_svg, + class: "crayons-textfield", + value: SiteConfig.logo_svg, + rows: 6, + placeholder: Constants::SiteConfig::DETAILS[:logo_svg][:placeholder] %> + <% if SiteConfig.logo_svg.present? %> + + <% end %> +
-
- <%= admin_config_label :secondary_logo_url %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:secondary_logo_url][:description] %> - <%= f.text_field :secondary_logo_url, - class: "crayons-textfield", - value: SiteConfig.secondary_logo_url, - placeholder: Constants::SiteConfig::DETAILS[:secondary_logo_url][:placeholder] %> - <% if SiteConfig.secondary_logo_url.present? %> - secondary logo image - <% end %> -
+
+ <%= admin_config_label :secondary_logo_url %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:secondary_logo_url][:description] %> + <%= f.text_field :secondary_logo_url, + class: "crayons-textfield", + value: SiteConfig.secondary_logo_url, + placeholder: Constants::SiteConfig::DETAILS[:secondary_logo_url][:placeholder] %> + <% if SiteConfig.secondary_logo_url.present? %> + secondary logo image + <% end %> +
- <%= render "form_submission", f: f %> -
-
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -811,72 +784,72 @@ target: "mascotBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :mascot_user_id, "Mascot user ID" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_user_id][:description] %> - <%= f.text_field :mascot_user_id, - class: "crayons-textfield", - value: SiteConfig.mascot_user_id, - min: 1, - placeholder: Constants::SiteConfig::DETAILS[:mascot_user_id][:placeholder] %> -
- -
- <%= admin_config_label :mascot_image_url, "Mascot Image URL" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_image_url][:description] %> - <%= f.text_field :mascot_image_url, - class: "crayons-textfield", - value: SiteConfig.mascot_image_url, - placeholder: Constants::SiteConfig::DETAILS[:mascot_image_url][:placeholder] %> - -
- <%= SiteConfig.mascot_image_description %> -
- -
- -
- <%= admin_config_label :mascot_footer_image_url %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_footer_image_url][:description] %> - <%= f.text_field :mascot_footer_image_url, - class: "crayons-textfield", - value: SiteConfig.mascot_footer_image_url, - placeholder: Constants::SiteConfig::DETAILS[:mascot_footer_image_url][:placeholder] %> - -
- <%= SiteConfig.mascot_image_description %> -
-
- -
- <%= admin_config_label :mascot_footer_image_width %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_footer_image_width][:description] %> - <%= f.text_field :mascot_footer_image_width, - class: "form-control", - value: SiteConfig.mascot_footer_image_width %> -
- -
- <%= admin_config_label :mascot_footer_image_height %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_footer_image_height][:description] %> - <%= f.text_field :mascot_footer_image_height, - class: "form-control", - value: SiteConfig.mascot_footer_image_height %> -
- -
- <%= admin_config_label :mascot_image_description %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_image_description][:description] %> - <%= f.text_field :mascot_image_description, - class: "form-control", - value: SiteConfig.mascot_image_description %> -
- - <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :mascot_user_id, "Mascot user ID" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_user_id][:description] %> + <%= f.text_field :mascot_user_id, + class: "crayons-textfield", + value: SiteConfig.mascot_user_id, + min: 1, + placeholder: Constants::SiteConfig::DETAILS[:mascot_user_id][:placeholder] %>
+ +
+ <%= admin_config_label :mascot_image_url, "Mascot Image URL" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_image_url][:description] %> + <%= f.text_field :mascot_image_url, + class: "crayons-textfield", + value: SiteConfig.mascot_image_url, + placeholder: Constants::SiteConfig::DETAILS[:mascot_image_url][:placeholder] %> + +
+ <%= SiteConfig.mascot_image_description %> +
+ +
+ +
+ <%= admin_config_label :mascot_footer_image_url %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_footer_image_url][:description] %> + <%= f.text_field :mascot_footer_image_url, + class: "crayons-textfield", + value: SiteConfig.mascot_footer_image_url, + placeholder: Constants::SiteConfig::DETAILS[:mascot_footer_image_url][:placeholder] %> + +
+ <%= SiteConfig.mascot_image_description %> +
+
+ +
+ <%= admin_config_label :mascot_footer_image_width %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_footer_image_width][:description] %> + <%= f.text_field :mascot_footer_image_width, + class: "form-control", + value: SiteConfig.mascot_footer_image_width %> +
+ +
+ <%= admin_config_label :mascot_footer_image_height %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_footer_image_height][:description] %> + <%= f.text_field :mascot_footer_image_height, + class: "form-control", + value: SiteConfig.mascot_footer_image_height %> +
+ +
+ <%= admin_config_label :mascot_image_description %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mascot_image_description][:description] %> + <%= f.text_field :mascot_image_description, + class: "form-control", + value: SiteConfig.mascot_image_description %> +
+ + <%= render "form_submission", f: f %> +
+
<% end %> @@ -889,26 +862,26 @@ target: "metaKeywordsBodyContainer", expanded: false } %> -
-
- <%= f.fields_for :meta_keywords do |meta_keywords_field| %> - <% SiteConfig.meta_keywords.each do |area, keywords| %> -
- <%= admin_config_label area.to_s %> -

- <%= area.capitalize %><%= "page" unless area == "default" %> keywords -

- <%= meta_keywords_field.text_field area, - class: "crayons-textfield", - value: SiteConfig.meta_keywords[area], - placeholder: Constants::SiteConfig::DETAILS[:meta_keywords][:placeholder] %> -
- <% end %> - <% end %> +
+
+ <%= f.fields_for :meta_keywords do |meta_keywords_field| %> + <% SiteConfig.meta_keywords.each do |area, keywords| %> +
+ <%= admin_config_label area.to_s %> +

+ <%= area.capitalize %><%= "page" unless area == "default" %> keywords +

+ <%= meta_keywords_field.text_field area, + class: "crayons-textfield", + value: SiteConfig.meta_keywords[area], + placeholder: Constants::SiteConfig::DETAILS[:meta_keywords][:placeholder] %> +
+ <% end %> + <% end %> - <%= render "form_submission", f: f %> -
-
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -921,47 +894,47 @@ target: "monetizationBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :shop_url, "Shop URL" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:shop_url][:description] %> - <%= f.text_field :shop_url, - class: "crayons-textfield", - value: SiteConfig.shop_url, - placeholder: Constants::SiteConfig::DETAILS[:shop_url][:placeholder] %> -
- -
- <%= admin_config_label :stripe_api_key, "Stripe API key" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:stripe_api_key][:description] %> - <%= f.text_field :stripe_api_key, - class: "crayons-textfield", - value: SiteConfig.stripe_api_key, - placeholder: Constants::SiteConfig::DETAILS[:stripe_api_key][:placeholder] %> -
- -
- <%= admin_config_label :stripe_publishable_key %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:stripe_publishable_key][:description] %> - <%= f.text_field :stripe_publishable_key, - class: "crayons-textfield", - value: SiteConfig.stripe_publishable_key, - placeholder: Constants::SiteConfig::DETAILS[:stripe_publishable_key][:placeholder] %> -
- -
- <%= admin_config_label :payment_pointer %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:payment_pointer][:description] %> - <%= f.text_field :payment_pointer, - class: "crayons-textfield", - value: SiteConfig.payment_pointer, - placeholder: Constants::SiteConfig::DETAILS[:payment_pointer][:placeholder] %> -
- - <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :shop_url, "Shop URL" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:shop_url][:description] %> + <%= f.text_field :shop_url, + class: "crayons-textfield", + value: SiteConfig.shop_url, + placeholder: Constants::SiteConfig::DETAILS[:shop_url][:placeholder] %>
+ +
+ <%= admin_config_label :stripe_api_key, "Stripe API key" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:stripe_api_key][:description] %> + <%= f.text_field :stripe_api_key, + class: "crayons-textfield", + value: SiteConfig.stripe_api_key, + placeholder: Constants::SiteConfig::DETAILS[:stripe_api_key][:placeholder] %> +
+ +
+ <%= admin_config_label :stripe_publishable_key %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:stripe_publishable_key][:description] %> + <%= f.text_field :stripe_publishable_key, + class: "crayons-textfield", + value: SiteConfig.stripe_publishable_key, + placeholder: Constants::SiteConfig::DETAILS[:stripe_publishable_key][:placeholder] %> +
+ +
+ <%= admin_config_label :payment_pointer %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:payment_pointer][:description] %> + <%= f.text_field :payment_pointer, + class: "crayons-textfield", + value: SiteConfig.payment_pointer, + placeholder: Constants::SiteConfig::DETAILS[:payment_pointer][:placeholder] %> +
+ + <%= render "form_submission", f: f %> +
+
<% end %> @@ -974,51 +947,51 @@ target: "newsletterBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :mailchimp_api_key, "Mailchimp API Key" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_api_key][:description] %> - <%= f.text_field :mailchimp_api_key, - class: "crayons-textfield", - value: SiteConfig.mailchimp_api_key %> -
- -
- <%= admin_config_label :mailchimp_newsletter_id, "Main Newsletter" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_newsletter_id][:description] %> - <%= f.text_field :mailchimp_newsletter_id, - class: "crayons-textfield", - value: SiteConfig.mailchimp_newsletter_id %> -
- -
- <%= admin_config_label :mailchimp_sustaining_members_id, "Sustaining Members Newsletter" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_sustaining_members_id][:description] %> - <%= f.text_field :mailchimp_sustaining_members_id, - class: "crayons-textfield", - value: SiteConfig.mailchimp_sustaining_members_id %> -
- -
- <%= admin_config_label :mailchimp_tag_moderators_id, "Tag Moderators Newsletter" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_tag_moderators_id][:description] %> - <%= f.text_field :mailchimp_tag_moderators_id, - class: "crayons-textfield", - value: SiteConfig.mailchimp_tag_moderators_id %> -
- -
- <%= admin_config_label :mailchimp_community_moderators_id, "Community Moderators Newsletter" %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_community_moderators_id][:description] %> - <%= f.text_field :mailchimp_community_moderators_id, - class: "crayons-textfield", - value: SiteConfig.mailchimp_community_moderators_id %> -
- - <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :mailchimp_api_key, "Mailchimp API Key" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_api_key][:description] %> + <%= f.text_field :mailchimp_api_key, + class: "crayons-textfield", + value: SiteConfig.mailchimp_api_key %>
+ +
+ <%= admin_config_label :mailchimp_newsletter_id, "Main Newsletter" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_newsletter_id][:description] %> + <%= f.text_field :mailchimp_newsletter_id, + class: "crayons-textfield", + value: SiteConfig.mailchimp_newsletter_id %> +
+ +
+ <%= admin_config_label :mailchimp_sustaining_members_id, "Sustaining Members Newsletter" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_sustaining_members_id][:description] %> + <%= f.text_field :mailchimp_sustaining_members_id, + class: "crayons-textfield", + value: SiteConfig.mailchimp_sustaining_members_id %> +
+ +
+ <%= admin_config_label :mailchimp_tag_moderators_id, "Tag Moderators Newsletter" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_tag_moderators_id][:description] %> + <%= f.text_field :mailchimp_tag_moderators_id, + class: "crayons-textfield", + value: SiteConfig.mailchimp_tag_moderators_id %> +
+ +
+ <%= admin_config_label :mailchimp_community_moderators_id, "Community Moderators Newsletter" %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:mailchimp_community_moderators_id][:description] %> + <%= f.text_field :mailchimp_community_moderators_id, + class: "crayons-textfield", + value: SiteConfig.mailchimp_community_moderators_id %> +
+ + <%= render "form_submission", f: f %> +
+
<% end %> @@ -1031,44 +1004,44 @@ target: "onboardingBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :onboarding_background_image %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:onboarding_background_image][:description] %> - <%= f.text_field :onboarding_background_image, - class: "crayons-textfield", - value: SiteConfig.onboarding_background_image, - placeholder: Constants::SiteConfig::DETAILS[:onboarding_background_image][:placeholder] %> -
-
- onboarding background image -
+
+
+
+ <%= admin_config_label :onboarding_background_image %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:onboarding_background_image][:description] %> + <%= f.text_field :onboarding_background_image, + class: "crayons-textfield", + value: SiteConfig.onboarding_background_image, + placeholder: Constants::SiteConfig::DETAILS[:onboarding_background_image][:placeholder] %> +
+
+ onboarding background image
+
-
- <%= admin_config_label :suggested_users %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:suggested_users][:description] %> - <%= f.text_field :suggested_users, - class: "crayons-textfield", - value: SiteConfig.suggested_users.join(","), - placeholder: Constants::SiteConfig::DETAILS[:suggested_users][:placeholder] %> -
- -
- <%= f.check_box :prefer_manual_suggested_users, checked: SiteConfig.prefer_manual_suggested_users, class: "crayons-checkbox" %> -
- <%= admin_config_label :prefer_manual_suggested_users %> -

- <%= Constants::SiteConfig::DETAILS[:prefer_manual_suggested_users][:description] %> -

-
-
- - <%= render "form_submission", f: f %> -
+
+ <%= admin_config_label :suggested_users %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:suggested_users][:description] %> + <%= f.text_field :suggested_users, + class: "crayons-textfield", + value: SiteConfig.suggested_users.join(","), + placeholder: Constants::SiteConfig::DETAILS[:suggested_users][:placeholder] %>
+ +
+ <%= f.check_box :prefer_manual_suggested_users, checked: SiteConfig.prefer_manual_suggested_users, class: "crayons-checkbox" %> +
+ <%= admin_config_label :prefer_manual_suggested_users %> +

+ <%= Constants::SiteConfig::DETAILS[:prefer_manual_suggested_users][:description] %> +

+
+
+ + <%= render "form_submission", f: f %> +
+
<% end %> @@ -1081,42 +1054,42 @@ target: "rateLimitsBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :user_considered_new_days %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:user_considered_new_days][:description] %> - <%= f.number_field :user_considered_new_days, - class: "crayons-textfield", - value: SiteConfig.user_considered_new_days, - placeholder: Constants::SiteConfig::DETAILS[:user_considered_new_days][:placeholder] %> -
- - <% configurable_rate_limits.each do |key, field_hash| %> -
- <%= admin_config_label field_hash[:title] %> -

- <%= field_hash[:description] %> -

- <%= f.number_field key, - class: "crayons-textfield", - value: SiteConfig.public_send(key), - min: field_hash[:min], - placeholder: field_hash[:placeholder] %> -
- <% end %> - -
- <%= admin_config_label :spam_trigger_terms %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:spam_trigger_terms][:description] %> - <%= f.text_area :spam_trigger_terms, - class: "crayons-textfield", - value: SiteConfig.spam_trigger_terms.join(","), - placeholder: Constants::SiteConfig::DETAILS[:spam_trigger_terms][:placeholder] %> -
- <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :user_considered_new_days %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:user_considered_new_days][:description] %> + <%= f.number_field :user_considered_new_days, + class: "crayons-textfield", + value: SiteConfig.user_considered_new_days, + placeholder: Constants::SiteConfig::DETAILS[:user_considered_new_days][:placeholder] %>
+ + <% configurable_rate_limits.each do |key, field_hash| %> +
+ <%= admin_config_label field_hash[:title] %> +

+ <%= field_hash[:description] %> +

+ <%= f.number_field key, + class: "crayons-textfield", + value: SiteConfig.public_send(key), + min: field_hash[:min], + placeholder: field_hash[:placeholder] %> +
+ <% end %> + +
+ <%= admin_config_label :spam_trigger_terms %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:spam_trigger_terms][:description] %> + <%= f.text_area :spam_trigger_terms, + class: "crayons-textfield", + value: SiteConfig.spam_trigger_terms.join(","), + placeholder: Constants::SiteConfig::DETAILS[:spam_trigger_terms][:placeholder] %> +
+ <%= render "form_submission", f: f %> +
+
<% end %> @@ -1129,34 +1102,34 @@ target: "socialMediaBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :twitter_hashtag %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:twitter_hashtag][:description] %> - <%= f.text_field :twitter_hashtag, - class: "crayons-textfield", - value: SiteConfig.twitter_hashtag.to_s, - placeholder: Constants::SiteConfig::DETAILS[:twitter_hashtag][:placeholder] %> -
- <%= f.fields_for :social_media_handles do |social_media_field| %> - <% SiteConfig.social_media_handles.each do |platform, username| %> -
- <%= admin_config_label platform %> -

- <%= platform.capitalize %> username -

- <%= social_media_field.text_field platform, - class: "crayons-textfield", - value: SiteConfig.social_media_handles[platform], - placeholder: "" %> -
- <% end %> - <% end %> - - <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :twitter_hashtag %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:twitter_hashtag][:description] %> + <%= f.text_field :twitter_hashtag, + class: "crayons-textfield", + value: SiteConfig.twitter_hashtag.to_s, + placeholder: Constants::SiteConfig::DETAILS[:twitter_hashtag][:placeholder] %>
+ <%= f.fields_for :social_media_handles do |social_media_field| %> + <% SiteConfig.social_media_handles.each do |platform, username| %> +
+ <%= admin_config_label platform %> +

+ <%= platform.capitalize %> username +

+ <%= social_media_field.text_field platform, + class: "crayons-textfield", + value: SiteConfig.social_media_handles[platform], + placeholder: "" %> +
+ <% end %> + <% end %> + + <%= render "form_submission", f: f %> +
+
<% end %> @@ -1169,20 +1142,20 @@ target: "sponsorsContainer", expanded: false } %> -
-
-
- <%= admin_config_label :sponsor_headline %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:sponsor_headline][:description] %> - <%= f.text_field :sponsor_headline, - class: "crayons-textfield", - value: SiteConfig.sponsor_headline, - placeholder: Constants::SiteConfig::DETAILS[:sponsor_headline][:placeholder] %> -
- - <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :sponsor_headline %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:sponsor_headline][:description] %> + <%= f.text_field :sponsor_headline, + class: "crayons-textfield", + value: SiteConfig.sponsor_headline, + placeholder: Constants::SiteConfig::DETAILS[:sponsor_headline][:placeholder] %>
+ + <%= render "form_submission", f: f %> +
+
<% end %> @@ -1195,21 +1168,21 @@ target: "tagsBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :sidebar_tags %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:sidebar_tags][:description] %> - <%= f.text_field :sidebar_tags, - class: "crayons-textfield", - value: SiteConfig.sidebar_tags.join(","), - placeholder: Constants::SiteConfig::DETAILS[:sidebar_tags][:placeholder], - pattern: "[a-z0-9,]+" %> -
- - <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :sidebar_tags %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:sidebar_tags][:description] %> + <%= f.text_field :sidebar_tags, + class: "crayons-textfield", + value: SiteConfig.sidebar_tags.join(","), + placeholder: Constants::SiteConfig::DETAILS[:sidebar_tags][:placeholder], + pattern: "[a-z0-9,]+" %>
+ + <%= render "form_submission", f: f %> +
+
<% end %> @@ -1222,73 +1195,73 @@ target: "uxBodyContainer", expanded: false } %> -
-
-
- <%= admin_config_label :feed_style %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:feed_style][:description] %> - <%= f.text_field :feed_style, - class: "crayons-textfield", - value: SiteConfig.feed_style, - placeholder: Constants::SiteConfig::DETAILS[:feed_style][:placeholder] %> -
-
- <%= admin_config_label :feed_strategy %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:feed_strategy][:description] %> - <%= f.text_field :feed_strategy, - class: "crayons-textfield", - value: SiteConfig.feed_strategy, - placeholder: Constants::SiteConfig::DETAILS[:feed_strategy][:placeholder] %> -
-
- <%= admin_config_label :tag_feed_minimum_score %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:tag_feed_minimum_score][:description] %> - <%= f.number_field :tag_feed_minimum_score, - class: "crayons-textfield", - value: SiteConfig.tag_feed_minimum_score, - placeholder: Constants::SiteConfig::DETAILS[:tag_feed_minimum_score][:placeholder] %> -
-
- <%= admin_config_label :home_feed_minimum_score %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:home_feed_minimum_score][:description] %> - <%= f.number_field :home_feed_minimum_score, - class: "crayons-textfield", - value: SiteConfig.home_feed_minimum_score, - placeholder: Constants::SiteConfig::DETAILS[:home_feed_minimum_score][:placeholder] %> -
-
- <%= admin_config_label :default_font %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:default_font][:description] %> - <%= select_tag "site_config[default_font]", - options_for_select( - [%w[sans-serif sans_serif], %w[serif serif], %w[open-dyslexic open_dyslexic]], - SiteConfig.default_font, - ), - multiple: false, - class: "selectpicker" %> -
-
- <%= admin_config_label :primary_brand_color_hex %> - <%= admin_config_description Constants::SiteConfig::DETAILS[:primary_brand_color_hex][:description] %> - <%= f.color_field :primary_brand_color_hex, - class: "crayons-color-selector", - value: SiteConfig.primary_brand_color_hex, - pattern: "^#+([a-fA-F0-9]{6})$", - placeholder: Constants::SiteConfig::DETAILS[:primary_brand_color_hex][:placeholder] %> -
-
- <%= f.check_box :public, checked: SiteConfig.public, class: "crayons-checkbox" %> -
- <%= admin_config_label :public %> -

- Are most of the site pages (e.g. posts, profiles) public? Please take precaution when changing this setting. -

-
-
- - <%= render "form_submission", f: f %> -
+
+
+
+ <%= admin_config_label :feed_style %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:feed_style][:description] %> + <%= f.text_field :feed_style, + class: "crayons-textfield", + value: SiteConfig.feed_style, + placeholder: Constants::SiteConfig::DETAILS[:feed_style][:placeholder] %>
+
+ <%= admin_config_label :feed_strategy %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:feed_strategy][:description] %> + <%= f.text_field :feed_strategy, + class: "crayons-textfield", + value: SiteConfig.feed_strategy, + placeholder: Constants::SiteConfig::DETAILS[:feed_strategy][:placeholder] %> +
+
+ <%= admin_config_label :tag_feed_minimum_score %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:tag_feed_minimum_score][:description] %> + <%= f.number_field :tag_feed_minimum_score, + class: "crayons-textfield", + value: SiteConfig.tag_feed_minimum_score, + placeholder: Constants::SiteConfig::DETAILS[:tag_feed_minimum_score][:placeholder] %> +
+
+ <%= admin_config_label :home_feed_minimum_score %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:home_feed_minimum_score][:description] %> + <%= f.number_field :home_feed_minimum_score, + class: "crayons-textfield", + value: SiteConfig.home_feed_minimum_score, + placeholder: Constants::SiteConfig::DETAILS[:home_feed_minimum_score][:placeholder] %> +
+
+ <%= admin_config_label :default_font %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:default_font][:description] %> + <%= select_tag "site_config[default_font]", + options_for_select( + [%w[sans-serif sans_serif], %w[serif serif], %w[open-dyslexic open_dyslexic]], + SiteConfig.default_font, + ), + multiple: false, + class: "selectpicker" %> +
+
+ <%= admin_config_label :primary_brand_color_hex %> + <%= admin_config_description Constants::SiteConfig::DETAILS[:primary_brand_color_hex][:description] %> + <%= f.color_field :primary_brand_color_hex, + class: "crayons-color-selector", + value: SiteConfig.primary_brand_color_hex, + pattern: "^#+([a-fA-F0-9]{6})$", + placeholder: Constants::SiteConfig::DETAILS[:primary_brand_color_hex][:placeholder] %> +
+
+ <%= f.check_box :public, checked: SiteConfig.public, class: "crayons-checkbox" %> +
+ <%= admin_config_label :public %> +

+ Are most of the site pages (e.g. posts, profiles) public? Please take precaution when changing this setting. +

+
+
+ + <%= render "form_submission", f: f %> +
+
<% end %> diff --git a/app/views/devise/registrations/_registration_form.html.erb b/app/views/devise/registrations/_registration_form.html.erb index 67cc9f4e1..3ffd2dcb0 100644 --- a/app/views/devise/registrations/_registration_form.html.erb +++ b/app/views/devise/registrations/_registration_form.html.erb @@ -24,7 +24,7 @@ <% else %>
- <% if SiteConfig.allow_email_password_login %> + <% if Settings::Authentication.allow_email_password_login %>
Have a password? Continue with your email address diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb index bce8a7895..ceef512ac 100644 --- a/app/views/devise/registrations/new.html.erb +++ b/app/views/devise/registrations/new.html.erb @@ -1,6 +1,6 @@ <% title "Welcome!" %> -<% if params[:state] == "email_signup" && SiteConfig.allow_email_password_registration %> +<% if params[:state] == "email_signup" && Settings::Authentication.allow_email_password_registration %> <%= render "shared/authentication/email_registration_form" %> <% elsif params[:state] == "email_signup" %>
diff --git a/app/views/feedback_messages/_form.html.erb b/app/views/feedback_messages/_form.html.erb index dd530071a..b8ef71df9 100644 --- a/app/views/feedback_messages/_form.html.erb +++ b/app/views/feedback_messages/_form.html.erb @@ -69,7 +69,7 @@ <% if ReCaptcha::CheckEnabled.call(current_user) %>
- <%= recaptcha_tags site_key: SiteConfig.recaptcha_site_key %> + <%= recaptcha_tags site_key: Settings::Authentication.recaptcha_site_key %>
<% end %> diff --git a/app/views/shared/authentication/_email_registration_form.html.erb b/app/views/shared/authentication/_email_registration_form.html.erb index 09e11974c..a075e6b30 100644 --- a/app/views/shared/authentication/_email_registration_form.html.erb +++ b/app/views/shared/authentication/_email_registration_form.html.erb @@ -29,15 +29,15 @@ <% else %>

Create your account

<% end %> - <% if SiteConfig.display_email_domain_allow_list_publicly && - SiteConfig.allowed_registration_email_domains.any? %> + <% if Settings::Authentication.display_email_domain_allow_list_publicly && + Settings::Authentication.allowed_registration_email_domains.any? %>
- <% if SiteConfig.allowed_registration_email_domains.one? %> - Registration restricted to @<%= SiteConfig.allowed_registration_email_domains.first %> emails. + <% if Settings::Authentication.allowed_registration_email_domains.one? %> + Registration restricted to @<%= Settings::Authentication.allowed_registration_email_domains.first %> emails. <% else %> Registration restricted to the following emails