FIX: Include locale in extra-locales URLs (#31480)

Previously the rendered locale was based on the current session's
locale. Now that we're routing requests via the CDN, we can't rely on
the user's session, and should instead include the locale name in the
URL. Also adds a `.js` suffix for parity with our other JS assets.
This commit is contained in:
David Taylor
2025-02-24 17:20:46 +00:00
committed by GitHub
parent 2062e4eb90
commit 1f5cce705c
4 changed files with 77 additions and 59 deletions

View File

@ -23,50 +23,54 @@ class ExtraLocalesController < ApplicationController
@js_digests ||= { site_specific: {}, shared: {} }
end
def bundle_js_hash(bundle)
bundle_key = "#{bundle}_#{I18n.locale}"
def bundle_js_hash(bundle, locale:)
bundle_key = "#{bundle}_#{locale}"
if bundle.in?(SITE_SPECIFIC_BUNDLES)
site = RailsMultisite::ConnectionManagement.current_db
js_digests[:site_specific][site] ||= {}
js_digests[:site_specific][site][bundle_key] ||= begin
js = bundle_js(bundle)
js = bundle_js(bundle, locale: locale)
js.present? ? digest_for_content(js) : nil
end
elsif bundle.in?(SHARED_BUNDLES)
js_digests[:shared][bundle_key] ||= digest_for_content(bundle_js(bundle))
js_digests[:shared][bundle_key] ||= digest_for_content(bundle_js(bundle, locale: locale))
else
raise "Unknown bundle: #{bundle}"
end
end
def url(bundle)
def url(bundle, locale: I18n.locale)
hash = bundle_js_hash(bundle, locale:)
base = "#{GlobalSetting.cdn_url}#{Discourse.base_path}"
path = "/extra-locales/#{bundle_js_hash(bundle)}/#{bundle}"
path = "/extra-locales/#{hash}/#{locale}/#{bundle}.js"
query = SITE_SPECIFIC_BUNDLES.include?(bundle) ? "?__ws=#{Discourse.current_hostname}" : ""
"#{base}#{path}#{query}"
end
def client_overrides_exist?
bundle_js_hash(OVERRIDES_BUNDLE).present?
def client_overrides_exist?(locale: I18n.locale)
bundle_js_hash(OVERRIDES_BUNDLE, locale: locale).present?
end
def bundle_js(bundle)
locale_str = I18n.locale.to_s
def bundle_js(bundle, locale:)
locale_str = locale.to_s
bundle_str = "#{bundle}_js"
case bundle
when OVERRIDES_BUNDLE
JsLocaleHelper.output_client_overrides(locale_str)
when MF_BUNDLE
JsLocaleHelper.output_MF(locale_str)
else
JsLocaleHelper.output_extra_locales(bundle_str, locale_str)
I18n.with_locale(locale) do
case bundle
when OVERRIDES_BUNDLE
JsLocaleHelper.output_client_overrides(locale_str)
when MF_BUNDLE
JsLocaleHelper.output_MF(locale_str)
else
JsLocaleHelper.output_extra_locales(bundle_str, locale_str)
end
end
end
def bundle_js_with_hash(bundle)
js = bundle_js(bundle)
def bundle_js_with_hash(bundle, locale:)
js = bundle_js(bundle, locale: locale)
[js, digest_for_content(js)]
end
@ -82,14 +86,17 @@ class ExtraLocalesController < ApplicationController
def show
bundle = params[:bundle]
raise Discourse::InvalidAccess.new if !valid_bundle?(bundle)
raise Discourse::NotFound if !valid_bundle?(bundle)
locale = params[:locale]
raise Discourse::NotFound if !I18n.available_locales.include?(locale.to_sym)
digest = params[:digest]
if digest.present?
raise Discourse::InvalidParameters.new(:digest) unless digest.to_s.size == SHA1_HASH_LENGTH
end
content, hash = ExtraLocalesController.bundle_js_with_hash(bundle)
content, hash = ExtraLocalesController.bundle_js_with_hash(bundle, locale:)
immutable_for(1.year) if hash == digest
render plain: content, content_type: "application/javascript"