From 874b9b3ed91fd492a978134d369f95f8724208ed Mon Sep 17 00:00:00 2001 From: Sylvain Date: Fri, 17 Feb 2023 16:56:17 +0100 Subject: [PATCH] (feat) Check SCSS syntax before saving home page style --- CHANGELOG.md | 1 + app/controllers/api/settings_controller.rb | 20 ++++++++++++++------ app/services/setting_service.rb | 17 +++++++++++++++++ config/locales/app.admin.en.yml | 2 +- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c1ee98d7..9c29c2c63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Filter projects by status - Maximum validity period for trainings authorizations - Automatically cancel trainings with insufficient attendees +- Check SCSS syntax before saving home page style - Fix a bug: cannot cancel a subscription after offering free days - Fix a bug: event image updates are not reflected unless the browser's cache is purged - Fix a bug: schedules jobs are not launched at the right time diff --git a/app/controllers/api/settings_controller.rb b/app/controllers/api/settings_controller.rb index 4bf7a5155..f5bb6a381 100644 --- a/app/controllers/api/settings_controller.rb +++ b/app/controllers/api/settings_controller.rb @@ -14,6 +14,9 @@ class API::SettingsController < API::ApiController render status: :not_modified and return if setting_params[:value] == @setting.value render status: :locked, json: { error: I18n.t('settings.locked_setting') } and return unless SettingService.update_allowed?(@setting) + error = SettingService.check_before_update({ name: params[:name], value: setting_params[:value] }) + render status: :unprocessable_entity, json: { error: error } and return if error + if @setting.save && @setting.history_values.create(value: setting_params[:value], invoicing_profile: current_user.invoicing_profile) SettingService.run_after_update([@setting]) render status: :ok @@ -32,13 +35,18 @@ class API::SettingsController < API::ApiController next if !setting[:name] || !setting[:value] || setting[:value].blank? db_setting = Setting.find_or_initialize_by(name: setting[:name]) - if !SettingService.update_allowed?(db_setting) - db_setting.errors.add(:-, "#{I18n.t("settings.#{setting[:name]}")}: #{I18n.t('settings.locked_setting')}") - elsif db_setting.save - if db_setting.value != setting[:value] && - db_setting.history_values.create(value: setting[:value], invoicing_profile: current_user.invoicing_profile) - updated_settings.push(db_setting) + if SettingService.update_allowed?(db_setting) + error = SettingService.check_before_update(setting) + if error + db_setting.errors.add(:-, "#{I18n.t("settings.#{setting[:name]}")}: #{error}") + elsif db_setting.save + if db_setting.value != setting[:value] && + db_setting.history_values.create(value: setting[:value], invoicing_profile: current_user.invoicing_profile) + updated_settings.push(db_setting) + end end + else + db_setting.errors.add(:-, "#{I18n.t("settings.#{setting[:name]}")}: #{I18n.t('settings.locked_setting')}") end @settings.push db_setting diff --git a/app/services/setting_service.rb b/app/services/setting_service.rb index f904d9213..f6c13c05e 100644 --- a/app/services/setting_service.rb +++ b/app/services/setting_service.rb @@ -12,6 +12,12 @@ class SettingService true end + # @param setting [Hash{Symbol->String}] + # @return [StandardError,NilClass] + def check_before_update(setting) + check_home_scss(setting) + end + # @param settings [Array] def run_after_update(settings) update_theme_stylesheet(settings) @@ -37,6 +43,17 @@ class SettingService Stylesheet.theme&.rebuild! end + # validate that the provided SCSS has a valid syntax + def check_home_scss(setting) + return nil unless setting[:name] == 'home_css' + + engine = SassC::Engine.new(".home-page { #{setting[:value]} }", style: :compressed) + engine.render + nil + rescue StandardError => e + e + end + # rebuild the home page stylesheet # @param settings [Array] def update_home_stylesheet(settings) diff --git a/config/locales/app.admin.en.yml b/config/locales/app.admin.en.yml index c64b15735..c89977d48 100644 --- a/config/locales/app.admin.en.yml +++ b/config/locales/app.admin.en.yml @@ -1654,7 +1654,7 @@ en: slot_duration: "slots duration" advanced: "Advanced settings" customize_home_page_css: "Customise the stylesheet of the home page" - home_css_notice_html: "You can customize the stylesheet which will apply to the home page, using the SASS syntax. These styles will be automatically subordinated to the .home-page selector to prevent any risk of breaking the application. Meanwhile please be careful, any changes in the home page editor at the top of the page may broke your styles, always refer to the HTML code." + home_css_notice_html: "You can customize the stylesheet which will apply to the home page, using the SCSS syntax. These styles will be automatically subordinated to the .home-page selector to prevent any risk of breaking the application. Meanwhile please be careful, any changes in the home page editor at the top of the page may broke your styles, always refer to the HTML code." error_SETTING_locked: "Unable to update the setting: {SETTING} is locked. Please contact your system administrator." an_error_occurred_saving_the_setting: "An error occurred while saving the setting. Please try again later." book_overlapping_slots_info: "Allow / prevent the reservation of overlapping slots"