diff --git a/app/models/theme_field.rb b/app/models/theme_field.rb
index 38c19da7bb5..fe4e0bf644f 100644
--- a/app/models/theme_field.rb
+++ b/app/models/theme_field.rb
@@ -71,6 +71,8 @@ class ThemeField < ActiveRecord::Base
errors = []
javascript_cache || build_javascript_cache
+ errors << I18n.t("themes.errors.optimized_link") if contains_optimized_link?(html)
+
js_compiler = ThemeJavascriptCompiler.new(theme_id, self.theme.name)
doc = Nokogiri::HTML.fragment(html)
@@ -355,7 +357,11 @@ class ThemeField < ActiveRecord::Base
result = ["failed"]
begin
result = compile_scss
- self.error = nil unless error.nil?
+ if contains_optimized_link?(self.value)
+ self.error = I18n.t("themes.errors.optimized_link")
+ else
+ self.error = nil unless error.nil?
+ end
rescue SassC::SyntaxError => e
self.error = e.message unless self.destroyed?
end
@@ -367,6 +373,10 @@ class ThemeField < ActiveRecord::Base
Theme.targets[target_id].to_s
end
+ def contains_optimized_link?(text)
+ OptimizedImage::URL_REGEX.match?(text)
+ end
+
class ThemeFileMatcher
OPTIONS = %i{name type target}
# regex: used to match file names to fields (import).
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 6d3cefe3056..2945673db6a 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -92,6 +92,7 @@ en:
component_no_default: "Theme components can't be default theme"
component_no_color_scheme: "Theme components can't have color palettes"
no_multilevels_components: "Themes with child themes can't be child themes themselves"
+ optimized_link: Optimized image links are ephemeral and should not be included in theme source code.
settings_errors:
invalid_yaml: "Provided YAML is invalid."
data_type_not_a_number: "Setting `%{name}` type is unsupported. Supported types are `integer`, `bool`, `list` and `enum`"
diff --git a/spec/models/theme_field_spec.rb b/spec/models/theme_field_spec.rb
index 5506305924b..c6fc9c5764e 100644
--- a/spec/models/theme_field_spec.rb
+++ b/spec/models/theme_field_spec.rb
@@ -34,6 +34,30 @@ describe ThemeField do
expect(theme_field.value_baked).to_not include('
+ HTML
+ theme_field.ensure_baked!
+ expect(theme_field.error).to include(I18n.t("themes.errors.optimized_link"))
+
+ theme_field = ThemeField.create!(theme_id: 1, target_id: 0, name: "scss", value: <<~SCSS)
+ body {
+ background: url(http://mysite.invalid/uploads/default/optimized/1X/6d749a141f513f88f167e750e528515002043da1_2_1282x1000.png);
+ }
+ SCSS
+ theme_field.ensure_baked!
+ expect(theme_field.error).to include(I18n.t("themes.errors.optimized_link"))
+
+ theme_field.update(value: <<~SCSS)
+ body {
+ background: url(http://notdiscourse.invalid/optimized/my_image.png);
+ }
+ SCSS
+ theme_field.ensure_baked!
+ expect(theme_field.error).to eq(nil)
+ end
+
it 'only extracts inline javascript to an external file' do
html = <<~HTML