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