From f17718f69fe6d059feb955b2c449c68e27596c5b Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Wed, 16 Nov 2022 19:19:03 +0100 Subject: [PATCH] CSP: Extract JavaScript from layout to assets Fixes CODEOCEAN-CP --- app/assets/javascripts/base.js | 35 +++++++++++++++++-- app/assets/javascripts/codeharbor_link.js | 1 - app/models/user.rb | 9 +++++ app/views/exercises/feedback.html.slim | 3 -- app/views/layouts/application.html.slim | 24 ++----------- .../initializers/content_security_policy.rb | 4 +-- 6 files changed, 46 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/base.js b/app/assets/javascripts/base.js index ef524c25..2abdd3ce 100644 --- a/app/assets/javascripts/base.js +++ b/app/assets/javascripts/base.js @@ -28,11 +28,40 @@ $.fn.scrollTo = function(selector) { // See https://github.com/vakata/jstree/issues/1717 for details $.jstree.defaults.core.worker = false; -// Update all CSRF tokens on the page to reduce InvalidAuthenticityToken errors -// See https://github.com/rails/jquery-ujs/issues/456 for details -$(document).on('turbolinks:load', function(){ +$(document).on('turbolinks:load', function() { + // Update all CSRF tokens on the page to reduce InvalidAuthenticityToken errors + // See https://github.com/rails/jquery-ujs/issues/456 for details $.rails.refreshCSRFTokens(); $('.reloadCurrentPage').on('click', function() { window.location.reload(); }); + + // Set locale for all JavaScript functions + const htmlTag = $('html') + I18n.defaultLocale = htmlTag.data('default-locale'); + I18n.locale = htmlTag.attr('lang'); + jQuery.timeago.settings.lang = I18n.locale; + + // Initialize Sentry + const sentrySettings = $('meta[name="sentry"]') + if (sentrySettings.data()['enabled']) { + Sentry.init({ + dsn: sentrySettings.data('dsn'), + attachStacktrace: true, + release: sentrySettings.data('release'), + environment: sentrySettings.data('environment'), + autoSessionTracking: false + }); + + Sentry.configureScope(function (scope) { + const user = $('meta[name="current-user"]').attr('content'); + + if (user) { + scope.setUser(JSON.parse(user)); + } + }); + } + + // Enable all tooltips + $('[data-bs-toggle="tooltip"]').tooltip(); }); diff --git a/app/assets/javascripts/codeharbor_link.js b/app/assets/javascripts/codeharbor_link.js index fdf42859..c63e8b60 100644 --- a/app/assets/javascripts/codeharbor_link.js +++ b/app/assets/javascripts/codeharbor_link.js @@ -1,5 +1,4 @@ $(document).on('turbolinks:load', function() { - $('[data-bs-toggle="tooltip"]').tooltip(); if($.isController('codeharbor_links')) { if ($('.edit_codeharbor_link, .new_codeharbor_link').isPresent()) { diff --git a/app/models/user.rb b/app/models/user.rb index f6dbc976..e1d8fe1e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -71,6 +71,15 @@ class User < ApplicationRecord displayname end + def to_sentry_context + { + id: id, + type: self.class.name, + username: displayname, + consumer: consumer.name, + } + end + def self.ransackable_attributes(auth_object) if auth_object.present? && auth_object.admin? %w[name email external_id consumer_id platform_admin] diff --git a/app/views/exercises/feedback.html.slim b/app/views/exercises/feedback.html.slim index e52b5c5b..74bd2c7c 100644 --- a/app/views/exercises/feedback.html.slim +++ b/app/views/exercises/feedback.html.slim @@ -35,6 +35,3 @@ h1 = link_to_if(policy(@exercise).show?, @exercise, exercise_path(@exercise)) span.working_time.float-end = "#{t('exercises.statistics.worktime')}: #{@exercise.average_working_time_for(feedback.user) or 0}" = render('shared/pagination', collection: @feedbacks) - - = javascript_tag nonce: true do - | $(function () { $('[data-bs-toggle="tooltip"]').tooltip() }); diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index 864e5b6d..9deeee8e 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -1,5 +1,5 @@ doctype html -html lang="#{I18n.locale || I18n.default_locale}" +html lang="#{I18n.locale || I18n.default_locale}" data-default-locale="#{I18n.default_locale}" head meta charset='utf8' meta name='viewport' content='width=device-width, initial-scale=1' @@ -15,26 +15,8 @@ html lang="#{I18n.locale || I18n.default_locale}" = javascript_include_tag('application', 'data-turbolinks-track': true, integrity: true, crossorigin: 'anonymous') = yield(:head) = csrf_meta_tags - = timeago_script_tag nonce: true - = javascript_tag nonce: true do - | I18n.defaultLocale = "#{I18n.default_locale}"; - | I18n.locale = "#{I18n.locale}"; - - if SentryJavascript.active? - | Sentry.init({ - | dsn: 'https://2616b10855e04ce1b748775203ff0f7c@o257002.ingest.sentry.io/5667283', - | attachStacktrace: true, - | release: "#{SentryJavascript.release}", - | environment: "#{SentryJavascript.environment}", - | }); - - if current_user - | Sentry.configureScope(function(scope) { - | scope.setUser({ - | "id": "#{current_user.id}", - | "type": "#{current_user.class.name}", - | "username": "#{current_user.displayname}", - | "consumer": "#{current_user.consumer.name}" - | }); - | }); + meta name='sentry' data-enabled=SentryJavascript.active?.to_s data-release=SentryJavascript.release data-dsn=SentryJavascript.dsn data-environment=SentryJavascript.environment + meta name='current-user' content=current_user&.to_sentry_context&.to_json body - unless @embed_options[:hide_navbar] nav.navbar.navbar-dark.bg-dark.navbar-expand-md.mb-4.py-1 role='navigation' diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 28a405e1..ec5c5583 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -56,10 +56,10 @@ Rails.application.config.content_security_policy do |policy| end # If you are using UJS then enable automatic nonce generation -Rails.application.config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# Rails.application.config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } # Set the nonce only to specific directives -Rails.application.config.content_security_policy_nonce_directives = %w[script-src] +# Rails.application.config.content_security_policy_nonce_directives = %w[script-src] # Report CSP violations to a specified URI # For further information see the following documentation: