app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include Pagy::Backend
include Authorizable
include Dateable
include Organization::Currentable
delegate :instrument, to: ActiveSupport::Notifications
delegate :local_ephemeral_cache, to: :Rails
before_action :store_ids
before_action :reload_extensions, unless: -> { Rails.env.production? }
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :set_paper_trail_whodunnit
before_action :set_meta_tag_data
before_action :sample_requests_for_scout
before_action :set_ngrok_urls, if: -> { Rails.env.development? }
before_action :allow_cors_requests, unless: -> { Rails.env.production? }
before_action :organization_redirect, if: -> { params["current-organization"] }
before_action -> { Current.user_interface = current_user&.persisted? }
impersonates :user
protected
def sanitize_params(key, params)
params[key].each do |k, v|
params[key][k] = v.select(&:present?).uniq if v.is_a?(Array)
end
params
end
def organization_redirect
redirect_to organization_path(Current.organization)
end
def store_ids
return if is_a?(Untrackable)
cookies.encrypted[:cuid] = current_user&.id
cookies.encrypted[:tuid] = true_user&.id
cookies.encrypted[:sid] = session&.id
end
def device
@device ||= DeviceDetector.new(request.headers["User-Agent"])
end
def device_small?
device.device_type == "smartphone"
end
def clear_searches(except: [])
except = [except] unless except.is_a?(Array)
except = except.map(&:to_s)
session.keys.each do |key|
key = key.to_s
next unless key.end_with?("_search")
next if except.include?(key)
session.delete key
end
end
def allow_cors_requests
headers["Access-Control-Allow-Origin"] = "*"
headers["Access-Control-Request-Method"] = "GET, PUT, POST, UPDATE, DELETE"
end
def set_cors_headers
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Methods"] = "POST, PUT, DELETE, GET, OPTIONS"
response.headers["Access-Control-Request-Method"] = "*"
response.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept, Authorization"
end
def set_no_caching_headers
response.headers["Cache-Control"] = "no-cache, no-store"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = 1.day.ago.httpdate
end
# See https://github.com/kpumuk/meta-tags#allowed-options-for-display_meta_tags-and-set_meta_tags-methods
def set_meta_tag_data
set_meta_tags(
site: "CodeFund",
title: "CodeFund | Ethical Advertising",
description: "CodeFund is an open source platform that helps fund maintainers, bloggers, and builders through non-tracking ethical ads",
keywords: ["open source", "ethical advertising", "advertising", "fund open source"],
charset: "utf-8",
image_src: "https://cdn2.codefund.app/packs/media/images/branding/codefund-logo-square-512-07880204c83ca5c547cc909713157c77.png",
index: true,
icon: [
{href: "/favicon.ico", rel: "shortcut icon"},
{href: "/apple-touch-icon.png", sizes: "180x180", rel: "apple-touch-icon", type: "image/png"},
{href: "/favicon-32x32.png", sizes: "32x32 96x96", rel: "icon", type: "image/png"},
{href: "/favicon-16x16.png", sizes: "16x16", rel: "icon", type: "image/png"},
{href: "/safari-pinned-tab.svg", rel: "mask-icon", color: "#5bbad5", type: "image/svg"}
],
manifest: "/site.webmanifest",
alternate: [
{href: "#{ENV["WORDPRESS_URL"]}/blog/feed", type: "application/rss+xml", title: "RSS"}
],
"apple-mobile-web-app-title": "CodeFund",
"application-name": "CodeFund",
"msapplication-TileColor": "#da532c",
"theme-color": "#3063A0",
og: {
title: :title,
type: "website",
url: request.fullpath,
image: :image_src,
site_name: "CodeFund",
locale: "en_US",
fb: {
admins: "801507563"
}
},
twitter: {
card: "photo",
site: "@codefundio"
},
viewport: "width=device-width, initial-scale=1, shrink-to-fit=no"
)
end
def authenticate_administrator!
return render_forbidden unless AuthorizedUser.new(current_user || User.new).can_admin_system?
end
def render_not_found
render "errors/404", status: :not_found
end
def render_forbidden
render "errors/403", status: :forbidden
end
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:accept_invitation, keys: [:first_name, :last_name])
devise_parameter_sanitizer.permit(:invite, keys: [:first_name, :last_name, :organization_id, roles: []])
end
def reload_extensions
load Rails.root.join("app/lib/extensions.rb")
end
def default_value(development: nil, production: nil)
return production if Rails.env.production?
development || production
end
def sample_requests_for_scout
# Method to be overridden in high-traffic controllers
# Sample rate should range from 0-1:
# * 0: captures no requests
# * 0.75: captures 75% of requests
# * 1: captures all requests
# sample_rate = (ENV["SCOUT_SAMPLE_RATE"] || 1).to_f
# if rand > sample_rate
# Rails.logger.debug("[Scout] Ignoring request: #{request.original_url}")
# ScoutApm::Transaction.ignore!
# end
end
def set_ngrok_urls
if Ngrok::Tunnel.running?
# Getting current url
url = Ngrok::Tunnel.ngrok_url_https
# Variable hash
default_url_options = {host: url}
# Overwriting current variables
Rails.application.config.action_controller.asset_host = url
Rails.application.config.action_mailer.asset_host = url
Rails.application.routes.default_url_options = default_url_options
Rails.application.config.action_mailer.default_url_options = default_url_options
end
end
end