mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 09:12:45 +08:00
DEV: Upgrade to Rails 7
This patch upgrades Rails to version 7.0.2.4.
This commit is contained in:
parent
532f9cdb1a
commit
008b700a3f
|
@ -13,6 +13,7 @@ allowed:
|
||||||
ignored:
|
ignored:
|
||||||
bundler:
|
bundler:
|
||||||
- rchardet # Ruby terms
|
- rchardet # Ruby terms
|
||||||
|
- strscan # Ruby
|
||||||
|
|
||||||
reviewed:
|
reviewed:
|
||||||
bundler:
|
bundler:
|
||||||
|
@ -31,10 +32,16 @@ reviewed:
|
||||||
- highline # GPL-2.0 OR Ruby terms
|
- highline # GPL-2.0 OR Ruby terms
|
||||||
- htmlentities # MIT
|
- htmlentities # MIT
|
||||||
- image_size # MIT
|
- image_size # MIT
|
||||||
|
- io-wait # Ruby terms
|
||||||
- json # Ruby terms
|
- json # Ruby terms
|
||||||
- jwt # MIT
|
- jwt # MIT
|
||||||
- kgio # LGPL-2.1+
|
- kgio # LGPL-2.1+
|
||||||
- logstash-event # Apache-2.0
|
- logstash-event # Apache-2.0
|
||||||
|
- net-http # Ruby
|
||||||
|
- net-imap # Ruby
|
||||||
|
- net-pop # Ruby
|
||||||
|
- net-protocol # Ruby
|
||||||
|
- net-smtp # Ruby
|
||||||
- omniauth # MIT
|
- omniauth # MIT
|
||||||
- openssl # Ruby terms
|
- openssl # Ruby terms
|
||||||
- pg # Ruby terms
|
- pg # Ruby terms
|
||||||
|
@ -44,5 +51,7 @@ reviewed:
|
||||||
- rubyzip # Ruby terms
|
- rubyzip # Ruby terms
|
||||||
- sidekiq # LGPL (Sidekiq)
|
- sidekiq # LGPL (Sidekiq)
|
||||||
- tilt
|
- tilt
|
||||||
|
- timeout # Ruby
|
||||||
- unf # BSD-2-Clause
|
- unf # BSD-2-Clause
|
||||||
- unicorn
|
- unicorn
|
||||||
|
- uri # Ruby
|
||||||
|
|
10
Gemfile
10
Gemfile
|
@ -18,7 +18,7 @@ else
|
||||||
# this allows us to include the bits of rails we use without pieces we do not.
|
# this allows us to include the bits of rails we use without pieces we do not.
|
||||||
#
|
#
|
||||||
# To issue a rails update bump the version number here
|
# To issue a rails update bump the version number here
|
||||||
rails_version = '6.1.4.7'
|
rails_version = '7.0.2.4'
|
||||||
gem 'actionmailer', rails_version
|
gem 'actionmailer', rails_version
|
||||||
gem 'actionpack', rails_version
|
gem 'actionpack', rails_version
|
||||||
gem 'actionview', rails_version
|
gem 'actionview', rails_version
|
||||||
|
@ -68,7 +68,7 @@ gem 'http_accept_language', require: false
|
||||||
gem 'discourse-ember-rails', '0.18.6', require: 'ember-rails'
|
gem 'discourse-ember-rails', '0.18.6', require: 'ember-rails'
|
||||||
gem 'discourse-ember-source', '~> 3.12.2'
|
gem 'discourse-ember-source', '~> 3.12.2'
|
||||||
gem 'ember-handlebars-template', '0.8.0'
|
gem 'ember-handlebars-template', '0.8.0'
|
||||||
gem 'discourse-fonts'
|
gem 'discourse-fonts', require: 'discourse_fonts'
|
||||||
|
|
||||||
gem 'barber'
|
gem 'barber'
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ if ENV["ALLOW_DEV_POPULATE"] == "1"
|
||||||
gem 'discourse_dev_assets'
|
gem 'discourse_dev_assets'
|
||||||
gem 'faker', "~> 2.16"
|
gem 'faker', "~> 2.16"
|
||||||
else
|
else
|
||||||
group :development do
|
group :development, :test do
|
||||||
gem 'discourse_dev_assets'
|
gem 'discourse_dev_assets'
|
||||||
gem 'faker', "~> 2.16"
|
gem 'faker', "~> 2.16"
|
||||||
end
|
end
|
||||||
|
@ -268,3 +268,7 @@ gem 'colored2', require: false
|
||||||
gem 'maxminddb'
|
gem 'maxminddb'
|
||||||
|
|
||||||
gem 'rails_failover', require: false
|
gem 'rails_failover', require: false
|
||||||
|
|
||||||
|
# workaround for faraday-net_http, see
|
||||||
|
# https://github.com/ruby/net-imap/issues/16#issuecomment-803086765
|
||||||
|
gem 'net-http'
|
||||||
|
|
89
Gemfile.lock
89
Gemfile.lock
|
@ -8,22 +8,25 @@ GIT
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (6.1.4.7)
|
actionmailer (7.0.2.4)
|
||||||
actionpack (= 6.1.4.7)
|
actionpack (= 7.0.2.4)
|
||||||
actionview (= 6.1.4.7)
|
actionview (= 7.0.2.4)
|
||||||
activejob (= 6.1.4.7)
|
activejob (= 7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
|
net-imap
|
||||||
|
net-pop
|
||||||
|
net-smtp
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (6.1.4.7)
|
actionpack (7.0.2.4)
|
||||||
actionview (= 6.1.4.7)
|
actionview (= 7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
rack (~> 2.0, >= 2.0.9)
|
rack (~> 2.0, >= 2.2.0)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||||
actionview (6.1.4.7)
|
actionview (7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
|
@ -32,20 +35,19 @@ GEM
|
||||||
actionview (>= 6.0.a)
|
actionview (>= 6.0.a)
|
||||||
active_model_serializers (0.8.4)
|
active_model_serializers (0.8.4)
|
||||||
activemodel (>= 3.0)
|
activemodel (>= 3.0)
|
||||||
activejob (6.1.4.7)
|
activejob (7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (6.1.4.7)
|
activemodel (7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
activerecord (6.1.4.7)
|
activerecord (7.0.2.4)
|
||||||
activemodel (= 6.1.4.7)
|
activemodel (= 7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
activesupport (6.1.4.7)
|
activesupport (7.0.2.4)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
tzinfo (~> 2.0)
|
tzinfo (~> 2.0)
|
||||||
zeitwerk (~> 2.3)
|
|
||||||
addressable (2.8.0)
|
addressable (2.8.0)
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
annotate (3.2.0)
|
annotate (3.2.0)
|
||||||
|
@ -106,6 +108,7 @@ GEM
|
||||||
debug_inspector (1.1.0)
|
debug_inspector (1.1.0)
|
||||||
diff-lcs (1.5.0)
|
diff-lcs (1.5.0)
|
||||||
diffy (3.4.0)
|
diffy (3.4.0)
|
||||||
|
digest (3.1.0)
|
||||||
discourse-ember-rails (0.18.6)
|
discourse-ember-rails (0.18.6)
|
||||||
active_model_serializers
|
active_model_serializers
|
||||||
ember-data-source (>= 1.0.0.beta.5)
|
ember-data-source (>= 1.0.0.beta.5)
|
||||||
|
@ -185,6 +188,7 @@ GEM
|
||||||
progress (~> 3.0, >= 3.0.1)
|
progress (~> 3.0, >= 3.0.1)
|
||||||
image_size (3.0.1)
|
image_size (3.0.1)
|
||||||
in_threads (1.6.0)
|
in_threads (1.6.0)
|
||||||
|
io-wait (0.2.1)
|
||||||
ipaddr (1.2.4)
|
ipaddr (1.2.4)
|
||||||
jmespath (1.6.1)
|
jmespath (1.6.1)
|
||||||
jquery-rails (4.4.0)
|
jquery-rails (4.4.0)
|
||||||
|
@ -246,6 +250,24 @@ GEM
|
||||||
multi_xml (0.6.0)
|
multi_xml (0.6.0)
|
||||||
multipart-post (2.1.1)
|
multipart-post (2.1.1)
|
||||||
mustache (1.1.1)
|
mustache (1.1.1)
|
||||||
|
net-http (0.2.0)
|
||||||
|
net-protocol
|
||||||
|
uri
|
||||||
|
net-imap (0.2.3)
|
||||||
|
digest
|
||||||
|
net-protocol
|
||||||
|
strscan
|
||||||
|
net-pop (0.1.1)
|
||||||
|
digest
|
||||||
|
net-protocol
|
||||||
|
timeout
|
||||||
|
net-protocol (0.1.2)
|
||||||
|
io-wait
|
||||||
|
timeout
|
||||||
|
net-smtp (0.3.1)
|
||||||
|
digest
|
||||||
|
net-protocol
|
||||||
|
timeout
|
||||||
nio4r (2.5.8)
|
nio4r (2.5.8)
|
||||||
nokogiri (1.13.4)
|
nokogiri (1.13.4)
|
||||||
mini_portile2 (~> 2.8.0)
|
mini_portile2 (~> 2.8.0)
|
||||||
|
@ -332,12 +354,13 @@ GEM
|
||||||
rails_multisite (4.0.1)
|
rails_multisite (4.0.1)
|
||||||
activerecord (> 5.0, < 7.1)
|
activerecord (> 5.0, < 7.1)
|
||||||
railties (> 5.0, < 7.1)
|
railties (> 5.0, < 7.1)
|
||||||
railties (6.1.4.7)
|
railties (7.0.2.4)
|
||||||
actionpack (= 6.1.4.7)
|
actionpack (= 7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.13)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
|
zeitwerk (~> 2.5)
|
||||||
rainbow (3.1.1)
|
rainbow (3.1.1)
|
||||||
raindrops (0.20.0)
|
raindrops (0.20.0)
|
||||||
rake (13.0.6)
|
rake (13.0.6)
|
||||||
|
@ -452,9 +475,11 @@ GEM
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
sshkey (2.0.0)
|
sshkey (2.0.0)
|
||||||
stackprof (0.2.19)
|
stackprof (0.2.19)
|
||||||
|
strscan (3.0.1)
|
||||||
test-prof (1.0.8)
|
test-prof (1.0.8)
|
||||||
thor (1.2.1)
|
thor (1.2.1)
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
|
timeout (0.2.0)
|
||||||
tzinfo (2.0.4)
|
tzinfo (2.0.4)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
uglifier (4.2.0)
|
uglifier (4.2.0)
|
||||||
|
@ -467,6 +492,7 @@ GEM
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
uniform_notifier (1.16.0)
|
uniform_notifier (1.16.0)
|
||||||
|
uri (0.11.0)
|
||||||
uri_template (0.7.0)
|
uri_template (0.7.0)
|
||||||
webmock (3.14.0)
|
webmock (3.14.0)
|
||||||
addressable (>= 2.8.0)
|
addressable (>= 2.8.0)
|
||||||
|
@ -489,14 +515,14 @@ PLATFORMS
|
||||||
x86_64-linux
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
actionmailer (= 6.1.4.7)
|
actionmailer (= 7.0.2.4)
|
||||||
actionpack (= 6.1.4.7)
|
actionpack (= 7.0.2.4)
|
||||||
actionview (= 6.1.4.7)
|
actionview (= 7.0.2.4)
|
||||||
actionview_precompiler
|
actionview_precompiler
|
||||||
active_model_serializers (~> 0.8.3)
|
active_model_serializers (~> 0.8.3)
|
||||||
activemodel (= 6.1.4.7)
|
activemodel (= 7.0.2.4)
|
||||||
activerecord (= 6.1.4.7)
|
activerecord (= 7.0.2.4)
|
||||||
activesupport (= 6.1.4.7)
|
activesupport (= 7.0.2.4)
|
||||||
addressable
|
addressable
|
||||||
annotate
|
annotate
|
||||||
aws-sdk-s3
|
aws-sdk-s3
|
||||||
|
@ -556,6 +582,7 @@ DEPENDENCIES
|
||||||
mocha
|
mocha
|
||||||
multi_json
|
multi_json
|
||||||
mustache
|
mustache
|
||||||
|
net-http
|
||||||
nokogiri
|
nokogiri
|
||||||
oj
|
oj
|
||||||
omniauth
|
omniauth
|
||||||
|
@ -575,7 +602,7 @@ DEPENDENCIES
|
||||||
rack-protection
|
rack-protection
|
||||||
rails_failover
|
rails_failover
|
||||||
rails_multisite
|
rails_multisite
|
||||||
railties (= 6.1.4.7)
|
railties (= 7.0.2.4)
|
||||||
rake
|
rake
|
||||||
rb-fsevent
|
rb-fsevent
|
||||||
rbtrace
|
rbtrace
|
||||||
|
|
|
@ -68,7 +68,7 @@ class ApplicationController < ActionController::Base
|
||||||
def use_crawler_layout?
|
def use_crawler_layout?
|
||||||
@use_crawler_layout ||=
|
@use_crawler_layout ||=
|
||||||
request.user_agent &&
|
request.user_agent &&
|
||||||
(request.content_type.blank? || request.content_type.include?('html')) &&
|
(request.media_type.blank? || request.media_type.include?('html')) &&
|
||||||
!['json', 'rss'].include?(params[:format]) &&
|
!['json', 'rss'].include?(params[:format]) &&
|
||||||
(has_escaped_fragment? || params.key?("print") || show_browser_update? ||
|
(has_escaped_fragment? || params.key?("print") || show_browser_update? ||
|
||||||
CrawlerDetection.crawler?(request.user_agent, request.headers["HTTP_VIA"])
|
CrawlerDetection.crawler?(request.user_agent, request.headers["HTTP_VIA"])
|
||||||
|
@ -287,7 +287,7 @@ class ApplicationController < ActionController::Base
|
||||||
# cause category / topic was deleted
|
# cause category / topic was deleted
|
||||||
if permalink.present? && permalink.target_url
|
if permalink.present? && permalink.target_url
|
||||||
# permalink present, redirect to that URL
|
# permalink present, redirect to that URL
|
||||||
redirect_with_client_support permalink.target_url, status: :moved_permanently
|
redirect_with_client_support permalink.target_url, status: :moved_permanently, allow_other_host: true
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -834,7 +834,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
if UserApiKey.allowed_scopes.superset?(Set.new(["one_time_password"]))
|
if UserApiKey.allowed_scopes.superset?(Set.new(["one_time_password"]))
|
||||||
redirect_to("#{params[:auth_redirect]}?otp=true")
|
redirect_to("#{params[:auth_redirect]}?otp=true", allow_other_host: true)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class PostsController < ApplicationController
|
class PostsController < ApplicationController
|
||||||
|
# Bug with Rails 7+
|
||||||
|
# see https://github.com/rails/rails/issues/44867
|
||||||
|
self._flash_types -= [:notice]
|
||||||
|
|
||||||
requires_login except: [
|
requires_login except: [
|
||||||
:show,
|
:show,
|
||||||
|
|
|
@ -33,7 +33,7 @@ class SessionController < ApplicationController
|
||||||
if SiteSetting.verbose_discourse_connect_logging
|
if SiteSetting.verbose_discourse_connect_logging
|
||||||
Rails.logger.warn("Verbose SSO log: Started SSO process\n\n#{sso.diagnostics}")
|
Rails.logger.warn("Verbose SSO log: Started SSO process\n\n#{sso.diagnostics}")
|
||||||
end
|
end
|
||||||
redirect_to sso_url(sso)
|
redirect_to sso_url(sso), allow_other_host: true
|
||||||
else
|
else
|
||||||
render body: nil, status: 404
|
render body: nil, status: 404
|
||||||
end
|
end
|
||||||
|
@ -69,14 +69,14 @@ class SessionController < ApplicationController
|
||||||
# for the login modal
|
# for the login modal
|
||||||
cookies[:sso_destination_url] = data[:sso_redirect_url]
|
cookies[:sso_destination_url] = data[:sso_redirect_url]
|
||||||
else
|
else
|
||||||
redirect_to data[:sso_redirect_url]
|
redirect_to data[:sso_redirect_url], allow_other_host: true
|
||||||
end
|
end
|
||||||
elsif result.no_second_factors_enabled?
|
elsif result.no_second_factors_enabled?
|
||||||
if request.xhr?
|
if request.xhr?
|
||||||
# for the login modal
|
# for the login modal
|
||||||
cookies[:sso_destination_url] = result.data[:sso_redirect_url]
|
cookies[:sso_destination_url] = result.data[:sso_redirect_url]
|
||||||
else
|
else
|
||||||
redirect_to result.data[:sso_redirect_url]
|
redirect_to result.data[:sso_redirect_url], allow_other_host: true
|
||||||
end
|
end
|
||||||
elsif result.second_factor_auth_completed?
|
elsif result.second_factor_auth_completed?
|
||||||
redirect_url = result.data[:sso_redirect_url]
|
redirect_url = result.data[:sso_redirect_url]
|
||||||
|
@ -169,7 +169,7 @@ class SessionController < ApplicationController
|
||||||
# they are already pre-approved because they have been invited
|
# they are already pre-approved because they have been invited
|
||||||
if SiteSetting.must_approve_users? && !user.approved? && invite.blank?
|
if SiteSetting.must_approve_users? && !user.approved? && invite.blank?
|
||||||
if SiteSetting.discourse_connect_not_approved_url.present?
|
if SiteSetting.discourse_connect_not_approved_url.present?
|
||||||
redirect_to SiteSetting.discourse_connect_not_approved_url
|
redirect_to SiteSetting.discourse_connect_not_approved_url, allow_other_host: true
|
||||||
else
|
else
|
||||||
render_sso_error(text: I18n.t("discourse_connect.account_not_approved"), status: 403)
|
render_sso_error(text: I18n.t("discourse_connect.account_not_approved"), status: 403)
|
||||||
end
|
end
|
||||||
|
@ -220,7 +220,7 @@ class SessionController < ApplicationController
|
||||||
return_path = path("/")
|
return_path = path("/")
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to return_path
|
redirect_to return_path, allow_other_host: true
|
||||||
else
|
else
|
||||||
render_sso_error(text: I18n.t("discourse_connect.not_found"), status: 500)
|
render_sso_error(text: I18n.t("discourse_connect.not_found"), status: 500)
|
||||||
end
|
end
|
||||||
|
@ -583,7 +583,7 @@ class SessionController < ApplicationController
|
||||||
redirect_url: redirect_url
|
redirect_url: redirect_url
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
redirect_to redirect_url
|
redirect_to redirect_url, allow_other_host: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class StaticController < ApplicationController
|
||||||
if map.has_key?(@page)
|
if map.has_key?(@page)
|
||||||
site_setting_key = map[@page][:redirect]
|
site_setting_key = map[@page][:redirect]
|
||||||
url = SiteSetting.get(site_setting_key) if site_setting_key
|
url = SiteSetting.get(site_setting_key) if site_setting_key
|
||||||
return redirect_to(url) if url.present?
|
return redirect_to(url, allow_other_host: true) if url.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
# The /guidelines route ALWAYS shows our FAQ, ignoring the faq_url site setting.
|
# The /guidelines route ALWAYS shows our FAQ, ignoring the faq_url site setting.
|
||||||
|
|
|
@ -15,7 +15,7 @@ class SvgSpriteController < ApplicationController
|
||||||
theme_id = params[:theme_id].to_i if params[:theme_id].present?
|
theme_id = params[:theme_id].to_i if params[:theme_id].present?
|
||||||
|
|
||||||
if SvgSprite.version(theme_id) != params[:version]
|
if SvgSprite.version(theme_id) != params[:version]
|
||||||
return redirect_to UrlHelper.absolute((SvgSprite.path(theme_id)))
|
return redirect_to UrlHelper.absolute((SvgSprite.path(theme_id))), allow_other_host: true
|
||||||
end
|
end
|
||||||
|
|
||||||
svg_sprite = "window.__svg_sprite = #{SvgSprite.bundle(theme_id).inspect};"
|
svg_sprite = "window.__svg_sprite = #{SvgSprite.bundle(theme_id).inspect};"
|
||||||
|
|
|
@ -118,7 +118,7 @@ class UploadsController < ApplicationController
|
||||||
if Discourse.store.internal?
|
if Discourse.store.internal?
|
||||||
send_file_local_upload(upload)
|
send_file_local_upload(upload)
|
||||||
else
|
else
|
||||||
redirect_to Discourse.store.url_for(upload, force_download: force_download?)
|
redirect_to Discourse.store.url_for(upload, force_download: force_download?), allow_other_host: true
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
render_404
|
render_404
|
||||||
|
@ -149,7 +149,7 @@ class UploadsController < ApplicationController
|
||||||
# private, so we don't want to go to the CDN url just yet otherwise we
|
# private, so we don't want to go to the CDN url just yet otherwise we
|
||||||
# will get a 403. if the upload is not secure we assume the ACL is public
|
# will get a 403. if the upload is not secure we assume the ACL is public
|
||||||
signed_secure_url = Discourse.store.signed_url_for_path(path_with_ext)
|
signed_secure_url = Discourse.store.signed_url_for_path(path_with_ext)
|
||||||
redirect_to upload.secure? ? signed_secure_url : Discourse.store.cdn_url(upload.url)
|
redirect_to upload.secure? ? signed_secure_url : Discourse.store.cdn_url(upload.url), allow_other_host: true
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_secure_upload_request(upload, path_with_ext = nil)
|
def handle_secure_upload_request(upload, path_with_ext = nil)
|
||||||
|
@ -166,14 +166,14 @@ class UploadsController < ApplicationController
|
||||||
# url_for figures out the full URL, handling multisite DBs,
|
# url_for figures out the full URL, handling multisite DBs,
|
||||||
# and will return a presigned URL for the upload
|
# and will return a presigned URL for the upload
|
||||||
if path_with_ext.blank?
|
if path_with_ext.blank?
|
||||||
return redirect_to Discourse.store.url_for(upload, force_download: force_download?)
|
return redirect_to Discourse.store.url_for(upload, force_download: force_download?), allow_other_host: true
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to Discourse.store.signed_url_for_path(
|
redirect_to Discourse.store.signed_url_for_path(
|
||||||
path_with_ext,
|
path_with_ext,
|
||||||
expires_in: S3Helper::DOWNLOAD_URL_EXPIRES_AFTER_SECONDS,
|
expires_in: S3Helper::DOWNLOAD_URL_EXPIRES_AFTER_SECONDS,
|
||||||
force_download: force_download?
|
force_download: force_download?
|
||||||
)
|
), allow_other_host: true
|
||||||
end
|
end
|
||||||
|
|
||||||
def metadata
|
def metadata
|
||||||
|
|
|
@ -97,7 +97,7 @@ class UserApiKeysController < ApplicationController
|
||||||
query_attributes << "oneTimePassword=#{CGI.escape(otp_payload)}" if scopes.include?("one_time_password")
|
query_attributes << "oneTimePassword=#{CGI.escape(otp_payload)}" if scopes.include?("one_time_password")
|
||||||
uri.query = query_attributes.compact.join('&')
|
uri.query = query_attributes.compact.join('&')
|
||||||
|
|
||||||
redirect_to(uri.to_s)
|
redirect_to(uri.to_s, allow_other_host: true)
|
||||||
else
|
else
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :show }
|
format.html { render :show }
|
||||||
|
@ -138,7 +138,7 @@ class UserApiKeysController < ApplicationController
|
||||||
otp_payload = one_time_password(public_key, current_user.username)
|
otp_payload = one_time_password(public_key, current_user.username)
|
||||||
|
|
||||||
redirect_path = "#{params[:auth_redirect]}?oneTimePassword=#{CGI.escape(otp_payload)}"
|
redirect_path = "#{params[:auth_redirect]}?oneTimePassword=#{CGI.escape(otp_payload)}"
|
||||||
redirect_to(redirect_path)
|
redirect_to(redirect_path, allow_other_host: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revoke
|
def revoke
|
||||||
|
|
|
@ -112,7 +112,7 @@ class UserAvatarsController < ApplicationController
|
||||||
if !Discourse.avatar_sizes.include?(size) && Discourse.store.external?
|
if !Discourse.avatar_sizes.include?(size) && Discourse.store.external?
|
||||||
closest = Discourse.avatar_sizes.to_a.min { |a, b| (size - a).abs <=> (size - b).abs }
|
closest = Discourse.avatar_sizes.to_a.min { |a, b| (size - a).abs <=> (size - b).abs }
|
||||||
avatar_url = UserAvatar.local_avatar_url(hostname, user.encoded_username(lower: true), upload_id, closest)
|
avatar_url = UserAvatar.local_avatar_url(hostname, user.encoded_username(lower: true), upload_id, closest)
|
||||||
return redirect_to cdn_path(avatar_url)
|
return redirect_to cdn_path(avatar_url), allow_other_host: true
|
||||||
end
|
end
|
||||||
|
|
||||||
upload = Upload.find_by(id: upload_id) if user&.user_avatar&.contains_upload?(upload_id)
|
upload = Upload.find_by(id: upload_id) if user&.user_avatar&.contains_upload?(upload_id)
|
||||||
|
@ -120,7 +120,7 @@ class UserAvatarsController < ApplicationController
|
||||||
|
|
||||||
if user.uploaded_avatar && !upload
|
if user.uploaded_avatar && !upload
|
||||||
avatar_url = UserAvatar.local_avatar_url(hostname, user.encoded_username(lower: true), user.uploaded_avatar_id, size)
|
avatar_url = UserAvatar.local_avatar_url(hostname, user.encoded_username(lower: true), user.uploaded_avatar_id, size)
|
||||||
return redirect_to cdn_path(avatar_url)
|
return redirect_to cdn_path(avatar_url), allow_other_host: true
|
||||||
elsif upload && optimized = get_optimized_image(upload, size)
|
elsif upload && optimized = get_optimized_image(upload, size)
|
||||||
if optimized.local?
|
if optimized.local?
|
||||||
optimized_path = Discourse.store.path_for(optimized)
|
optimized_path = Discourse.store.path_for(optimized)
|
||||||
|
|
|
@ -1024,7 +1024,7 @@ class UsersController < ApplicationController
|
||||||
if SiteSetting.enable_discourse_connect_provider && payload = cookies.delete(:sso_payload)
|
if SiteSetting.enable_discourse_connect_provider && payload = cookies.delete(:sso_payload)
|
||||||
return redirect_to(session_sso_provider_url + "?" + payload)
|
return redirect_to(session_sso_provider_url + "?" + payload)
|
||||||
elsif destination_url = cookies.delete(:destination_url)
|
elsif destination_url = cookies.delete(:destination_url)
|
||||||
return redirect_to(destination_url)
|
return redirect_to(destination_url, allow_other_host: true)
|
||||||
else
|
else
|
||||||
return redirect_to(path('/'))
|
return redirect_to(path('/'))
|
||||||
end
|
end
|
||||||
|
@ -1086,7 +1086,7 @@ class UsersController < ApplicationController
|
||||||
if Wizard.user_requires_completion?(@user)
|
if Wizard.user_requires_completion?(@user)
|
||||||
return redirect_to(wizard_path)
|
return redirect_to(wizard_path)
|
||||||
elsif destination_url.present?
|
elsif destination_url.present?
|
||||||
return redirect_to(destination_url)
|
return redirect_to(destination_url, allow_other_host: true)
|
||||||
elsif SiteSetting.enable_discourse_connect_provider && payload = cookies.delete(:sso_payload)
|
elsif SiteSetting.enable_discourse_connect_provider && payload = cookies.delete(:sso_payload)
|
||||||
return redirect_to(session_sso_provider_url + "?" + payload)
|
return redirect_to(session_sso_provider_url + "?" + payload)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'email/sender'
|
|
||||||
|
|
||||||
module Jobs
|
module Jobs
|
||||||
class GroupSmtpEmail < ::Jobs::Base
|
class GroupSmtpEmail < ::Jobs::Base
|
||||||
include Skippable
|
include Skippable
|
||||||
|
|
|
@ -57,8 +57,8 @@ module Jobs
|
||||||
end
|
end
|
||||||
|
|
||||||
def keys_list
|
def keys_list
|
||||||
messages = old_site_settings_keys.map { |key| "#{key.name} - #{key.updated_at.to_date.to_s(:db)}" }
|
messages = old_site_settings_keys.map { |key| "#{key.name} - #{key.updated_at.to_date.to_fs(:db)}" }
|
||||||
old_api_keys.each_with_object(messages) { |key, array| array << "#{[key.description, key.user&.username, key.created_at.to_date.to_s(:db)].compact.join(" - ")}" }
|
old_api_keys.each_with_object(messages) { |key, array| array << "#{[key.description, key.user&.username, key.created_at.to_date.to_fs(:db)].compact.join(" - ")}" }
|
||||||
messages.join("\n")
|
messages.join("\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'email/message_builder'
|
|
||||||
|
|
||||||
class GroupSmtpMailer < ActionMailer::Base
|
class GroupSmtpMailer < ActionMailer::Base
|
||||||
include Email::BuildEmailHelper
|
include Email::BuildEmailHelper
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'global_path'
|
|
||||||
require 'csv'
|
require 'csv'
|
||||||
require 'json_schemer'
|
require 'json_schemer'
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,9 @@ class TopicList
|
||||||
ft.topic_list = self
|
ft.topic_list = self
|
||||||
end
|
end
|
||||||
|
|
||||||
ActiveRecord::Associations::Preloader.new.preload(@topics, [:image_upload, topic_thumbnails: :optimized_image])
|
ActiveRecord::Associations::Preloader
|
||||||
|
.new(records: @topics, associations: [:image_upload, topic_thumbnails: :optimized_image])
|
||||||
|
.call
|
||||||
|
|
||||||
if preloaded_custom_fields.present?
|
if preloaded_custom_fields.present?
|
||||||
Topic.preload_custom_fields(@topics, preloaded_custom_fields)
|
Topic.preload_custom_fields(@topics, preloaded_custom_fields)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "i18n/i18n_interpolation_keys_finder"
|
|
||||||
|
|
||||||
class TranslationOverride < ActiveRecord::Base
|
class TranslationOverride < ActiveRecord::Base
|
||||||
# Allowlist i18n interpolation keys that can be included when customizing translations
|
# Allowlist i18n interpolation keys that can be included when customizing translations
|
||||||
ALLOWED_CUSTOM_INTERPOLATION_KEYS = {
|
ALLOWED_CUSTOM_INTERPOLATION_KEYS = {
|
||||||
|
|
|
@ -73,8 +73,8 @@ class Bookmarkable
|
||||||
# @param [Array] bookmarks The array of bookmarks after initial listing and filtering, note this is
|
# @param [Array] bookmarks The array of bookmarks after initial listing and filtering, note this is
|
||||||
# array _not_ an ActiveRecord::Relation.
|
# array _not_ an ActiveRecord::Relation.
|
||||||
def perform_preload(bookmarks)
|
def perform_preload(bookmarks)
|
||||||
ActiveRecord::Associations::Preloader.new.preload(
|
ActiveRecord::Associations::Preloader
|
||||||
Bookmark.select_type(bookmarks, model.to_s), { bookmarkable: preload_associations }
|
.new(records: Bookmark.select_type(bookmarks, model.to_s), associations: [bookmarkable: preload_associations])
|
||||||
)
|
.call
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,7 +21,7 @@ require 'action_mailer/railtie'
|
||||||
require 'sprockets/railtie'
|
require 'sprockets/railtie'
|
||||||
|
|
||||||
# Plugin related stuff
|
# Plugin related stuff
|
||||||
require_relative '../lib/plugin_initialization_guard'
|
require_relative '../lib/plugin'
|
||||||
require_relative '../lib/discourse_event'
|
require_relative '../lib/discourse_event'
|
||||||
require_relative '../lib/discourse_plugin_registry'
|
require_relative '../lib/discourse_plugin_registry'
|
||||||
|
|
||||||
|
@ -31,7 +31,13 @@ require_relative '../lib/plugin_gem'
|
||||||
require_relative '../app/models/global_setting'
|
require_relative '../app/models/global_setting'
|
||||||
GlobalSetting.configure!
|
GlobalSetting.configure!
|
||||||
if GlobalSetting.load_plugins?
|
if GlobalSetting.load_plugins?
|
||||||
require_relative '../lib/custom_setting_providers'
|
# Support for plugins to register custom setting providers. They can do this
|
||||||
|
# by having a file, `register_provider.rb` in their root that will be run
|
||||||
|
# at this point.
|
||||||
|
|
||||||
|
Dir.glob(File.join(File.dirname(__FILE__), '../plugins', '*', "register_provider.rb")) do |p|
|
||||||
|
require p
|
||||||
|
end
|
||||||
end
|
end
|
||||||
GlobalSetting.load_defaults
|
GlobalSetting.load_defaults
|
||||||
if GlobalSetting.try(:cdn_url).present? && GlobalSetting.cdn_url !~ /^https?:\/\//
|
if GlobalSetting.try(:cdn_url).present? && GlobalSetting.cdn_url !~ /^https?:\/\//
|
||||||
|
@ -85,14 +91,11 @@ module Discourse
|
||||||
# Application configuration should go into files in config/initializers
|
# Application configuration should go into files in config/initializers
|
||||||
# -- all .rb files in that directory are automatically loaded.
|
# -- all .rb files in that directory are automatically loaded.
|
||||||
|
|
||||||
# this pattern is somewhat odd but the reloader gets very
|
require 'discourse'
|
||||||
# confused here if we load the deps without `lib` it thinks
|
require 'js_locale_helper'
|
||||||
# discourse.rb is under the discourse folder incorrectly
|
|
||||||
require_dependency 'lib/discourse'
|
|
||||||
require_dependency 'lib/js_locale_helper'
|
|
||||||
|
|
||||||
# tiny file needed by site settings
|
# tiny file needed by site settings
|
||||||
require_dependency 'lib/highlight_js/highlight_js'
|
require 'highlight_js'
|
||||||
|
|
||||||
# we skip it cause we configure it in the initializer
|
# we skip it cause we configure it in the initializer
|
||||||
# the railtie for message_bus would insert it in the
|
# the railtie for message_bus would insert it in the
|
||||||
|
@ -109,120 +112,19 @@ module Discourse
|
||||||
# issue is image_optim crashes on missing dependencies
|
# issue is image_optim crashes on missing dependencies
|
||||||
config.assets.image_optim = false
|
config.assets.image_optim = false
|
||||||
|
|
||||||
config.autoloader = :zeitwerk
|
|
||||||
|
|
||||||
# Custom directories with classes and modules you want to be autoloadable.
|
# Custom directories with classes and modules you want to be autoloadable.
|
||||||
config.autoload_paths += Dir["#{config.root}/lib"]
|
config.autoload_paths << "#{root}/lib"
|
||||||
config.autoload_paths += Dir["#{config.root}/lib/common_passwords"]
|
config.autoload_paths << "#{root}/lib/guardian"
|
||||||
config.autoload_paths += Dir["#{config.root}/lib/highlight_js"]
|
config.autoload_paths << "#{root}/lib/i18n"
|
||||||
config.autoload_paths += Dir["#{config.root}/lib/i18n"]
|
config.autoload_paths << "#{root}/lib/validators"
|
||||||
config.autoload_paths += Dir["#{config.root}/lib/validators/"]
|
|
||||||
|
|
||||||
Rails.autoloaders.main.ignore(Dir["#{config.root}/app/models/reports"])
|
|
||||||
Rails.autoloaders.main.ignore(Dir["#{config.root}/lib/freedom_patches"])
|
|
||||||
|
|
||||||
def watchable_args
|
|
||||||
files, dirs = super
|
|
||||||
|
|
||||||
# Skip the assets directory. It doesn't contain any .rb files, so watching it
|
|
||||||
# is just slowing things down and raising warnings about node_modules symlinks
|
|
||||||
app_file_extensions = dirs.delete("#{config.root}/app")
|
|
||||||
Dir["#{config.root}/app/*"].reject { |path| path.end_with? "/assets" }.each do |path|
|
|
||||||
dirs[path] = app_file_extensions
|
|
||||||
end
|
|
||||||
|
|
||||||
[files, dirs]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Only load the plugins named here, in the order given (default is alphabetical).
|
# Only load the plugins named here, in the order given (default is alphabetical).
|
||||||
# :all can be used as a placeholder for all plugins not explicitly named.
|
# :all can be used as a placeholder for all plugins not explicitly named.
|
||||||
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
||||||
|
|
||||||
config.assets.paths += %W(#{config.root}/config/locales #{config.root}/public/javascripts)
|
|
||||||
|
|
||||||
# Allows us to skip minification on some files
|
# Allows us to skip minification on some files
|
||||||
config.assets.skip_minification = []
|
config.assets.skip_minification = []
|
||||||
|
|
||||||
# explicitly precompile any images in plugins ( /assets/images ) path
|
|
||||||
config.assets.precompile += [lambda do |filename, path|
|
|
||||||
path =~ /assets\/images/ && !%w(.js .css).include?(File.extname(filename))
|
|
||||||
end]
|
|
||||||
|
|
||||||
config.assets.precompile += %w{
|
|
||||||
vendor.js
|
|
||||||
admin.js
|
|
||||||
browser-detect.js
|
|
||||||
browser-update.js
|
|
||||||
break_string.js
|
|
||||||
ember_jquery.js
|
|
||||||
pretty-text-bundle.js
|
|
||||||
wizard-application.js
|
|
||||||
wizard-vendor.js
|
|
||||||
markdown-it-bundle.js
|
|
||||||
service-worker.js
|
|
||||||
google-tag-manager.js
|
|
||||||
google-universal-analytics-v3.js
|
|
||||||
google-universal-analytics-v4.js
|
|
||||||
start-discourse.js
|
|
||||||
print-page.js
|
|
||||||
omniauth-complete.js
|
|
||||||
activate-account.js
|
|
||||||
auto-redirect.js
|
|
||||||
wizard-start.js
|
|
||||||
locales/i18n.js
|
|
||||||
discourse/app/lib/webauthn.js
|
|
||||||
confirm-new-email/confirm-new-email.js
|
|
||||||
confirm-new-email/bootstrap.js
|
|
||||||
onpopstate-handler.js
|
|
||||||
embed-application.js
|
|
||||||
discourse/tests/active-plugins.js
|
|
||||||
admin-plugins.js
|
|
||||||
discourse/tests/test_starter.js
|
|
||||||
}
|
|
||||||
|
|
||||||
if EmberCli.enabled?
|
|
||||||
config.assets.precompile += %w{
|
|
||||||
discourse.js
|
|
||||||
test-support.js
|
|
||||||
test-helpers.js
|
|
||||||
scripts/discourse-test-listen-boot
|
|
||||||
scripts/discourse-boot
|
|
||||||
}
|
|
||||||
else
|
|
||||||
config.assets.precompile += %w{
|
|
||||||
application.js
|
|
||||||
discourse/tests/test-support-rails.js
|
|
||||||
discourse/tests/test-helpers-rails.js
|
|
||||||
vendor-theme-tests.js
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Precompile all available locales
|
|
||||||
unless GlobalSetting.try(:omit_base_locales)
|
|
||||||
Dir.glob("#{config.root}/app/assets/javascripts/locales/*.js.erb").each do |file|
|
|
||||||
config.assets.precompile << "locales/#{file.match(/([a-z_A-Z]+\.js)\.erb$/)[1]}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# out of the box sprockets 3 grabs loose files that are hanging in assets,
|
|
||||||
# the exclusion list does not include hbs so you double compile all this stuff
|
|
||||||
initializer :fix_sprockets_loose_file_searcher, after: :set_default_precompile do |app|
|
|
||||||
app.config.assets.precompile.delete(Sprockets::Railtie::LOOSE_APP_ASSETS)
|
|
||||||
|
|
||||||
# We don't want application from node_modules, only from the root
|
|
||||||
app.config.assets.precompile.delete(/(?:\/|\\|\A)application\.(css|js)$/)
|
|
||||||
app.config.assets.precompile += ['application.js']
|
|
||||||
|
|
||||||
start_path = ::Rails.root.join("app/assets").to_s
|
|
||||||
exclude = ['.es6', '.hbs', '.hbr', '.js', '.css', '.lock', '.json', '.log', '.html', '']
|
|
||||||
app.config.assets.precompile << lambda do |logical_path, filename|
|
|
||||||
filename.start_with?(start_path) &&
|
|
||||||
!filename.include?("/node_modules/") &&
|
|
||||||
!filename.include?("/dist/") &&
|
|
||||||
!exclude.include?(File.extname(logical_path))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||||
config.time_zone = 'UTC'
|
config.time_zone = 'UTC'
|
||||||
|
@ -234,24 +136,6 @@ module Discourse
|
||||||
# Configure the default encoding used in templates for Ruby 1.9.
|
# Configure the default encoding used in templates for Ruby 1.9.
|
||||||
config.encoding = 'utf-8'
|
config.encoding = 'utf-8'
|
||||||
|
|
||||||
# Configure sensitive parameters which will be filtered from the log file.
|
|
||||||
config.filter_parameters += [
|
|
||||||
:password,
|
|
||||||
:pop3_polling_password,
|
|
||||||
:api_key,
|
|
||||||
:s3_secret_access_key,
|
|
||||||
:twitter_consumer_secret,
|
|
||||||
:facebook_app_secret,
|
|
||||||
:github_client_secret,
|
|
||||||
:second_factor_token,
|
|
||||||
]
|
|
||||||
|
|
||||||
# Enable the asset pipeline
|
|
||||||
config.assets.enabled = true
|
|
||||||
|
|
||||||
# Version of your assets, change this if you want to expire all your assets
|
|
||||||
config.assets.version = '1.2.5'
|
|
||||||
|
|
||||||
# see: http://stackoverflow.com/questions/11894180/how-does-one-correctly-add-custom-sql-dml-in-migrations/11894420#11894420
|
# see: http://stackoverflow.com/questions/11894180/how-does-one-correctly-add-custom-sql-dml-in-migrations/11894420#11894420
|
||||||
config.active_record.schema_format = :sql
|
config.active_record.schema_format = :sql
|
||||||
|
|
||||||
|
@ -336,45 +220,21 @@ module Discourse
|
||||||
if Rails.env.test? && GlobalSetting.load_plugins?
|
if Rails.env.test? && GlobalSetting.load_plugins?
|
||||||
Discourse.activate_plugins!
|
Discourse.activate_plugins!
|
||||||
elsif GlobalSetting.load_plugins?
|
elsif GlobalSetting.load_plugins?
|
||||||
plugin_initialization_guard do
|
Plugin.initialization_guard do
|
||||||
Discourse.activate_plugins!
|
Discourse.activate_plugins!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Discourse.find_plugin_js_assets(include_disabled: true).each do |file|
|
|
||||||
config.assets.precompile << "#{file}.js"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Use discourse-fonts gem to symlink fonts and generate .scss file
|
# Use discourse-fonts gem to symlink fonts and generate .scss file
|
||||||
fonts_path = File.join(config.root, 'public/fonts')
|
fonts_path = File.join(config.root, 'public/fonts')
|
||||||
Discourse::Utils.atomic_ln_s(DiscourseFonts.path_for_fonts, fonts_path)
|
Discourse::Utils.atomic_ln_s(DiscourseFonts.path_for_fonts, fonts_path)
|
||||||
|
|
||||||
require_dependency 'stylesheet/manager'
|
require 'stylesheet/manager'
|
||||||
require_dependency 'svg_sprite/svg_sprite'
|
require 'svg_sprite'
|
||||||
|
|
||||||
config.after_initialize do
|
config.after_initialize do
|
||||||
# require common dependencies that are often required by plugins
|
|
||||||
# in the past observers would load them as side-effects
|
|
||||||
# correct behavior is for plugins to require stuff they need,
|
|
||||||
# however it would be a risky and breaking change not to require here
|
|
||||||
require_dependency 'category'
|
|
||||||
require_dependency 'post'
|
|
||||||
require_dependency 'topic'
|
|
||||||
require_dependency 'user'
|
|
||||||
require_dependency 'post_action'
|
|
||||||
require_dependency 'post_revision'
|
|
||||||
require_dependency 'notification'
|
|
||||||
require_dependency 'topic_user'
|
|
||||||
require_dependency 'topic_view'
|
|
||||||
require_dependency 'topic_list'
|
|
||||||
require_dependency 'group'
|
|
||||||
require_dependency 'user_field'
|
|
||||||
require_dependency 'post_action_type'
|
|
||||||
# Ensure that Discourse event triggers for web hooks are loaded
|
|
||||||
require_dependency 'web_hook'
|
|
||||||
|
|
||||||
# Load plugins
|
# Load plugins
|
||||||
plugin_initialization_guard do
|
Plugin.initialization_guard do
|
||||||
Discourse.plugins.each(&:notify_after_initialize)
|
Discourse.plugins.each(&:notify_after_initialize)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Load the rails application
|
# Load the Rails application.
|
||||||
require File.expand_path('../application', __FILE__)
|
require_relative "application"
|
||||||
|
|
||||||
# Initialize the rails application
|
# Initialize the Rails application.
|
||||||
Discourse::Application.initialize!
|
Rails.application.initialize!
|
||||||
|
|
||||||
# When in "dev" mode, ensure we won't be sending any emails
|
# When in "dev" mode, ensure we won't be sending any emails
|
||||||
if Rails.env.development? && ActionMailer::Base.smtp_settings != { address: "localhost", port: 1025 }
|
if Rails.env.development? && ActionMailer::Base.smtp_settings.slice(:address, :port) != { address: "localhost", port: 1025 }
|
||||||
fail "In development mode, you should be using mailhog otherwise you might end up sending thousands of digest emails"
|
fail "In development mode, you should be using mailhog otherwise you might end up sending thousands of digest emails"
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,5 +36,15 @@ Rails.autoloaders.each do |autoloader|
|
||||||
'onceoff' => 'Jobs',
|
'onceoff' => 'Jobs',
|
||||||
'regular' => 'Jobs',
|
'regular' => 'Jobs',
|
||||||
'scheduled' => 'Jobs',
|
'scheduled' => 'Jobs',
|
||||||
|
'google_oauth2_authenticator' => 'GoogleOAuth2Authenticator',
|
||||||
|
'omniauth_strategies' => 'OmniAuthStrategies',
|
||||||
|
'csrf_token_verifier' => 'CSRFTokenVerifier',
|
||||||
|
'html' => 'HTML',
|
||||||
|
'json' => 'JSON'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
Rails.autoloaders.main.ignore("lib/tasks",
|
||||||
|
"lib/generators",
|
||||||
|
"lib/freedom_patches",
|
||||||
|
"lib/i18n/backend",
|
||||||
|
"lib/unicorn_logstash_patch.rb")
|
||||||
|
|
|
@ -30,14 +30,14 @@ if defined?(RailsFailover::ActiveRecord)
|
||||||
return unless Rails.configuration.active_record_rails_failover
|
return unless Rails.configuration.active_record_rails_failover
|
||||||
|
|
||||||
if Rails.configuration.multisite
|
if Rails.configuration.multisite
|
||||||
if ActiveRecord::Base.current_role == ActiveRecord::Base.reading_role
|
if ActiveRecord::Base.current_role == ActiveRecord.reading_role
|
||||||
RailsMultisite::ConnectionManagement.default_connection_handler =
|
RailsMultisite::ConnectionManagement.default_connection_handler =
|
||||||
ActiveRecord::Base.connection_handlers[ActiveRecord::Base.reading_role]
|
ActiveRecord::Base.connection_handlers[ActiveRecord.reading_role]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RailsFailover::ActiveRecord.on_failover do |role|
|
RailsFailover::ActiveRecord.on_failover do |role|
|
||||||
if role == ActiveRecord::Base.writing_role # Multisite master
|
if role == ActiveRecord.writing_role # Multisite master
|
||||||
RailsMultisite::ConnectionManagement.each_connection do
|
RailsMultisite::ConnectionManagement.each_connection do
|
||||||
Discourse.enable_readonly_mode(Discourse::PG_READONLY_MODE_KEY)
|
Discourse.enable_readonly_mode(Discourse::PG_READONLY_MODE_KEY)
|
||||||
end
|
end
|
||||||
|
@ -47,16 +47,16 @@ if defined?(RailsFailover::ActiveRecord)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Test connection to the master, and trigger master failover if needed
|
# Test connection to the master, and trigger master failover if needed
|
||||||
ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do
|
ActiveRecord::Base.connected_to(role: ActiveRecord.writing_role) do
|
||||||
ActiveRecord::Base.connection.active?
|
ActiveRecord::Base.connection.active?
|
||||||
rescue PG::ConnectionBad, PG::UnableToSend, PG::ServerError
|
rescue PG::ConnectionBad, PG::UnableToSend, PG::ServerError
|
||||||
RailsFailover::ActiveRecord.verify_primary(ActiveRecord::Base.writing_role)
|
RailsFailover::ActiveRecord.verify_primary(ActiveRecord.writing_role)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RailsFailover::ActiveRecord.on_fallback do |role|
|
RailsFailover::ActiveRecord.on_fallback do |role|
|
||||||
if role == ActiveRecord::Base.writing_role # Multisite master
|
if role == ActiveRecord.writing_role # Multisite master
|
||||||
RailsMultisite::ConnectionManagement.each_connection do
|
RailsMultisite::ConnectionManagement.each_connection do
|
||||||
Discourse.disable_readonly_mode(Discourse::PG_READONLY_MODE_KEY)
|
Discourse.disable_readonly_mode(Discourse::PG_READONLY_MODE_KEY)
|
||||||
end
|
end
|
||||||
|
@ -68,7 +68,7 @@ if defined?(RailsFailover::ActiveRecord)
|
||||||
|
|
||||||
if Rails.configuration.multisite
|
if Rails.configuration.multisite
|
||||||
RailsMultisite::ConnectionManagement.default_connection_handler =
|
RailsMultisite::ConnectionManagement.default_connection_handler =
|
||||||
ActiveRecord::Base.connection_handlers[ActiveRecord::Base.writing_role]
|
ActiveRecord::Base.connection_handlers[ActiveRecord.writing_role]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,15 @@
|
||||||
Discourse.git_version
|
Discourse.git_version
|
||||||
|
|
||||||
if GlobalSetting.skip_redis?
|
if GlobalSetting.skip_redis?
|
||||||
# Requiring this file explicitly prevents it from being autoloaded and so the
|
|
||||||
# provider attribute is not cleared
|
|
||||||
require File.expand_path('../../../app/models/site_setting', __FILE__)
|
|
||||||
|
|
||||||
require 'site_settings/local_process_provider'
|
require 'site_settings/local_process_provider'
|
||||||
Rails.cache = Discourse.cache
|
Rails.cache = Discourse.cache
|
||||||
|
Rails.application.config.to_prepare do
|
||||||
SiteSetting.provider = SiteSettings::LocalProcessProvider.new
|
SiteSetting.provider = SiteSettings::LocalProcessProvider.new
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
reload_settings = lambda {
|
Rails.application.config.to_prepare do
|
||||||
RailsMultisite::ConnectionManagement.safe_each_connection do
|
RailsMultisite::ConnectionManagement.safe_each_connection do
|
||||||
begin
|
begin
|
||||||
SiteSetting.refresh!
|
SiteSetting.refresh!
|
||||||
|
@ -28,12 +26,4 @@ reload_settings = lambda {
|
||||||
# This will happen when migrating a new database
|
# This will happen when migrating a new database
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
|
||||||
|
|
||||||
reload_settings.call
|
|
||||||
|
|
||||||
if !Rails.configuration.cache_classes
|
|
||||||
ActiveSupport::Reloader.to_prepare do
|
|
||||||
reload_settings.call
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
return if GlobalSetting.skip_db?
|
return if GlobalSetting.skip_db?
|
||||||
|
|
||||||
|
Rails.application.config.to_prepare do
|
||||||
# Some sanity checking so we don't count on an unindexed column on boot
|
# Some sanity checking so we don't count on an unindexed column on boot
|
||||||
begin
|
begin
|
||||||
if ActiveRecord::Base.connection.table_exists?(:users) &&
|
if ActiveRecord::Base.connection.table_exists?(:users) &&
|
||||||
|
@ -29,3 +30,4 @@ begin
|
||||||
rescue ActiveRecord::NoDatabaseError
|
rescue ActiveRecord::NoDatabaseError
|
||||||
# Database might not have been created
|
# Database might not have been created
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
Rails.application.config.to_prepare do
|
||||||
if Rails.env.development? && SiteSetting.port.to_i > 0
|
if Rails.env.development? && SiteSetting.port.to_i > 0
|
||||||
Onebox.options = {
|
Onebox.options = {
|
||||||
twitter_client: TwitterApi,
|
twitter_client: TwitterApi,
|
||||||
|
@ -14,3 +15,4 @@ else
|
||||||
user_agent: "Discourse Forum Onebox v#{Discourse::VERSION::STRING}"
|
user_agent: "Discourse Forum Onebox v#{Discourse::VERSION::STRING}"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
return if GlobalSetting.skip_db?
|
return if GlobalSetting.skip_db?
|
||||||
|
|
||||||
require_dependency 'webpush'
|
Rails.application.config.to_prepare do
|
||||||
|
require 'webpush'
|
||||||
|
|
||||||
def generate_vapid_key?
|
def generate_vapid_key?
|
||||||
SiteSetting.vapid_public_key.blank? ||
|
SiteSetting.vapid_public_key.blank? ||
|
||||||
|
@ -29,3 +30,4 @@ end
|
||||||
DiscourseEvent.on(:user_logged_out) do |user|
|
DiscourseEvent.on(:user_logged_out) do |user|
|
||||||
PushNotificationPusher.clear_subscriptions(user)
|
PushNotificationPusher.clear_subscriptions(user)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Be sure to restart your server when you modify this file.
|
# Be sure to restart your server when you modify this file.
|
||||||
#
|
|
||||||
require_dependency 'discourse_cookie_store'
|
|
||||||
|
|
||||||
if Rails.env == "development" && SiteSetting.force_https
|
Rails.application.config.session_store(
|
||||||
|
:discourse_cookie_store,
|
||||||
|
key: '_forum_session',
|
||||||
|
path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root
|
||||||
|
)
|
||||||
|
|
||||||
|
Rails.application.config.to_prepare do
|
||||||
|
if Rails.env.development? && SiteSetting.force_https
|
||||||
STDERR.puts
|
STDERR.puts
|
||||||
STDERR.puts "WARNING: force_https is enabled in dev"
|
STDERR.puts "WARNING: force_https is enabled in dev"
|
||||||
STDERR.puts "It is very unlikely you are running HTTPS in dev."
|
STDERR.puts "It is very unlikely you are running HTTPS in dev."
|
||||||
|
@ -13,9 +18,4 @@ if Rails.env == "development" && SiteSetting.force_https
|
||||||
STDERR.puts "SiteSetting.force_https = false"
|
STDERR.puts "SiteSetting.force_https = false"
|
||||||
STDERR.puts
|
STDERR.puts
|
||||||
end
|
end
|
||||||
|
end
|
||||||
Discourse::Application.config.session_store(
|
|
||||||
:discourse_cookie_store,
|
|
||||||
key: '_forum_session',
|
|
||||||
path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
Rails.application.config.to_prepare do
|
||||||
if (Rails.env.production? && SiteSetting.logging_provider == 'lograge') || (ENV["ENABLE_LOGRAGE"] == "1")
|
if (Rails.env.production? && SiteSetting.logging_provider == 'lograge') || (ENV["ENABLE_LOGRAGE"] == "1")
|
||||||
require 'lograge'
|
require 'lograge'
|
||||||
|
|
||||||
|
@ -115,3 +116,4 @@ if (Rails.env.production? && SiteSetting.logging_provider == 'lograge') || (ENV[
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
99
config/initializers/assets.rb
Normal file
99
config/initializers/assets.rb
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
|
# Enable the asset pipeline
|
||||||
|
Rails.application.config.assets.enabled = true
|
||||||
|
|
||||||
|
# Version of your assets, change this if you want to expire all your assets.
|
||||||
|
Rails.application.config.assets.version = "1.2.5"
|
||||||
|
|
||||||
|
# Add additional assets to the asset load path.
|
||||||
|
Rails.application.config.assets.paths << "#{Rails.root}/config/locales"
|
||||||
|
Rails.application.config.assets.paths << "#{Rails.root}/public/javascripts"
|
||||||
|
|
||||||
|
# Precompile additional assets.
|
||||||
|
# application.js, application.css, and all non-JS/CSS in the app/assets
|
||||||
|
# folder are already added.
|
||||||
|
|
||||||
|
# explicitly precompile any images in plugins ( /assets/images ) path
|
||||||
|
Rails.application.config.assets.precompile += [lambda do |filename, path|
|
||||||
|
path =~ /assets\/images/ && !%w(.js .css).include?(File.extname(filename))
|
||||||
|
end]
|
||||||
|
|
||||||
|
Rails.application.config.assets.precompile += %w{
|
||||||
|
vendor.js
|
||||||
|
admin.js
|
||||||
|
browser-detect.js
|
||||||
|
browser-update.js
|
||||||
|
break_string.js
|
||||||
|
ember_jquery.js
|
||||||
|
pretty-text-bundle.js
|
||||||
|
wizard-application.js
|
||||||
|
wizard-vendor.js
|
||||||
|
markdown-it-bundle.js
|
||||||
|
service-worker.js
|
||||||
|
google-tag-manager.js
|
||||||
|
google-universal-analytics-v3.js
|
||||||
|
google-universal-analytics-v4.js
|
||||||
|
start-discourse.js
|
||||||
|
print-page.js
|
||||||
|
omniauth-complete.js
|
||||||
|
activate-account.js
|
||||||
|
auto-redirect.js
|
||||||
|
wizard-start.js
|
||||||
|
locales/i18n.js
|
||||||
|
discourse/app/lib/webauthn.js
|
||||||
|
confirm-new-email/confirm-new-email.js
|
||||||
|
confirm-new-email/bootstrap.js
|
||||||
|
onpopstate-handler.js
|
||||||
|
embed-application.js
|
||||||
|
discourse/tests/active-plugins.js
|
||||||
|
admin-plugins.js
|
||||||
|
discourse/tests/test_starter.js
|
||||||
|
}
|
||||||
|
|
||||||
|
if EmberCli.enabled?
|
||||||
|
Rails.application.config.assets.precompile += %w{
|
||||||
|
discourse.js
|
||||||
|
test-support.js
|
||||||
|
test-helpers.js
|
||||||
|
scripts/discourse-test-listen-boot
|
||||||
|
scripts/discourse-boot
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Rails.application.config.assets.precompile += %w{
|
||||||
|
application.js
|
||||||
|
discourse/tests/test-support-rails.js
|
||||||
|
discourse/tests/test-helpers-rails.js
|
||||||
|
vendor-theme-tests.js
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Precompile all available locales
|
||||||
|
unless GlobalSetting.try(:omit_base_locales)
|
||||||
|
Dir.glob("#{Rails.root}/app/assets/javascripts/locales/*.js.erb").each do |file|
|
||||||
|
Rails.application.config.assets.precompile << "locales/#{file.match(/([a-z_A-Z]+\.js)\.erb$/)[1]}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# out of the box sprockets 3 grabs loose files that are hanging in assets,
|
||||||
|
# the exclusion list does not include hbs so you double compile all this stuff
|
||||||
|
Rails.application.config.assets.precompile.delete(Sprockets::Railtie::LOOSE_APP_ASSETS)
|
||||||
|
|
||||||
|
# We don't want application from node_modules, only from the root
|
||||||
|
Rails.application.config.assets.precompile.delete(/(?:\/|\\|\A)application\.(css|js)$/)
|
||||||
|
Rails.application.config.assets.precompile += ['application.js']
|
||||||
|
|
||||||
|
start_path = ::Rails.root.join("app/assets").to_s
|
||||||
|
exclude = ['.es6', '.hbs', '.hbr', '.js', '.css', '.lock', '.json', '.log', '.html', '']
|
||||||
|
Rails.application.config.assets.precompile << lambda do |logical_path, filename|
|
||||||
|
filename.start_with?(start_path) &&
|
||||||
|
!filename.include?("/node_modules/") &&
|
||||||
|
!filename.include?("/dist/") &&
|
||||||
|
!exclude.include?(File.extname(logical_path))
|
||||||
|
end
|
||||||
|
|
||||||
|
Discourse.find_plugin_js_assets(include_disabled: true).each do |file|
|
||||||
|
Rails.application.config.assets.precompile << "#{file}.js"
|
||||||
|
end
|
15
config/initializers/filter_parameter_logging.rb
Normal file
15
config/initializers/filter_parameter_logging.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Be sure to restart your server when you modify this file.
|
||||||
|
|
||||||
|
# Configure sensitive parameters which will be filtered from the log file.
|
||||||
|
Rails.application.config.filter_parameters += [
|
||||||
|
:password,
|
||||||
|
:pop3_polling_password,
|
||||||
|
:api_key,
|
||||||
|
:s3_secret_access_key,
|
||||||
|
:twitter_consumer_secret,
|
||||||
|
:facebook_app_secret,
|
||||||
|
:github_client_secret,
|
||||||
|
:second_factor_token,
|
||||||
|
]
|
106
config/initializers/new_framework_defaults_7_0.rb
Normal file
106
config/initializers/new_framework_defaults_7_0.rb
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Be sure to restart your server when you modify this file.
|
||||||
|
#
|
||||||
|
# This file eases your Rails 7.0 framework defaults upgrade.
|
||||||
|
#
|
||||||
|
# Uncomment each configuration one by one to switch to the new default.
|
||||||
|
# Once your application is ready to run with all new defaults, you can remove
|
||||||
|
# this file and set the `config.load_defaults` to `7.0`.
|
||||||
|
#
|
||||||
|
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
|
||||||
|
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
|
||||||
|
|
||||||
|
# `button_to` view helper will render `<button>` element, regardless of whether
|
||||||
|
# or not the content is passed as the first argument or as a block.
|
||||||
|
Rails.application.config.action_view.button_to_generates_button_tag = true
|
||||||
|
|
||||||
|
# `stylesheet_link_tag` view helper will not render the media attribute by default.
|
||||||
|
Rails.application.config.action_view.apply_stylesheet_media_default = false
|
||||||
|
|
||||||
|
# Change the digest class for the key generators to `OpenSSL::Digest::SHA256`.
|
||||||
|
# Changing this default means invalidate all encrypted messages generated by
|
||||||
|
# your application and, all the encrypted cookies. Only change this after you
|
||||||
|
# rotated all the messages using the key rotator.
|
||||||
|
#
|
||||||
|
# See upgrading guide for more information on how to build a rotator.
|
||||||
|
# https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
|
||||||
|
# Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
|
||||||
|
|
||||||
|
# Change the digest class for ActiveSupport::Digest.
|
||||||
|
# Changing this default means that for example Etags change and
|
||||||
|
# various cache keys leading to cache invalidation.
|
||||||
|
# Rails.application.config.active_support.hash_digest_class = OpenSSL::Digest::SHA256
|
||||||
|
|
||||||
|
# Don't override ActiveSupport::TimeWithZone.name and use the default Ruby
|
||||||
|
# implementation.
|
||||||
|
Rails.application.config.active_support.remove_deprecated_time_with_zone_name = true
|
||||||
|
|
||||||
|
# Change the format of the cache entry.
|
||||||
|
# Changing this default means that all new cache entries added to the cache
|
||||||
|
# will have a different format that is not supported by Rails 6.1 applications.
|
||||||
|
# Only change this value after your application is fully deployed to Rails 7.0
|
||||||
|
# and you have no plans to rollback.
|
||||||
|
# Rails.application.config.active_support.cache_format_version = 7.0
|
||||||
|
|
||||||
|
# Calls `Rails.application.executor.wrap` around test cases.
|
||||||
|
# This makes test cases behave closer to an actual request or job.
|
||||||
|
# Several features that are normally disabled in test, such as Active Record query cache
|
||||||
|
# and asynchronous queries will then be enabled.
|
||||||
|
Rails.application.config.active_support.executor_around_test_case = true
|
||||||
|
|
||||||
|
# Define the isolation level of most of Rails internal state.
|
||||||
|
# If you use a fiber based server or job processor, you should set it to `:fiber`.
|
||||||
|
# Otherwise the default of `:thread` if preferable.
|
||||||
|
Rails.application.config.active_support.isolation_level = :thread
|
||||||
|
|
||||||
|
# Set both the `:open_timeout` and `:read_timeout` values for `:smtp` delivery method.
|
||||||
|
Rails.application.config.action_mailer.smtp_timeout = 5
|
||||||
|
|
||||||
|
# Automatically infer `inverse_of` for associations with a scope.
|
||||||
|
Rails.application.config.active_record.automatic_scope_inversing = true
|
||||||
|
|
||||||
|
# Raise when running tests if fixtures contained foreign key violations
|
||||||
|
Rails.application.config.active_record.verify_foreign_keys_for_fixtures = true
|
||||||
|
|
||||||
|
# Disable partial inserts.
|
||||||
|
# This default means that all columns will be referenced in INSERT queries
|
||||||
|
# regardless of whether they have a default or not.
|
||||||
|
Rails.application.config.active_record.partial_inserts = false
|
||||||
|
#
|
||||||
|
# Protect from open redirect attacks in `redirect_back_or_to` and `redirect_to`.
|
||||||
|
Rails.application.config.action_controller.raise_on_open_redirects = true
|
||||||
|
|
||||||
|
# If you're upgrading and haven't set `cookies_serializer` previously, your cookie serializer
|
||||||
|
# was `:marshal`. Convert all cookies to JSON, using the `:hybrid` formatter.
|
||||||
|
#
|
||||||
|
# If you're confident all your cookies are JSON formatted, you can switch to the `:json` formatter.
|
||||||
|
#
|
||||||
|
# Continue to use `:marshal` for backward-compatibility with old cookies.
|
||||||
|
#
|
||||||
|
# If you have configured the serializer elsewhere, you can remove this.
|
||||||
|
#
|
||||||
|
# See https://guides.rubyonrails.org/action_controller_overview.html#cookies for more information.
|
||||||
|
Rails.application.config.action_dispatch.cookies_serializer = :marshal
|
||||||
|
|
||||||
|
# Enable parameter wrapping for JSON.
|
||||||
|
# Previously this was set in an initializer. It's fine to keep using that initializer if you've customized it.
|
||||||
|
# To disable parameter wrapping entirely, set this config to `false`.
|
||||||
|
# Rails.application.config.action_controller.wrap_parameters_by_default = true
|
||||||
|
|
||||||
|
# Specifies whether generated namespaced UUIDs follow the RFC 4122 standard for namespace IDs provided as a
|
||||||
|
# `String` to `Digest::UUID.uuid_v3` or `Digest::UUID.uuid_v5` method calls.
|
||||||
|
#
|
||||||
|
# See https://guides.rubyonrails.org/configuring.html#config-active-support-use-rfc4122-namespaced-uuids for
|
||||||
|
# more information.
|
||||||
|
Rails.application.config.active_support.use_rfc4122_namespaced_uuids = true
|
||||||
|
|
||||||
|
# Change the default headers to disable browsers' flawed legacy XSS protection.
|
||||||
|
Rails.application.config.action_dispatch.default_headers = {
|
||||||
|
"X-Frame-Options" => "SAMEORIGIN",
|
||||||
|
"X-XSS-Protection" => "0",
|
||||||
|
"X-Content-Type-Options" => "nosniff",
|
||||||
|
"X-Download-Options" => "noopen",
|
||||||
|
"X-Permitted-Cross-Domain-Policies" => "none",
|
||||||
|
"Referrer-Policy" => "strict-origin-when-cross-origin"
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "common_passwords/common_passwords"
|
require "common_passwords"
|
||||||
|
|
||||||
class ClearCommonPasswordsCache < ActiveRecord::Migration[4.2]
|
class ClearCommonPasswordsCache < ActiveRecord::Migration[4.2]
|
||||||
def change
|
def change
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'has_errors'
|
require 'has_errors'
|
||||||
|
|
||||||
class Auth::GithubAuthenticator < Auth::ManagedAuthenticator
|
class Auth::GithubAuthenticator < Auth::ManagedAuthenticator
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Auth::OAuth2Authenticator < Auth::Authenticator
|
|
||||||
|
|
||||||
def name
|
|
||||||
@name
|
|
||||||
end
|
|
||||||
|
|
||||||
# only option at the moment is :trusted
|
|
||||||
def initialize(name, opts = {})
|
|
||||||
Discourse.deprecate("OAuth2Authenticator is deprecated. Use `ManagedAuthenticator` and `UserAssociatedAccount` instead. For more information, see https://meta.discourse.org/t/106695", drop_from: '2.9.0', output_in_test: true)
|
|
||||||
@name = name
|
|
||||||
@opts = opts
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_authenticate(auth_token)
|
|
||||||
|
|
||||||
result = Auth::Result.new
|
|
||||||
|
|
||||||
oauth2_provider = auth_token[:provider]
|
|
||||||
oauth2_uid = auth_token[:uid]
|
|
||||||
data = auth_token[:info]
|
|
||||||
result.email = email = data[:email]
|
|
||||||
result.name = name = data[:name]
|
|
||||||
|
|
||||||
oauth2_user_info = Oauth2UserInfo.find_by(uid: oauth2_uid, provider: oauth2_provider)
|
|
||||||
|
|
||||||
if !oauth2_user_info && @opts[:trusted] && user = User.find_by_email(email)
|
|
||||||
oauth2_user_info = Oauth2UserInfo.create(uid: oauth2_uid,
|
|
||||||
provider: oauth2_provider,
|
|
||||||
name: name,
|
|
||||||
email: email,
|
|
||||||
user: user)
|
|
||||||
end
|
|
||||||
|
|
||||||
result.user = oauth2_user_info.try(:user)
|
|
||||||
result.email_valid = @opts[:trusted]
|
|
||||||
|
|
||||||
result.extra_data = {
|
|
||||||
uid: oauth2_uid,
|
|
||||||
provider: oauth2_provider
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_create_account(user, auth)
|
|
||||||
data = auth[:extra_data]
|
|
||||||
association = Oauth2UserInfo.find_or_initialize_by(provider: data[:provider], uid: data[:uid])
|
|
||||||
association.user = user
|
|
||||||
association.email = auth[:email]
|
|
||||||
association.save!
|
|
||||||
end
|
|
||||||
|
|
||||||
def description_for_user(user)
|
|
||||||
info = Oauth2UserInfo.find_by(user_id: user.id, provider: @name)
|
|
||||||
info&.email || info&.name || info&.uid || ""
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -75,7 +75,7 @@ class Auth::Result
|
||||||
|
|
||||||
def self.from_session_data(data, user:)
|
def self.from_session_data(data, user:)
|
||||||
result = new
|
result = new
|
||||||
data = data.symbolize_keys
|
data = data.with_indifferent_access
|
||||||
SESSION_ATTRIBUTES.each { |att| result.public_send("#{att}=", data[att]) }
|
SESSION_ATTRIBUTES.each { |att| result.public_send("#{att}=", data[att]) }
|
||||||
result.user = user
|
result.user = user
|
||||||
result
|
result
|
||||||
|
|
|
@ -10,10 +10,10 @@ module BackupRestore
|
||||||
def self.create(opts = {})
|
def self.create(opts = {})
|
||||||
case opts[:location] || SiteSetting.backup_location
|
case opts[:location] || SiteSetting.backup_location
|
||||||
when BackupLocationSiteSetting::LOCAL
|
when BackupLocationSiteSetting::LOCAL
|
||||||
require_dependency "backup_restore/local_backup_store"
|
require "backup_restore/local_backup_store"
|
||||||
BackupRestore::LocalBackupStore.new(opts)
|
BackupRestore::LocalBackupStore.new(opts)
|
||||||
when BackupLocationSiteSetting::S3
|
when BackupLocationSiteSetting::S3
|
||||||
require_dependency "backup_restore/s3_backup_store"
|
require "backup_restore/s3_backup_store"
|
||||||
BackupRestore::S3BackupStore.new(opts)
|
BackupRestore::S3BackupStore.new(opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require_dependency 'content_security_policy/default'
|
require 'content_security_policy/default'
|
||||||
|
|
||||||
class ContentSecurityPolicy
|
class ContentSecurityPolicy
|
||||||
class Builder
|
class Builder
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require_dependency 'content_security_policy'
|
require 'content_security_policy'
|
||||||
|
|
||||||
class ContentSecurityPolicy
|
class ContentSecurityPolicy
|
||||||
class Default
|
class Default
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
require_dependency 'content_security_policy'
|
require 'content_security_policy'
|
||||||
|
|
||||||
class ContentSecurityPolicy
|
class ContentSecurityPolicy
|
||||||
class Middleware
|
class Middleware
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Support for plugins to register custom setting providers. They can do this
|
|
||||||
# by having a file, `register_provider.rb` in their root that will be run
|
|
||||||
# at this point.
|
|
||||||
|
|
||||||
Dir.glob(File.join(File.dirname(__FILE__), '../plugins', '*', "register_provider.rb")) do |p|
|
|
||||||
require p
|
|
||||||
end
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency "migration/base_dropper"
|
require "migration/base_dropper"
|
||||||
|
|
||||||
class DbHelper
|
class DbHelper
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
require 'cache'
|
require 'cache'
|
||||||
require 'open3'
|
require 'open3'
|
||||||
require_dependency 'plugin/instance'
|
require 'plugin/instance'
|
||||||
require_dependency 'version'
|
require 'version'
|
||||||
|
|
||||||
module Discourse
|
module Discourse
|
||||||
DB_POST_MIGRATE_PATH ||= "db/post_migrate"
|
DB_POST_MIGRATE_PATH ||= "db/post_migrate"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'file_store/base_store'
|
require 'file_store/base_store'
|
||||||
|
|
||||||
module FileStore
|
module FileStore
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
require "uri"
|
require "uri"
|
||||||
require "mini_mime"
|
require "mini_mime"
|
||||||
require_dependency "file_store/base_store"
|
require "file_store/base_store"
|
||||||
require_dependency "s3_helper"
|
require "s3_helper"
|
||||||
require_dependency "file_helper"
|
require "file_helper"
|
||||||
|
|
||||||
module FileStore
|
module FileStore
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Pulls in https://github.com/rails/rails/pull/42368 early since the query is
|
|
||||||
# definitely more efficient as it does not involved the PG planner.
|
|
||||||
# Remove once Rails 7 has been released.
|
|
||||||
module ActiveRecord
|
|
||||||
module ConnectionAdapters
|
|
||||||
class PostgreSQLAdapter
|
|
||||||
def active?
|
|
||||||
@lock.synchronize do
|
|
||||||
@connection.query ";"
|
|
||||||
end
|
|
||||||
true
|
|
||||||
rescue PG::Error
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
50
lib/freedom_patches/ar_references_fix.rb
Normal file
50
lib/freedom_patches/ar_references_fix.rb
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# This patch is a backport of https://github.com/rails/rails/pull/42350
|
||||||
|
# It fixes a bug introduced by Rails which affects reference columns marking
|
||||||
|
# them as integer instead of bigint.
|
||||||
|
#
|
||||||
|
# This should be deleted when version 7.0.3 is released.
|
||||||
|
module FreedomPatches
|
||||||
|
module ArReferencesFix
|
||||||
|
module SchemaDefinition
|
||||||
|
def index_options(table_name)
|
||||||
|
index_options = as_options(index)
|
||||||
|
|
||||||
|
# legacy reference index names are used on versions 6.0 and earlier
|
||||||
|
return index_options if options[:_uses_legacy_reference_index_name]
|
||||||
|
|
||||||
|
index_options[:name] ||= polymorphic_index_name(table_name) if polymorphic
|
||||||
|
index_options
|
||||||
|
end
|
||||||
|
|
||||||
|
ActiveRecord::ConnectionAdapters::ReferenceDefinition.prepend(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ActiveRecord::Migration::Compatibility::V6_0
|
||||||
|
module TableDefinition
|
||||||
|
def references(*args, **options)
|
||||||
|
options[:_uses_legacy_reference_index_name] = true
|
||||||
|
super
|
||||||
|
end
|
||||||
|
alias :belongs_to :references
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_reference(table_name, ref_name, **options)
|
||||||
|
if connection.adapter_name == "SQLite"
|
||||||
|
options[:type] = :integer
|
||||||
|
end
|
||||||
|
options[:_uses_legacy_reference_index_name] = true
|
||||||
|
super
|
||||||
|
end
|
||||||
|
alias :add_belongs_to :add_reference
|
||||||
|
|
||||||
|
def compatible_table_definition(t)
|
||||||
|
class << t
|
||||||
|
prepend TableDefinition
|
||||||
|
end
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@ module RailsMultisite
|
||||||
break if !defined?(RailsFailover::ActiveRecord)
|
break if !defined?(RailsFailover::ActiveRecord)
|
||||||
break if db == RailsMultisite::ConnectionManagement::DEFAULT
|
break if db == RailsMultisite::ConnectionManagement::DEFAULT
|
||||||
|
|
||||||
reading_role = :"#{db}_#{ActiveRecord::Base.reading_role}"
|
reading_role = :"#{db}_#{ActiveRecord.reading_role}"
|
||||||
spec = RailsMultisite::ConnectionManagement.connection_spec(db: db)
|
spec = RailsMultisite::ConnectionManagement.connection_spec(db: db)
|
||||||
|
|
||||||
ActiveRecord::Base.connection_handlers[reading_role] ||= begin
|
ActiveRecord::Base.connection_handlers[reading_role] ||= begin
|
||||||
|
|
|
@ -59,13 +59,13 @@ class HtmlToMarkdown
|
||||||
before, after = parent.children.slice_when { |n| n == br }.to_a
|
before, after = parent.children.slice_when { |n| n == br }.to_a
|
||||||
|
|
||||||
if before.size > 1
|
if before.size > 1
|
||||||
b = Nokogiri::XML::Node.new(parent.name, doc)
|
b = Nokogiri::XML::Node.new(parent.name, doc.document)
|
||||||
before[0...-1].each { |c| b.add_child(c) }
|
before[0...-1].each { |c| b.add_child(c) }
|
||||||
parent.previous = b if b.inner_html.present?
|
parent.previous = b if b.inner_html.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
if after.present?
|
if after.present?
|
||||||
a = Nokogiri::XML::Node.new(parent.name, doc)
|
a = Nokogiri::XML::Node.new(parent.name, doc.document)
|
||||||
after.each { |c| a.add_child(c) }
|
after.each { |c| a.add_child(c) }
|
||||||
parent.next = a if a.inner_html.present?
|
parent.next = a if a.inner_html.present?
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_relative "locale_file_walker"
|
require "locale_file_walker"
|
||||||
|
|
||||||
class DuplicateKeyFinder < LocaleFileWalker
|
class DuplicateKeyFinder < LocaleFileWalker
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency "mobile_detection"
|
require "mobile_detection"
|
||||||
require_dependency "crawler_detection"
|
require "crawler_detection"
|
||||||
require_dependency "guardian"
|
require "guardian"
|
||||||
require_dependency "http_language_parser"
|
require "http_language_parser"
|
||||||
|
|
||||||
module Middleware
|
module Middleware
|
||||||
class AnonymousCache
|
class AnonymousCache
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'migration/base_dropper'
|
require 'migration/base_dropper'
|
||||||
|
|
||||||
module Migration
|
module Migration
|
||||||
class ColumnDropper
|
class ColumnDropper
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'migration/base_dropper'
|
require 'migration/base_dropper'
|
||||||
|
|
||||||
module Migration
|
module Migration
|
||||||
class Migration::TableDropper
|
class Migration::TableDropper
|
||||||
|
|
53
lib/plugin.rb
Normal file
53
lib/plugin.rb
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Plugin
|
||||||
|
def self.initialization_guard(&block)
|
||||||
|
begin
|
||||||
|
block.call
|
||||||
|
rescue => error
|
||||||
|
plugins_directory = Rails.root + 'plugins'
|
||||||
|
|
||||||
|
if error.backtrace && error.backtrace_locations
|
||||||
|
plugin_path = error.backtrace_locations.lazy.map do |location|
|
||||||
|
Pathname.new(location.absolute_path)
|
||||||
|
.ascend
|
||||||
|
.lazy
|
||||||
|
.find { |path| path.parent == plugins_directory }
|
||||||
|
end.next
|
||||||
|
|
||||||
|
raise unless plugin_path
|
||||||
|
|
||||||
|
stack_trace = error.backtrace.each_with_index.inject([]) do |messages, (line, index)|
|
||||||
|
if index == 0
|
||||||
|
messages << "#{line}: #{error} (#{error.class})"
|
||||||
|
else
|
||||||
|
messages << "\t#{index}: from #{line}"
|
||||||
|
end
|
||||||
|
end.reverse.join("\n")
|
||||||
|
|
||||||
|
STDERR.puts <<~TEXT
|
||||||
|
#{stack_trace}
|
||||||
|
|
||||||
|
** INCOMPATIBLE PLUGIN **
|
||||||
|
|
||||||
|
You are unable to build Discourse due to errors in the plugin at
|
||||||
|
#{plugin_path}
|
||||||
|
|
||||||
|
Please try removing this plugin and rebuilding again!
|
||||||
|
TEXT
|
||||||
|
else
|
||||||
|
STDERR.puts <<~TEXT
|
||||||
|
** PLUGIN FAILURE **
|
||||||
|
|
||||||
|
You are unable to build Discourse due to this error during plugin
|
||||||
|
initialization:
|
||||||
|
|
||||||
|
#{error}
|
||||||
|
|
||||||
|
#{error.backtrace.join("\n")}
|
||||||
|
TEXT
|
||||||
|
end
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
require 'digest/sha1'
|
require 'digest/sha1'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require_dependency 'plugin/metadata'
|
require 'plugin/metadata'
|
||||||
require_dependency 'auth'
|
require 'auth'
|
||||||
|
|
||||||
class Plugin::CustomEmoji
|
class Plugin::CustomEmoji
|
||||||
CACHE_KEY ||= "plugin-emoji"
|
CACHE_KEY ||= "plugin-emoji"
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
def plugin_initialization_guard(&block)
|
|
||||||
begin
|
|
||||||
block.call
|
|
||||||
rescue => error
|
|
||||||
plugins_directory = Rails.root + 'plugins'
|
|
||||||
|
|
||||||
if error.backtrace && error.backtrace_locations
|
|
||||||
plugin_path = error.backtrace_locations.lazy.map do |location|
|
|
||||||
Pathname.new(location.absolute_path)
|
|
||||||
.ascend
|
|
||||||
.lazy
|
|
||||||
.find { |path| path.parent == plugins_directory }
|
|
||||||
end.next
|
|
||||||
|
|
||||||
raise unless plugin_path
|
|
||||||
|
|
||||||
stack_trace = error.backtrace.each_with_index.inject([]) do |messages, (line, index)|
|
|
||||||
if index == 0
|
|
||||||
messages << "#{line}: #{error} (#{error.class})"
|
|
||||||
else
|
|
||||||
messages << "\t#{index}: from #{line}"
|
|
||||||
end
|
|
||||||
end.reverse.join("\n")
|
|
||||||
|
|
||||||
STDERR.puts <<~TEXT
|
|
||||||
#{stack_trace}
|
|
||||||
|
|
||||||
** INCOMPATIBLE PLUGIN **
|
|
||||||
|
|
||||||
You are unable to build Discourse due to errors in the plugin at
|
|
||||||
#{plugin_path}
|
|
||||||
|
|
||||||
Please try removing this plugin and rebuilding again!
|
|
||||||
TEXT
|
|
||||||
else
|
|
||||||
STDERR.puts <<~TEXT
|
|
||||||
** PLUGIN FAILURE **
|
|
||||||
|
|
||||||
You are unable to build Discourse due to this error during plugin
|
|
||||||
initialization:
|
|
||||||
|
|
||||||
#{error}
|
|
||||||
|
|
||||||
#{error.backtrace.join("\n")}
|
|
||||||
TEXT
|
|
||||||
end
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'has_errors'
|
require 'has_errors'
|
||||||
|
|
||||||
class PostActionResult
|
class PostActionResult
|
||||||
include HasErrors
|
include HasErrors
|
||||||
|
|
|
@ -18,5 +18,5 @@ module RequireDependencyBackwardCompatibility
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
ActiveSupport::Dependencies::ZeitwerkIntegration::RequireDependency.prepend(self)
|
Object.prepend(self)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'reviewable/collection'
|
require 'reviewable/collection'
|
||||||
|
|
||||||
class Reviewable < ActiveRecord::Base
|
class Reviewable < ActiveRecord::Base
|
||||||
class Actions < Reviewable::Collection
|
class Actions < Reviewable::Collection
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency "s3_helper"
|
require "s3_helper"
|
||||||
|
|
||||||
class S3CorsRulesets
|
class S3CorsRulesets
|
||||||
ASSETS = {
|
ASSETS = {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'stylesheet/importer'
|
require 'stylesheet/importer'
|
||||||
require 'stylesheet/functions'
|
|
||||||
|
|
||||||
module Stylesheet
|
module Stylesheet
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Stylesheet
|
|
||||||
module ScssFunctions
|
|
||||||
def asset_url(path)
|
|
||||||
Discourse.deprecate("The `asset-url` SCSS function is deprecated. Use `absolute-image-url` instead.", drop_from: '2.9.0')
|
|
||||||
SassC::Script::Value::String.new("url('#{ActionController::Base.helpers.asset_url(path.value)}')")
|
|
||||||
end
|
|
||||||
def image_url(path)
|
|
||||||
Discourse.deprecate("The `image-url` SCSS function is deprecated. Use `absolute-image-url` instead.", drop_from: '2.9.0')
|
|
||||||
SassC::Script::Value::String.new("url('#{ActionController::Base.helpers.image_url(path.value)}')")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
::SassC::Script::Functions.include(Stylesheet::ScssFunctions)
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'global_path'
|
require 'global_path'
|
||||||
|
|
||||||
module Stylesheet
|
module Stylesheet
|
||||||
class Importer
|
class Importer
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'distributed_cache'
|
require 'distributed_cache'
|
||||||
require_dependency 'stylesheet/compiler'
|
require 'stylesheet/compiler'
|
||||||
|
|
||||||
module Stylesheet; end
|
module Stylesheet; end
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ require "fileutils"
|
||||||
require "json"
|
require "json"
|
||||||
require "nokogiri"
|
require "nokogiri"
|
||||||
require "open-uri"
|
require "open-uri"
|
||||||
require_dependency "file_helper"
|
require "file_helper"
|
||||||
|
|
||||||
EMOJI_GROUPS_PATH ||= "lib/emoji/groups.json"
|
EMOJI_GROUPS_PATH ||= "lib/emoji/groups.json"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency "file_helper"
|
require "file_helper"
|
||||||
|
|
||||||
task "images:compress" => :environment do
|
task "images:compress" => :environment do
|
||||||
images = Dir.glob("#{Rails.root}/app/**/*.png")
|
images = Dir.glob("#{Rails.root}/app/**/*.png")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency "rake_helpers"
|
require "rake_helpers"
|
||||||
|
|
||||||
def close_old_topics(category)
|
def close_old_topics(category)
|
||||||
topics = Topic.where(closed: false, category_id: category.id)
|
topics = Topic.where(closed: false, category_id: category.id)
|
||||||
|
|
|
@ -8,7 +8,7 @@ require "base62"
|
||||||
# gather #
|
# gather #
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
require_dependency "rake_helpers"
|
require "rake_helpers"
|
||||||
|
|
||||||
task "uploads:gather" => :environment do
|
task "uploads:gather" => :environment do
|
||||||
ENV["RAILS_DB"] ? gather_uploads : gather_uploads_for_all_sites
|
ENV["RAILS_DB"] ? gather_uploads : gather_uploads_for_all_sites
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'compression/zip'
|
require 'compression/zip'
|
||||||
|
|
||||||
module ThemeStore; end
|
module ThemeStore; end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency 'compression/engine'
|
require 'compression/engine'
|
||||||
|
|
||||||
module ThemeStore; end
|
module ThemeStore; end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require_dependency "file_helper"
|
require "file_helper"
|
||||||
|
|
||||||
module Validators; end
|
module Validators; end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "i18n/duplicate_key_finder"
|
|
||||||
|
|
||||||
def extract_locale(path)
|
def extract_locale(path)
|
||||||
path[/\.([^.]{2,})\.yml$/, 1]
|
path[/\.([^.]{2,})\.yml$/, 1]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "i18n/duplicate_key_finder"
|
|
||||||
|
|
||||||
describe "site setting integrity checks" do
|
describe "site setting integrity checks" do
|
||||||
let(:site_setting_file) { File.join(Rails.root, 'config', 'site_settings.yml') }
|
let(:site_setting_file) { File.join(Rails.root, 'config', 'site_settings.yml') }
|
||||||
let(:yaml) { YAML.load_file(site_setting_file) }
|
let(:yaml) { YAML.load_file(site_setting_file) }
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe Jobs::CreateLinkedTopic do
|
describe Jobs::CreateLinkedTopic do
|
||||||
|
|
||||||
it "returns when the post cannot be found" do
|
it "returns when the post cannot be found" do
|
||||||
expect { Jobs::CreateLinkedTopic.new.perform(post_id: 1, sync_exec: true) }.not_to raise_error
|
expect { Jobs::CreateLinkedTopic.new.perform(post_id: 1, sync_exec: true) }.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a post' do
|
context 'with a post' do
|
||||||
|
|
||||||
fab!(:category) { Fabricate(:category) }
|
fab!(:category) { Fabricate(:category) }
|
||||||
fab!(:topic) { Fabricate(:topic, category: category) }
|
fab!(:topic) { Fabricate(:topic, category: category) }
|
||||||
fab!(:post) do
|
fab!(:post) do
|
||||||
|
@ -54,5 +52,4 @@ describe Jobs::CreateLinkedTopic do
|
||||||
expect(linked_topic.sequence).to eq(2)
|
expect(linked_topic.sequence).to eq(2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe Jobs::FeatureTopicUsers do
|
describe Jobs::FeatureTopicUsers do
|
||||||
|
|
||||||
it "raises an error without a topic_id" do
|
it "raises an error without a topic_id" do
|
||||||
expect { Jobs::FeatureTopicUsers.new.execute({}) }.to raise_error(Discourse::InvalidParameters)
|
expect { Jobs::FeatureTopicUsers.new.execute({}) }.to raise_error(Discourse::InvalidParameters)
|
||||||
end
|
end
|
||||||
|
@ -32,16 +31,13 @@ describe Jobs::FeatureTopicUsers do
|
||||||
Jobs::FeatureTopicUsers.new.execute(topic_id: topic.id)
|
Jobs::FeatureTopicUsers.new.execute(topic_id: topic.id)
|
||||||
expect(topic.reload.featured_user_ids.include?(evil_trout.id)).to eq(false)
|
expect(topic.reload.featured_user_ids.include?(evil_trout.id)).to eq(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "participant count" do
|
context "participant count" do
|
||||||
|
|
||||||
let!(:post) { create_post }
|
let!(:post) { create_post }
|
||||||
let(:topic) { post.topic }
|
let(:topic) { post.topic }
|
||||||
|
|
||||||
it "it works as expected" do
|
it "it works as expected" do
|
||||||
|
|
||||||
# It has 1 participant after creation
|
# It has 1 participant after creation
|
||||||
expect(topic.participant_count).to eq(1)
|
expect(topic.participant_count).to eq(1)
|
||||||
|
|
||||||
|
@ -58,9 +54,6 @@ describe Jobs::FeatureTopicUsers do
|
||||||
create_post(topic: topic, user: Fabricate(:evil_trout))
|
create_post(topic: topic, user: Fabricate(:evil_trout))
|
||||||
Jobs::FeatureTopicUsers.new.execute(topic_id: topic.id)
|
Jobs::FeatureTopicUsers.new.execute(topic_id: topic.id)
|
||||||
expect(topic.reload.participant_count).to eq(2)
|
expect(topic.reload.participant_count).to eq(2)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,9 +28,9 @@ describe Jobs::OldKeysReminder do
|
||||||
|
|
||||||
As a courtesy, we wanted to let you know that the following credentials used on your Discourse instance have not been updated in more than two years:
|
As a courtesy, we wanted to let you know that the following credentials used on your Discourse instance have not been updated in more than two years:
|
||||||
|
|
||||||
google_oauth2_client_secret - #{google_secret.updated_at.to_date.to_s(:db)}
|
google_oauth2_client_secret - #{google_secret.updated_at.to_date.to_fs(:db)}
|
||||||
github_client_secret - #{github_secret.updated_at.to_date.to_s(:db)}
|
github_client_secret - #{github_secret.updated_at.to_date.to_fs(:db)}
|
||||||
api key description - #{api_key.created_at.to_date.to_s(:db)}
|
api key description - #{api_key.created_at.to_date.to_fs(:db)}
|
||||||
|
|
||||||
No action is required at this time, however, it is considered good security practice to cycle all your important credentials every few years.
|
No action is required at this time, however, it is considered good security practice to cycle all your important credentials every few years.
|
||||||
TEXT
|
TEXT
|
||||||
|
@ -45,11 +45,11 @@ describe Jobs::OldKeysReminder do
|
||||||
|
|
||||||
As a courtesy, we wanted to let you know that the following credentials used on your Discourse instance have not been updated in more than two years:
|
As a courtesy, we wanted to let you know that the following credentials used on your Discourse instance have not been updated in more than two years:
|
||||||
|
|
||||||
google_oauth2_client_secret - #{google_secret.updated_at.to_date.to_s(:db)}
|
google_oauth2_client_secret - #{google_secret.updated_at.to_date.to_fs(:db)}
|
||||||
github_client_secret - #{github_secret.updated_at.to_date.to_s(:db)}
|
github_client_secret - #{github_secret.updated_at.to_date.to_fs(:db)}
|
||||||
twitter_consumer_secret - #{recent_twitter_secret.updated_at.to_date.to_s(:db)}
|
twitter_consumer_secret - #{recent_twitter_secret.updated_at.to_date.to_fs(:db)}
|
||||||
api key description - #{api_key.created_at.to_date.to_s(:db)}
|
api key description - #{api_key.created_at.to_date.to_fs(:db)}
|
||||||
recent api key description - #{admin.username} - #{recent_api_key.created_at.to_date.to_s(:db)}
|
recent api key description - #{admin.username} - #{recent_api_key.created_at.to_date.to_fs(:db)}
|
||||||
|
|
||||||
No action is required at this time, however, it is considered good security practice to cycle all your important credentials every few years.
|
No action is required at this time, however, it is considered good security practice to cycle all your important credentials every few years.
|
||||||
TEXT
|
TEXT
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe Jobs::ProcessPost do
|
describe Jobs::ProcessPost do
|
||||||
|
|
||||||
it "returns when the post cannot be found" do
|
it "returns when the post cannot be found" do
|
||||||
expect { Jobs::ProcessPost.new.perform(post_id: 1, sync_exec: true) }.not_to raise_error
|
expect { Jobs::ProcessPost.new.perform(post_id: 1, sync_exec: true) }.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a post' do
|
context 'with a post' do
|
||||||
|
|
||||||
fab!(:post) { Fabricate(:post) }
|
fab!(:post) { Fabricate(:post) }
|
||||||
|
|
||||||
it 'does not erase posts when CookedPostProcessor malfunctions' do
|
it 'does not erase posts when CookedPostProcessor malfunctions' do
|
||||||
|
@ -90,5 +88,4 @@ describe Jobs::ProcessPost do
|
||||||
expect(post.topic.reload.excerpt).to eq("Some OP content")
|
expect(post.topic.reload.excerpt).to eq("Some OP content")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe Jobs::PullHotlinkedImages do
|
describe Jobs::PullHotlinkedImages do
|
||||||
|
|
||||||
let(:image_url) { "http://wiki.mozilla.org/images/2/2e/Longcat1.png" }
|
let(:image_url) { "http://wiki.mozilla.org/images/2/2e/Longcat1.png" }
|
||||||
let(:broken_image_url) { "http://wiki.mozilla.org/images/2/2e/Longcat2.png" }
|
let(:broken_image_url) { "http://wiki.mozilla.org/images/2/2e/Longcat2.png" }
|
||||||
let(:large_image_url) { "http://wiki.mozilla.org/images/2/2e/Longcat3.png" }
|
let(:large_image_url) { "http://wiki.mozilla.org/images/2/2e/Longcat3.png" }
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe Jobs::SendSystemMessage do
|
describe Jobs::SendSystemMessage do
|
||||||
|
|
||||||
it "raises an error without a user_id" do
|
it "raises an error without a user_id" do
|
||||||
expect { Jobs::SendSystemMessage.new.execute(message_type: 'welcome_invite') }.to raise_error(Discourse::InvalidParameters)
|
expect { Jobs::SendSystemMessage.new.execute(message_type: 'welcome_invite') }.to raise_error(Discourse::InvalidParameters)
|
||||||
end
|
end
|
||||||
|
@ -11,7 +10,6 @@ describe Jobs::SendSystemMessage do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with valid parameters' do
|
context 'with valid parameters' do
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
||||||
it "should call SystemMessage.create" do
|
it "should call SystemMessage.create" do
|
||||||
|
@ -24,7 +22,5 @@ describe Jobs::SendSystemMessage do
|
||||||
SystemMessage.any_instance.expects(:create).with('post_hidden', options)
|
SystemMessage.any_instance.expects(:create).with('post_hidden', options)
|
||||||
Jobs::SendSystemMessage.new.execute(user_id: user.id, message_type: 'post_hidden', message_options: options)
|
Jobs::SendSystemMessage.new.execute(user_id: user.id, message_type: 'post_hidden', message_options: options)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'guardian'
|
|
||||||
|
|
||||||
describe Guardian do
|
describe Guardian do
|
||||||
|
|
||||||
fab!(:user) { Fabricate(:user) }
|
fab!(:user) { Fabricate(:user) }
|
||||||
|
|
|
@ -193,7 +193,7 @@ describe Hijack do
|
||||||
Process.stubs(:clock_gettime).returns(1.0)
|
Process.stubs(:clock_gettime).returns(1.0)
|
||||||
tester.hijack_test do
|
tester.hijack_test do
|
||||||
Process.stubs(:clock_gettime).returns(2.0)
|
Process.stubs(:clock_gettime).returns(2.0)
|
||||||
redirect_to 'http://awesome.com'
|
redirect_to 'http://awesome.com', allow_other_host: true
|
||||||
end
|
end
|
||||||
|
|
||||||
result = "HTTP/1.1 302 Found\r\nLocation: http://awesome.com\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 84\r\nConnection: close\r\nX-Runtime: 1.000000\r\n\r\n<html><body>You are being <a href=\"http://awesome.com\">redirected</a>.</body></html>"
|
result = "HTTP/1.1 302 Found\r\nLocation: http://awesome.com\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 84\r\nConnection: close\r\nX-Runtime: 1.000000\r\n\r\n<html><body>You are being <a href=\"http://awesome.com\">redirected</a>.</body></html>"
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "i18n/i18n_interpolation_keys_finder"
|
|
||||||
|
|
||||||
RSpec.describe I18nInterpolationKeysFinder do
|
RSpec.describe I18nInterpolationKeysFinder do
|
||||||
describe '#find' do
|
describe '#find' do
|
||||||
it 'should return the right keys' do
|
it 'should return the right keys' do
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'onpdiff'
|
|
||||||
|
|
||||||
describe ONPDiff do
|
describe ONPDiff do
|
||||||
|
|
||||||
describe "diff" do
|
describe "diff" do
|
||||||
|
|
|
@ -74,20 +74,6 @@ describe Stylesheet::Compiler do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports asset-url" do
|
|
||||||
css, _map = Stylesheet::Compiler.compile(".body{background-image: asset-url('/images/favicons/github.png');}", "test.scss")
|
|
||||||
|
|
||||||
expect(css).to include("url('/images/favicons/github.png')")
|
|
||||||
expect(css).not_to include('asset-url')
|
|
||||||
end
|
|
||||||
|
|
||||||
it "supports image-url" do
|
|
||||||
css, _map = Stylesheet::Compiler.compile(".body{background-image: image-url('/favicons/github.png');}", "test.scss")
|
|
||||||
|
|
||||||
expect(css).to include("url('/favicons/github.png')")
|
|
||||||
expect(css).not_to include('image-url')
|
|
||||||
end
|
|
||||||
|
|
||||||
it "supports absolute-image-url" do
|
it "supports absolute-image-url" do
|
||||||
scss = Stylesheet::Importer.new({}).prepended_scss
|
scss = Stylesheet::Importer.new({}).prepended_scss
|
||||||
scss += ".body{background-image: absolute-image-url('/favicons/github.png');}"
|
scss += ".body{background-image: absolute-image-url('/favicons/github.png');}"
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'validators/category_search_priority_weights_validator'
|
|
||||||
|
|
||||||
RSpec.describe CategorySearchPriorityWeightsValidator do
|
RSpec.describe CategorySearchPriorityWeightsValidator do
|
||||||
it "should validate the results correctly" do
|
it "should validate the results correctly" do
|
||||||
[1, 1.1].each do |value|
|
[1, 1.1].each do |value|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'validators/max_emojis_validator'
|
|
||||||
|
|
||||||
describe MaxEmojisValidator do
|
describe MaxEmojisValidator do
|
||||||
|
|
||||||
# simulate Rails behavior (singleton)
|
# simulate Rails behavior (singleton)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'validators/quality_title_validator'
|
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
|
||||||
module QualityTitleValidatorSpec
|
module QualityTitleValidatorSpec
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'validators/topic_title_length_validator'
|
|
||||||
|
|
||||||
describe TopicTitleLengthValidator do
|
describe TopicTitleLengthValidator do
|
||||||
|
|
||||||
# simulate Rails behavior (singleton)
|
# simulate Rails behavior (singleton)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'validators/topic_title_length_validator'
|
|
||||||
|
|
||||||
RSpec.describe UrlValidator do
|
RSpec.describe UrlValidator do
|
||||||
let(:record) { Fabricate.build(:user_profile, user: Fabricate.build(:user)) }
|
let(:record) { Fabricate.build(:user_profile, user: Fabricate.build(:user)) }
|
||||||
let(:validator) { described_class.new(attributes: :website) }
|
let(:validator) { described_class.new(attributes: :website) }
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
describe GivenDailyLike do
|
describe GivenDailyLike do
|
||||||
|
|
||||||
it 'no errors without a user' do
|
it 'no errors without a user' do
|
||||||
expect(-> { GivenDailyLike.increment_for(nil) }).not_to raise_error
|
expect { GivenDailyLike.increment_for(nil) }.not_to raise_error
|
||||||
expect(-> { GivenDailyLike.decrement_for(nil) }).not_to raise_error
|
expect { GivenDailyLike.decrement_for(nil) }.not_to raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a user' do
|
context 'with a user' do
|
||||||
|
|
|
@ -487,7 +487,7 @@ end
|
||||||
|
|
||||||
def decrypt_auth_cookie(cookie)
|
def decrypt_auth_cookie(cookie)
|
||||||
request = ActionDispatch::Request.new(create_request_env.merge("HTTP_COOKIE" => "_t=#{cookie}"))
|
request = ActionDispatch::Request.new(create_request_env.merge("HTTP_COOKIE" => "_t=#{cookie}"))
|
||||||
request.cookie_jar.encrypted["_t"]
|
request.cookie_jar.encrypted["_t"].with_indifferent_access
|
||||||
end
|
end
|
||||||
|
|
||||||
class SpecSecureRandom
|
class SpecSecureRandom
|
||||||
|
|
|
@ -22,14 +22,23 @@ describe InvitesController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows unobfuscated email if email data is present in authentication data' do
|
context 'when email data is present in authentication data' do
|
||||||
ActionDispatch::Request.any_instance.stubs(:session).returns(authentication: { email: invite.email })
|
let(:store) { ActionDispatch::Session::CookieStore.new({}) }
|
||||||
|
let(:session_stub) { ActionDispatch::Request::Session.create(store, ActionDispatch::TestRequest.create, {}) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
session_stub[:authentication] = { email: invite.email }
|
||||||
|
ActionDispatch::Request.any_instance.stubs(:session).returns(session_stub)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows unobfuscated email' do
|
||||||
get "/invites/#{invite.invite_key}"
|
get "/invites/#{invite.invite_key}"
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
expect(response.body).to have_tag(:script, with: { src: "/assets/#{EmberCli.transform_name("application")}.js" })
|
expect(response.body).to have_tag(:script, with: { src: "/assets/#{EmberCli.transform_name("application")}.js" })
|
||||||
expect(response.body).to include(invite.email)
|
expect(response.body).to include(invite.email)
|
||||||
expect(response.body).not_to include('i*****g@a***********e.ooo')
|
expect(response.body).not_to include('i*****g@a***********e.ooo')
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it 'shows default user fields' do
|
it 'shows default user fields' do
|
||||||
user_field = Fabricate(:user_field)
|
user_field = Fabricate(:user_field)
|
||||||
|
|
|
@ -38,7 +38,7 @@ RSpec.describe EmailSettingsExceptionHandler do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "formats a Net::SMTPAuthenticationError with application-specific password Gmail error" do
|
it "formats a Net::SMTPAuthenticationError with application-specific password Gmail error" do
|
||||||
exception = Net::SMTPAuthenticationError.new("Application-specific password required")
|
exception = Net::SMTPAuthenticationError.new(nil, message: "Application-specific password required")
|
||||||
expect(subject.class.friendly_exception_message(exception, "smtp.gmail.com")).to eq(
|
expect(subject.class.friendly_exception_message(exception, "smtp.gmail.com")).to eq(
|
||||||
I18n.t("email_settings.authentication_error_gmail_app_password")
|
I18n.t("email_settings.authentication_error_gmail_app_password")
|
||||||
)
|
)
|
||||||
|
@ -52,15 +52,15 @@ RSpec.describe EmailSettingsExceptionHandler do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "formats a Net::SMTPSyntaxError, Net::SMTPFatalError, and Net::SMTPUnknownError" do
|
it "formats a Net::SMTPSyntaxError, Net::SMTPFatalError, and Net::SMTPUnknownError" do
|
||||||
exception = Net::SMTPSyntaxError.new("bad syntax")
|
exception = Net::SMTPSyntaxError.new(nil, message: "bad syntax")
|
||||||
expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq(
|
expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq(
|
||||||
I18n.t("email_settings.smtp_unhandled_error", message: exception.message)
|
I18n.t("email_settings.smtp_unhandled_error", message: exception.message)
|
||||||
)
|
)
|
||||||
exception = Net::SMTPFatalError.new("fatal")
|
exception = Net::SMTPFatalError.new(nil, message: "fatal")
|
||||||
expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq(
|
expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq(
|
||||||
I18n.t("email_settings.smtp_unhandled_error", message: exception.message)
|
I18n.t("email_settings.smtp_unhandled_error", message: exception.message)
|
||||||
)
|
)
|
||||||
exception = Net::SMTPUnknownError.new("unknown")
|
exception = Net::SMTPUnknownError.new(nil, message: "unknown")
|
||||||
expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq(
|
expect(subject.class.friendly_exception_message(exception, "smtp.test.com")).to eq(
|
||||||
I18n.t("email_settings.smtp_unhandled_error", message: exception.message)
|
I18n.t("email_settings.smtp_unhandled_error", message: exception.message)
|
||||||
)
|
)
|
||||||
|
|
|
@ -112,7 +112,7 @@ RSpec.describe EmailSettingsValidator do
|
||||||
|
|
||||||
it "logs a warning if debug: true passed in and still raises the error" do
|
it "logs a warning if debug: true passed in and still raises the error" do
|
||||||
Rails.logger.expects(:warn).with(regexp_matches(/\[EmailSettingsValidator\] Error encountered/)).at_least_once
|
Rails.logger.expects(:warn).with(regexp_matches(/\[EmailSettingsValidator\] Error encountered/)).at_least_once
|
||||||
net_smtp_stub.stubs(:start).raises(Net::SMTPAuthenticationError, "invalid credentials")
|
net_smtp_stub.stubs(:start).raises(Net::SMTPAuthenticationError, stub(message: "invalid credentials"))
|
||||||
expect { subject.class.validate_smtp(host: host, port: port, username: username, password: password, debug: true, domain: domain) }.to raise_error(Net::SMTPAuthenticationError)
|
expect { subject.class.validate_smtp(host: host, port: port, username: username, password: password, debug: true, domain: domain) }.to raise_error(Net::SMTPAuthenticationError)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
describe "users/omniauth_callbacks/failure.html.erb" do
|
describe "users/omniauth_callbacks/failure.html.erb" do
|
||||||
|
before do
|
||||||
|
flash[:error] = I18n.t("login.omniauth_error", strategy: 'test')
|
||||||
|
end
|
||||||
|
|
||||||
it "renders the failure page" do
|
it "renders the failure page" do
|
||||||
flash[:error] = I18n.t("login.omniauth_error", strategy: 'test')
|
render template: 'users/omniauth_callbacks/failure'
|
||||||
render
|
|
||||||
|
|
||||||
expect(rendered.match(I18n.t("login.omniauth_error.generic", strategy: 'test'))).not_to eq(nil)
|
expect(rendered).to match I18n.t("login.omniauth_error.generic", strategy: 'test')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user