diff --git a/Gemfile.lock b/Gemfile.lock index 9705bb5e34ec40b006277747630da32be3e6a3ca..423f6dc99ce4336812ed2f0c59242817089ec017 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -190,7 +190,7 @@ GEM delayed_job (> 2.0.3) rack-protection (>= 1.5.5) sinatra (>= 1.4.4) - devise (4.9.2) + devise (4.9.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -263,7 +263,7 @@ GEM json net-http open-uri - has_scope (0.8.1) + has_scope (0.8.2) actionpack (>= 5.2) activesupport (>= 5.2) hash_dot (2.5.0) @@ -318,7 +318,7 @@ GEM listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.21.3) + loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -450,10 +450,10 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - regexp_parser (2.8.1) + regexp_parser (2.8.2) requests (1.0.2) require_all (3.0.0) - responders (3.1.0) + responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) rexml (3.2.6) @@ -494,10 +494,10 @@ GEM typhoeus (~> 1.0, >= 1.0.1) simple-navigation (4.4.0) activesupport (>= 2.3.2) - simple_form (5.2.0) + simple_form (5.3.0) actionpack (>= 5.2) activemodel (>= 5.2) - simple_form_bs5_file_input (0.1.0) + simple_form_bs5_file_input (0.1.2) rails simple_form simple_form_password_with_hints (0.0.7) diff --git a/app/assets/images/communication/blocks/templates/video.jpg b/app/assets/images/communication/blocks/templates/video.jpg index 67209baf0e096853da894801adca4cb42e323514..1bfc82efc7dc17a1da288c579657e724edea9091 100644 Binary files a/app/assets/images/communication/blocks/templates/video.jpg and b/app/assets/images/communication/blocks/templates/video.jpg differ diff --git a/app/assets/stylesheets/extranet/layout/_nav.sass b/app/assets/stylesheets/extranet/layout/_nav.sass index bfe58ba9c021174e2a18a3fee42cca2cf1f6ac94..a15d37a376101b3e6ada794b67da62a96f6d7130 100644 --- a/app/assets/stylesheets/extranet/layout/_nav.sass +++ b/app/assets/stylesheets/extranet/layout/_nav.sass @@ -5,7 +5,7 @@ padding-top: 30px .navbar-brand img - max-width: 100px + object-fit: contain .nav-link color: black .active diff --git a/app/assets/stylesheets/extranet/pages/_devise.sass b/app/assets/stylesheets/extranet/pages/_devise.sass index 1912649d4e81c42ea626a6fc08596e52ca3e61f3..ee5e3a23810ace49650d54c49fd69b9570657f25 100644 --- a/app/assets/stylesheets/extranet/pages/_devise.sass +++ b/app/assets/stylesheets/extranet/pages/_devise.sass @@ -1,8 +1,8 @@ .layout-devise background-color: $header-color .logo - max-width: 150px margin: 120px 0 + object-fit: contain footer margin-top: 100px border-top: 1px solid $light-border-color diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index c4c9aa3b11e0c942ef52317d3bf54b3525f615cb..4325862409463736c68493a4a2c225cdeb80a6c4 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -34,8 +34,18 @@ class NotificationMailer < ApplicationMailer merge_with_university_infos(university, {}) @credits = credits.to_i mails = university.users.server_admin.pluck(:email) + I18n.locale = university.default_language.iso_code subject = t('mailers.notifications.low_sms_credits.subject', credits: @credits) mail(from: university.mail_from[:full], to: mails, subject: subject) end + + def new_registration(university, user) + merge_with_university_infos(university, {}) + @user = user + mails = university.users.where.not(id: @user.id).where(role: [:server_admin, :admin]).pluck(:email) + I18n.locale = university.default_language.iso_code + subject = t('mailers.notifications.new_registration.subject', mail: @user.email) + mail(from: university.mail_from[:full], to: mails, subject: subject) + end end diff --git a/app/models/communication/block/template/video.rb b/app/models/communication/block/template/video.rb index 0e0612d61b86f51883bdc0ff1bf4433d9d8ac71b..aca2443ddc02b8da59c351b913e6f1f5e873237e 100644 --- a/app/models/communication/block/template/video.rb +++ b/app/models/communication/block/template/video.rb @@ -5,11 +5,40 @@ class Communication::Block::Template::Video < Communication::Block::Template::Ba has_component :transcription, :text def video_iframe - Video::Provider.find(url).iframe_tag(title: video_title) + video_provider.iframe_tag(title: video_iframe_title) + end + + def video_iframe_title + video_title.blank? ? 'Video' + : video_title + end + + def video_platform + video_provider.platform + end + + def video_identifier + video_provider.identifier + end + + def video_poster + video_provider.poster + end + + def video_embed + video_provider.embed + end + + def video_embed_with_defaults + video_provider.embed_with_defaults end protected + def video_provider + @video_provider ||= Video::Provider.find(url) + end + def check_accessibility super accessibility_error 'accessibility.blocks.templates.video.title_missing' if block.title.blank? && video_title.blank? diff --git a/app/models/communication/extranet.rb b/app/models/communication/extranet.rb index 1a4615b3d6c6865f180dd318b43f9c1268235907..0dc31636314ab864924471003317609996665e7c 100644 --- a/app/models/communication/extranet.rb +++ b/app/models/communication/extranet.rb @@ -2,35 +2,34 @@ # # Table name: communication_extranets # -# id :uuid not null, primary key -# about_type :string indexed => [about_id] -# allow_experiences_modification :boolean default(TRUE) -# color :string -# cookies_policy :text -# css :text -# feature_alumni :boolean default(FALSE) -# feature_contacts :boolean default(FALSE) -# feature_jobs :boolean default(FALSE) -# feature_library :boolean default(FALSE) -# feature_posts :boolean default(FALSE) -# has_sso :boolean default(FALSE) -# home_sentence :text -# host :string -# name :string -# privacy_policy :text -# registration_contact :string -# sass :text -# sso_button_label :string -# sso_cert :text -# sso_mapping :jsonb -# sso_name_identifier_format :string -# sso_provider :integer default("saml") -# sso_target_url :string -# terms :text -# created_at :datetime not null -# updated_at :datetime not null -# about_id :uuid indexed => [about_type] -# university_id :uuid not null, indexed +# id :uuid not null, primary key +# about_type :string indexed => [about_id] +# color :string +# cookies_policy :text +# css :text +# feature_alumni :boolean default(FALSE) +# feature_contacts :boolean default(FALSE) +# feature_jobs :boolean default(FALSE) +# feature_library :boolean default(FALSE) +# feature_posts :boolean default(FALSE) +# has_sso :boolean default(FALSE) +# home_sentence :text +# host :string +# name :string +# privacy_policy :text +# registration_contact :string +# sass :text +# sso_button_label :string +# sso_cert :text +# sso_mapping :jsonb +# sso_name_identifier_format :string +# sso_provider :integer default("saml") +# sso_target_url :string +# terms :text +# created_at :datetime not null +# updated_at :datetime not null +# about_id :uuid indexed => [about_type] +# university_id :uuid not null, indexed # # Indexes # diff --git a/app/models/communication/website/with_security.rb b/app/models/communication/website/with_security.rb index d9aa9041dac34550347d6b6d985dc3bc6d396e40..9313daea312d19ea19587e39ca4efd5c83a213c9 100644 --- a/app/models/communication/website/with_security.rb +++ b/app/models/communication/website/with_security.rb @@ -16,11 +16,11 @@ module Communication::Website::WithSecurity def external_domains_default [ - 'osuny-1b4da.kxcdn.com', # KeyCDN for assets resize + ENV['KEYCDN_HOST'], # KeyCDN for assets resize '*.osuny.org', # Osuny for assets resize 'osuny.s3.fr-par.scw.cloud', # Scaleway for direct assets - 'tile.openstreetmap.org' # Open Street Map default tiles - ] + 'tile.openstreetmap.org' # Open Street Map default tiles + ].compact end def external_domains_plausible @@ -34,7 +34,7 @@ module Communication::Website::WithSecurity blocks.where(template_kind: :video).each do |block| video_url = block.template.url next unless video_url.present? - list << Video::Provider.find(video_url).csp_domain + list.concat Video::Provider.find(video_url).csp_domains end list end diff --git a/app/models/import.rb b/app/models/import.rb index d3ebfb313898a94e3b54ae7f60567fb31e867287..6e4c56d279484c96f3e5ed1fc582447e72afb004 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -10,7 +10,7 @@ # created_at :datetime not null # updated_at :datetime not null # university_id :uuid not null, indexed -# user_id :uuid not null, indexed +# user_id :uuid indexed # # Indexes # @@ -24,11 +24,10 @@ # class Import < ApplicationRecord belongs_to :university - belongs_to :user + belongs_to :user, optional: true has_one_attached_deletable :file - enum kind: { organizations: 0, alumni_cohorts: 1, people_experiences: 2 }, _prefix: :kind enum status: { pending: 0, finished: 1, finished_with_errors: 2 } diff --git a/app/models/user.rb b/app/models/user.rb index 3da9b8ced4d07c41daa1ab9719aa18aec6cc34d6..6e92659a9ac22e4f2158d41a21945b85fa84ff7c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -72,6 +72,7 @@ class User < ApplicationRecord belongs_to :language has_many :university_people, class_name: 'University::Person', dependent: :nullify + has_many :imports, class_name: 'Import', dependent: :nullify scope :ordered, -> { order(:last_name, :first_name) } scope :for_language, -> (language_id) { where(language_id: language_id) } diff --git a/app/models/user/with_registration_context.rb b/app/models/user/with_registration_context.rb index 2b994b4dd04a1644e00764dfd7a3d17ec8978583..a06d5dda1f32aef0b4eacd07b3fd5be1d509c2e8 100644 --- a/app/models/user/with_registration_context.rb +++ b/app/models/user/with_registration_context.rb @@ -6,6 +6,8 @@ module User::WithRegistrationContext validate :extranet_access, on: :create, if: -> { registration_context.is_a?(Communication::Extranet) } + after_create :send_notification_to_admins, unless: -> { registration_context.is_a?(Communication::Extranet) } + private def extranet_access @@ -30,5 +32,9 @@ module User::WithRegistrationContext registration_context.has_feature?(:contacts) && registration_context.connected_people.where(email: email).any? end + def send_notification_to_admins + NotificationMailer.new_registration(university, self).deliver_later + end + end end diff --git a/app/models/user/with_sync_between_universities.rb b/app/models/user/with_sync_between_universities.rb index da5871829b39ed39968771eda9241c88f31f854e..660f9f4e6354fb9083f6357e1977d5cefe3cd4bb 100644 --- a/app/models/user/with_sync_between_universities.rb +++ b/app/models/user/with_sync_between_universities.rb @@ -5,6 +5,7 @@ module User::WithSyncBetweenUniversities attr_accessor :skip_server_admin_sync after_save :sync_between_universities, if: Proc.new { |user| user.server_admin? && !user.skip_server_admin_sync } + after_destroy :remove_from_all_universities, if: Proc.new { |user| user.server_admin? } def self.synchronize_server_admin_users(source_university, target_university) source_university.users.server_admin.each do |user| @@ -48,4 +49,9 @@ module User::WithSyncBetweenUniversities user.update_column(:encrypted_password, self.encrypted_password) if user.valid? end + def remove_from_all_universities + # As a "server_admin" is synced between universities, any removal destroys the accounts of the concerned user in every university + User.where(email: email, role: :server_admin).destroy_all + end + end diff --git a/app/services/video/provider/dailymotion.rb b/app/services/video/provider/dailymotion.rb index 2cd9d3900692a9f76ecfcbf28b5a24562a3e4213..c69c4ec214e7ab4d18e6ec7be0db3b6e5b796fff 100644 --- a/app/services/video/provider/dailymotion.rb +++ b/app/services/video/provider/dailymotion.rb @@ -1,13 +1,32 @@ class Video::Provider::Dailymotion < Video::Provider::Default - DOMAINS = ['dailymotion.com', 'dai.ly'] + DOMAINS = [ + 'dailymotion.com', + 'www.dailymotion.com', + 'dai.ly', + '*.dmcdn.net' + ] def identifier video_url.include?('dai.ly') ? video_url.split('dai.ly/').last : video_url.split('video/').last end + def csp_domains + DOMAINS + end + + # https://www.dailymotion.com/thumbnail/video/x8lyp39 + def poster + "https://www.dailymotion.com/thumbnail/video/#{identifier}" + end + # https://developer.dailymotion.com/player#player-parameters def iframe_url "https://www.dailymotion.com/embed/video/#{identifier}" end + + # L'autoplay est à 1 uniquement parce que l'iframe n'est pas chargée + def embed_with_defaults + "#{iframe_url}?autoplay=1&quality=380" + end end diff --git a/app/services/video/provider/default.rb b/app/services/video/provider/default.rb index bb0f92e3f4bbf72beec5619eb7e9aa106cbe65ac..cb8b7b3ec048b661d26e486cf966a60f0be48a3f 100644 --- a/app/services/video/provider/default.rb +++ b/app/services/video/provider/default.rb @@ -17,10 +17,30 @@ class Video::Provider::Default video_url end - def csp_domain + def csp_domains + [host] + end + + def identifier + '' + end + + def host URI.parse(iframe_url).host end + def poster + '' + end + + def embed + iframe_url + end + + def embed_with_defaults + embed + end + def iframe_tag(**iframe_options) content_tag(:iframe, nil, default_iframe_options.merge(iframe_options)) end @@ -31,7 +51,7 @@ class Video::Provider::Default def default_iframe_options { - class: (platform == :default ? nil : platform), + class: platform, loading: 'lazy', src: iframe_url } diff --git a/app/services/video/provider/peertube.rb b/app/services/video/provider/peertube.rb index af3b2ce744b0f0f392d0d60618fda3f52ae0a3cc..136c1ad02d17c890c906f30d985b0aad1348cae3 100644 --- a/app/services/video/provider/peertube.rb +++ b/app/services/video/provider/peertube.rb @@ -1,25 +1,32 @@ class Video::Provider::Peertube < Video::Provider::Default - DOMAINS = ['peertube.fr'] + DOMAINS = [ + 'peertube.fr' + ] def identifier video_url.split('/w/').last end - def host - video_url.split('/w/').first - end - # https://docs.joinpeertube.org/support/doc/api/embeds#quick-start def iframe_url - "#{host}/videos/embed/#{identifier}" + "#{instance}/videos/embed/#{identifier}" end def correct? url_in_domains? || url_looks_like_peertube? end + # L'autoplay est à 1 uniquement parce que l'iframe n'est pas chargée + def embed_with_defaults + "#{iframe_url}?autoplay=1" + end + protected + def instance + video_url.split('/w/').first + end + def url_looks_like_peertube? "/w/".in?(video_url) || "/videos/watch/".in?(video_url) end diff --git a/app/services/video/provider/vimeo.rb b/app/services/video/provider/vimeo.rb index f13183cbcc969ccc87a08254fc45b8bfd5a1a08f..0655c9c14491fe5fef8d1c76e0b710279eae96f7 100644 --- a/app/services/video/provider/vimeo.rb +++ b/app/services/video/provider/vimeo.rb @@ -1,12 +1,30 @@ class Video::Provider::Vimeo < Video::Provider::Default - DOMAINS = ['vimeo.com'] + DOMAINS = [ + 'vimeo.com', + 'player.vimeo.com', + 'vumbnail.com' + ] def identifier video_url.chomp('/').split('/').last end + def csp_domains + DOMAINS + end + + # https://vumbnail.com/621585396.jpg + def poster + "https://vumbnail.com/#{identifier}.jpg" + end + # https://help.vimeo.com/hc/en-us/articles/360001494447-Using-Player-Parameters def iframe_url "https://player.vimeo.com/video/#{identifier}" end + + # L'autoplay est à 1 uniquement parce que l'iframe n'est pas chargée + def embed_with_defaults + "#{iframe_url}?autoplay=1&quality=360p" + end end diff --git a/app/services/video/provider/youtube.rb b/app/services/video/provider/youtube.rb index 62153446e92eeade6e43a866d1eb707f95468b60..88c249d6eb97e8e99ff1bd30789e1ab8d32f1f7b 100644 --- a/app/services/video/provider/youtube.rb +++ b/app/services/video/provider/youtube.rb @@ -1,13 +1,44 @@ class Video::Provider::Youtube < Video::Provider::Default - DOMAINS = ['youtube.com', 'youtu.be'] + DOMAINS = [ + 'youtube.com', + 'www.youtube.com', + 'img.youtube.com', + 'youtu.be', + ] def identifier - video_url.include?('youtu.be') ? video_url.split('youtu.be/').last - : video_url.split('v=').last + video_url.include?('youtu.be') ? identifier_path + : identifier_param + end + + def csp_domains + DOMAINS + end + + # https://img.youtube.com/vi/XEEUOiTgJL0/hqdefault.jpg + def poster + "https://img.youtube.com/vi/#{identifier}/hqdefault.jpg" end # https://developers.google.com/youtube/player_parameters def iframe_url "https://www.youtube.com/embed/#{identifier}" end + + # L'autoplay est à 1 uniquement parce que l'iframe n'est pas chargée + def embed_with_defaults + "#{iframe_url}?autoplay=1&modestbranding=1&rel=0" + end + + protected + + def identifier_path + video_url.split('youtu.be/').last + end + + def identifier_param + uri = URI(video_url) + params = CGI::parse(uri.query) + params['v'].first + end end diff --git a/app/views/admin/communication/blocks/templates/gallery/_snippet.html.erb b/app/views/admin/communication/blocks/templates/gallery/_snippet.html.erb index 4e8f6a91f42256e7f6bb2c54932a20a6dff071d8..0156dba41f33cd98f656cfd2202d69288ad95321 100644 --- a/app/views/admin/communication/blocks/templates/gallery/_snippet.html.erb +++ b/app/views/admin/communication/blocks/templates/gallery/_snippet.html.erb @@ -1,10 +1,4 @@ <% block.template.elements.first(4).each do |element| %> - <% - component = element.image_component - blob = component.blob - next unless blob - image = blob.representable? ? blob.representation(resize: 'x180') - : blob - %> - <%= kamifusen_tag image, height: 90, alt: '', class: 'me-2' %> + <% blob = element.image_component.blob %> + <%= kamifusen_tag blob, height: 90, alt: '', class: 'me-2' if blob %> <% end %> diff --git a/app/views/admin/communication/blocks/templates/video/_static.html.erb b/app/views/admin/communication/blocks/templates/video/_static.html.erb index 592e98d2c612deb20fd6694ee070278c82d27947..ca9e871fe0a66bbfb8becad5cfb336a243a5c66a 100644 --- a/app/views/admin/communication/blocks/templates/video/_static.html.erb +++ b/app/views/admin/communication/blocks/templates/video/_static.html.erb @@ -3,5 +3,17 @@ <% if block.template.url.present? %> video_iframe: >- <%= block.template.video_iframe %> + video: + platform: "<%= block.template.video_platform %>" + identifier: "<%= block.template.video_identifier %>" + title: "<%= block.template.video_iframe_title %>" + poster: >- + <%= block.template.video_poster %> + embed: >- + <%= block.template.video_embed %> + embed_with_defaults: >- + <%= block.template.video_embed_with_defaults %> + iframe: >- + <%= block.template.video_iframe %> <% end %> <%= block_component_static block, :transcription %> diff --git a/app/views/admin/imports/show.html.erb b/app/views/admin/imports/show.html.erb index 468671382947ee3d91cc767a13ba3a41989cf728..813803e885efb8031f959642097314e867d93248 100644 --- a/app/views/admin/imports/show.html.erb +++ b/app/views/admin/imports/show.html.erb @@ -2,7 +2,14 @@ <div class="row"> <div class="col-md-6"> - <p><%= t('imports.initiated_by') %> <%= link_to_if can?(:read, @import.user), @import.user, [:admin, @import.user] %></p> + <p> + <%= t('imports.initiated_by') %> + <% if @import.user %> + <%= link_to_if can?(:read, @import.user), @import.user, [:admin, @import.user] %> + <% else %> + <%= t('imports.deleted_user') %> + <% end %> + </p> <% if @import.file.attached? %> <p><%= link_to t('download_with_size', size: number_to_human_size(@import.file.byte_size)), url_for(@import.file), class: button_classes %></p> <% end %> diff --git a/app/views/mailers/notifications/low_sms_credits.html.erb b/app/views/mailers/notifications/low_sms_credits.html.erb index 1407e04402742964ae4c37e023a62c8265f7cc82..3bf50e278f95e33042e45ecbf5ed5679a0cc77b7 100644 --- a/app/views/mailers/notifications/low_sms_credits.html.erb +++ b/app/views/mailers/notifications/low_sms_credits.html.erb @@ -1,3 +1,3 @@ -<%= t('mailers.notifications.low_sms_credits.body_1_html', credits: @credits) %> -<br> -<%= t('mailers.notifications.low_sms_credits.body_2_html', link: 'https://app.sendinblue.com/billing/addon/customize/sms') %> \ No newline at end of file +<p><%= t('mailers.notifications.low_sms_credits.body_1_html', credits: @credits) %></p> +<p><%= t('mailers.notifications.low_sms_credits.body_2_html', link: 'https://app.brevo.com/billing/account/customize/message-credits') %></p> +<p><%= t('mailers.yours') %></p> \ No newline at end of file diff --git a/app/views/mailers/notifications/new_registration.html.erb b/app/views/mailers/notifications/new_registration.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..14e3fdb0e88c595604e903ea26646c30f6e9adc8 --- /dev/null +++ b/app/views/mailers/notifications/new_registration.html.erb @@ -0,0 +1,3 @@ +<p><%= t('mailers.notifications.new_registration.body_1_html', username: @user.to_s) %></p> +<p><%= t('mailers.notifications.new_registration.body_2_html', link: admin_user_url(@user)) %></p> +<p><%= t('mailers.yours') %></p> \ No newline at end of file diff --git a/config/application.sample.yml b/config/application.sample.yml index 02c0dbb10cf5be4547248b15f85b179c9ffc50d5..1791af25fe9aa85b623cab112eca5bc8134255f2 100644 --- a/config/application.sample.yml +++ b/config/application.sample.yml @@ -6,8 +6,8 @@ BUGSNAG_RUBY_KEY: GITHUB_WEBSITE_THEME_BRANCH: GITHUB_WEBSITE_THEME_PATH: GITHUB_WEBSITE_THEME_REPOSITORY: -GITHUB_WEBSITE_TEMPLATE_REPOSITORY: -GITHUB_ACCESS_TOKEN: +GITHUB_WEBSITE_TEMPLATE_REPOSITORY: +GITHUB_ACCESS_TOKEN: MAIL_FROM_DEFAULT_ADDRESS: MAIL_FROM_DEFAULT_NAME: @@ -27,6 +27,8 @@ SCALEWAY_OS_ENDPOINT: SCALEWAY_OS_REGION: SCALEWAY_OS_SECRET_ACCESS_KEY: +KEYCDN_HOST: + SECRET_KEY_BASE: SEND_IN_BLUE_API_KEY: @@ -38,8 +40,8 @@ UNSPLASH_ACCESS_KEY: UNSPLASH_SECRET: PEXELS_API_KEY: -DEUXFLEURS_USER: -DEUXFLEURS_PASSWORD: +DEUXFLEURS_USER: +DEUXFLEURS_PASSWORD: MAINTENANCE: "false" @@ -53,4 +55,3 @@ TEST_GITLAB_BRANCH: TEST_GITLAB_ENDPOINT: TEST_GITLAB_TOKEN: TEST_GITLAB_REPOSITORY: - diff --git a/config/locales/en.yml b/config/locales/en.yml index ac7c7b70559d09d09cb9a0f4c1d20be96d6e4a6e..31e2c4cac44c1d5501ba4b893da02c834dbc74b3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -236,6 +236,7 @@ en: hello: "Hello %{name}!" home: Home imports: + deleted_user: Deleted user error_msg: "Line %{line}: %{error}" errors: Errors example_file_html: Download an <a href="%{link}" target="_blank">example file</a> @@ -276,10 +277,14 @@ en: body_1_html: "Warning, your SMS credits are low: %{credits} credits remaining!" body_2_html: "Click <a href=\"%{link}\" target=\"_blank\" style=\"color: #c72b43;\">here</a> to refull." subject: "Osuny - Low SMS Credits (%{credits})" + new_registration: + body_1_html: "A new user (%{username}) just registered." + body_2_html: "Click <a href=\"%{link}\" target=\"_blank\" style=\"color: #c72b43;\">here</a> to see the account." + subject: "A new user just registered: %{mail}" website_invalid_access_token: subject: "Expired access token for \"%{website}\"" text_line_1_html: "The access token used for the website \"%{website}\" has expired and does not allow the website to be updated anymore." - text_line_2_html: "To solve this issue, please fill in a new access token by clicking <a href=\"%{url}\">here</a>." + text_line_2_html: "To solve this issue, please fill in a new access token by clicking <a href=\"%{url}\" target=\"_blank\" style=\"color: #c72b43;\">here</a>." yours: Yours. menu: admin: Admin diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 0007a675cdd80c9f5c3d2b53ad370d1fdbbce4cf..304eeb6bad444599f70be388756f7fc3b8179454 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -236,6 +236,7 @@ fr: hello: "Bonjour %{name} !" home: Accueil imports: + deleted_user: Utilisateur supprimé error_msg: "Ligne %{line} : %{error}" errors: Erreurs example_file_html: Télécharger un <a href="%{link}" target="_blank">fichier d'exemple</a> @@ -276,10 +277,14 @@ fr: body_1_html: "Attention, vos crédits SMS sont bas : %{credits} crédits restants !" body_2_html: "Cliquez <a href=\"%{link}\" target=\"_blank\" style=\"color: #c72b43;\">ici</a> pour recharger le compte." subject: "Osuny - Credits SMS bas (%{credits})" + new_registration: + body_1_html: "Un nouvel utilisateur (%{username}) vient de s'enregistrer." + body_2_html: "Cliquez <a href=\"%{link}\" target=\"_blank\" style=\"color: #c72b43;\">ici</a> pour voir son compte." + subject: "Un nouvel utilisateur vient de s'inscrire : %{mail}" website_invalid_access_token: subject: Jeton d'accès expiré pour « %{website} » text_line_1_html: Le jeton d'accès utilisé pour le site « %{website} » a expiré et ne permet plus la mise à jour du site. - text_line_2_html: Pour résoudre ce problème, veuillez renseigner un nouveau jeton d'accès en cliquant <a href=\"%{url}\">ici</a>. + text_line_2_html: "Pour résoudre ce problème, veuillez renseigner un nouveau jeton d'accès en cliquant <a href=\"%{url}\" target=\"_blank\" style=\"color: #c72b43;\">ici</a>." yours: Cordialement. menu: admin: Admin diff --git a/db/migrate/20231013090313_change_imports_user_nil.rb b/db/migrate/20231013090313_change_imports_user_nil.rb new file mode 100644 index 0000000000000000000000000000000000000000..00404e4079ab0eca3cad3e48bbecc9a808d9e3cc --- /dev/null +++ b/db/migrate/20231013090313_change_imports_user_nil.rb @@ -0,0 +1,5 @@ +class ChangeImportsUserNil < ActiveRecord::Migration[7.0] + def change + change_column_null :imports, :user_id, true + end +end diff --git a/db/schema.rb b/db/schema.rb index eb300673cd28c521c85435321edf407fbb8057d0..58b3335aac4511ecb9544f6e3bd7a91f054448f9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do +ActiveRecord::Schema[7.0].define(version: 2023_10_13_090313) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -78,7 +78,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["criterion_id"], name: "index_administration_qualiopi_indicators_on_criterion_id" end - create_table "communication_block_headings", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_block_headings", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.string "about_type", null: false t.uuid "about_id", null: false @@ -106,8 +106,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.datetime "updated_at", null: false t.string "title" t.boolean "published", default: true - t.uuid "heading_id" t.uuid "communication_website_id" + t.uuid "heading_id" t.string "migration_identifier" t.index ["about_type", "about_id"], name: "index_communication_website_blocks_on_about" t.index ["communication_website_id"], name: "index_communication_blocks_on_communication_website_id" @@ -115,7 +115,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_communication_blocks_on_university_id" end - create_table "communication_extranet_connections", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_extranet_connections", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "extranet_id", null: false t.string "object_type" @@ -127,7 +127,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_communication_extranet_connections_on_university_id" end - create_table "communication_extranet_document_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_extranet_document_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "extranet_id", null: false t.uuid "university_id", null: false t.string "name" @@ -139,7 +139,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "extranet_document_categories_universities" end - create_table "communication_extranet_document_kinds", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_extranet_document_kinds", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "extranet_id", null: false t.uuid "university_id", null: false t.string "name" @@ -151,7 +151,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "extranet_document_kinds_universities" end - create_table "communication_extranet_documents", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_extranet_documents", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.uuid "university_id", null: false t.uuid "extranet_id", null: false @@ -167,7 +167,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_communication_extranet_documents_on_university_id" end - create_table "communication_extranet_post_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_extranet_post_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.string "slug" t.uuid "extranet_id", null: false @@ -179,7 +179,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_communication_extranet_post_categories_on_university_id" end - create_table "communication_extranet_posts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_extranet_posts", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "title" t.boolean "published", default: false t.datetime "published_at" @@ -229,11 +229,12 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.text "home_sentence" t.text "sass" t.text "css" + t.boolean "allow_experiences_modification", default: true t.index ["about_type", "about_id"], name: "index_communication_extranets_on_about" t.index ["university_id"], name: "index_communication_extranets_on_university_id" end - create_table "communication_website_agenda_events", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_agenda_events", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "title" t.text "summary" t.uuid "university_id", null: false @@ -294,7 +295,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["communication_website_post_id", "communication_website_category_id"], name: "post_category" end - create_table "communication_website_connections", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_connections", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.string "indirect_object_type", null: false @@ -389,7 +390,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_communication_website_pages_on_university_id" end - create_table "communication_website_permalinks", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| + create_table "communication_website_permalinks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "website_id", null: false t.string "about_type", null: false @@ -629,7 +630,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_education_schools_on_university_id" end - create_table "emergency_messages", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "emergency_messages", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id" t.string "name" t.string "role" @@ -650,7 +651,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.integer "kind" t.integer "status", default: 0 t.uuid "university_id", null: false - t.uuid "user_id", null: false + t.uuid "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["university_id"], name: "index_imports_on_university_id" @@ -665,7 +666,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.string "summernote_locale" end - create_table "research_hal_authors", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_hal_authors", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "docid" t.string "form_identifier" t.string "person_identifier" @@ -691,7 +692,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_person_id", "research_hal_author_id"], name: "hal_person_author" end - create_table "research_hal_publications", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_hal_publications", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "docid" t.jsonb "data" t.string "title" @@ -721,7 +722,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_person_id", "research_hal_publication_id"], name: "index_person_publication" end - create_table "research_journal_paper_kinds", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "research_journal_paper_kinds", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "journal_id", null: false t.string "title" @@ -882,7 +883,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["default_language_id"], name: "index_universities_on_default_language_id" end - create_table "university_apps", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_apps", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.uuid "university_id", null: false t.string "token" @@ -893,7 +894,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_university_apps_on_university_id" end - create_table "university_organization_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_organization_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.uuid "university_id", null: false t.datetime "created_at", null: false @@ -937,7 +938,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_university_organizations_on_university_id" end - create_table "university_organizations_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_organizations_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "organization_id", null: false t.uuid "category_id", null: false t.index ["category_id"], name: "index_university_organizations_categories_on_category_id" @@ -986,14 +987,14 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["user_id"], name: "index_university_people_on_user_id" end - create_table "university_people_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_people_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "person_id", null: false t.uuid "category_id", null: false t.index ["category_id"], name: "index_university_people_categories_on_category_id" t.index ["person_id"], name: "index_university_people_categories_on_person_id" end - create_table "university_person_categories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "university_person_categories", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.string "name" t.uuid "university_id", null: false t.datetime "created_at", null: false @@ -1042,7 +1043,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_06_145950) do t.index ["university_id"], name: "index_university_roles_on_university_id" end - create_table "user_favorites", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + create_table "user_favorites", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t| t.uuid "user_id", null: false t.string "about_type", null: false t.uuid "about_id", null: false diff --git a/test/fixtures/communication/extranets.yml b/test/fixtures/communication/extranets.yml index 5b00f559b78ac19b9a3871e2736923e92e325c4b..c4a72564511a4905256b44eff1b90d9ad95d76db 100644 --- a/test/fixtures/communication/extranets.yml +++ b/test/fixtures/communication/extranets.yml @@ -2,35 +2,34 @@ # # Table name: communication_extranets # -# id :uuid not null, primary key -# about_type :string indexed => [about_id] -# allow_experiences_modification :boolean default(TRUE) -# color :string -# cookies_policy :text -# css :text -# feature_alumni :boolean default(FALSE) -# feature_contacts :boolean default(FALSE) -# feature_jobs :boolean default(FALSE) -# feature_library :boolean default(FALSE) -# feature_posts :boolean default(FALSE) -# has_sso :boolean default(FALSE) -# home_sentence :text -# host :string -# name :string -# privacy_policy :text -# registration_contact :string -# sass :text -# sso_button_label :string -# sso_cert :text -# sso_mapping :jsonb -# sso_name_identifier_format :string -# sso_provider :integer default("saml") -# sso_target_url :string -# terms :text -# created_at :datetime not null -# updated_at :datetime not null -# about_id :uuid indexed => [about_type] -# university_id :uuid not null, indexed +# id :uuid not null, primary key +# about_type :string indexed => [about_id] +# color :string +# cookies_policy :text +# css :text +# feature_alumni :boolean default(FALSE) +# feature_contacts :boolean default(FALSE) +# feature_jobs :boolean default(FALSE) +# feature_library :boolean default(FALSE) +# feature_posts :boolean default(FALSE) +# has_sso :boolean default(FALSE) +# home_sentence :text +# host :string +# name :string +# privacy_policy :text +# registration_contact :string +# sass :text +# sso_button_label :string +# sso_cert :text +# sso_mapping :jsonb +# sso_name_identifier_format :string +# sso_provider :integer default("saml") +# sso_target_url :string +# terms :text +# created_at :datetime not null +# updated_at :datetime not null +# about_id :uuid indexed => [about_type] +# university_id :uuid not null, indexed # # Indexes # diff --git a/test/mailers/previews/notification_mailer_preview.rb b/test/mailers/previews/notification_mailer_preview.rb index d5557f836e051baa7aea245d9486f0f97b8b3848..eb971f394e801e755c5b26b742e1f169795c1a8f 100644 --- a/test/mailers/previews/notification_mailer_preview.rb +++ b/test/mailers/previews/notification_mailer_preview.rb @@ -23,5 +23,10 @@ class NotificationMailerPreview < BaseMailerPreview NotificationMailer.low_sms_credits(university, credits) end + # Preview this email at http://localhost:3000/rails/mailers/notification_mailer/new_registration + def new_registration + NotificationMailer.new_registration(university, user) + end + end diff --git a/test/services/video/provider_test.rb b/test/services/video/provider_test.rb index c5d4ab978dffc3e9388181801f7cd0e3cfcead50..d9cbd9b0ae87a54f4f9ab713e2b69646a4d8b3af 100644 --- a/test/services/video/provider_test.rb +++ b/test/services/video/provider_test.rb @@ -10,33 +10,33 @@ class Video::ProviderTest < ActiveSupport::TestCase def test_vimeo provider = Video::Provider.find('https://vimeo.com/248482251') assert_equal Video::Provider::Vimeo, provider.class - assert_equal "player.vimeo.com", provider.csp_domain + assert "player.vimeo.com".in?(provider.csp_domains) end def test_youtube provider = Video::Provider.find('https://www.youtube.com/watch?v=sN8Cq5HEBug') assert_equal Video::Provider::Youtube, provider.class - assert_equal "www.youtube.com", provider.csp_domain + assert "www.youtube.com".in?(provider.csp_domains) provider = Video::Provider.find('https://youtu.be/sN8Cq5HEBug') assert_equal Video::Provider::Youtube, provider.class - assert_equal "www.youtube.com", provider.csp_domain + assert "www.youtube.com".in?(provider.csp_domains) end def test_dailymotion provider = Video::Provider.find('https://www.dailymotion.com/video/x35l6b8') assert_equal Video::Provider::Dailymotion, provider.class - assert_equal "www.dailymotion.com", provider.csp_domain + assert "www.dailymotion.com".in?(provider.csp_domains) provider = Video::Provider.find('https://dai.ly/x35l6b8') assert_equal Video::Provider::Dailymotion, provider.class - assert_equal "www.dailymotion.com", provider.csp_domain + assert "www.dailymotion.com".in?(provider.csp_domains) end def test_peertube provider = Video::Provider.find('https://peertube.fr/w/1i848Qvi7Q3ytW2uPY8AxG') assert_equal Video::Provider::Peertube, provider.class - assert_equal "peertube.fr", provider.csp_domain + assert "peertube.fr".in?(provider.csp_domains) provider = Video::Provider.find('https://peertube.my.noesya.coop/w/qBMwAAULLA9oadFgbtdyq8') assert_equal Video::Provider::Peertube, provider.class - assert_equal "peertube.my.noesya.coop", provider.csp_domain + assert "peertube.my.noesya.coop".in?(provider.csp_domains) end end \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index c7d515077ce9a861f931e17189c3cecd9862a22a..fd10b729c4d949633b45a9b8949776f393257ade 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,105 +2,110 @@ # yarn lockfile v1 -"@babel/parser@^7.16.4": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2" - integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg== - -"@vue/compiler-core@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.45.tgz#d9311207d96f6ebd5f4660be129fb99f01ddb41b" - integrity sha512-rcMj7H+PYe5wBV3iYeUgbCglC+pbpN8hBLTJvRiK2eKQiWqu+fG9F+8sW99JdL4LQi7Re178UOxn09puSXvn4A== +"@babel/parser@^7.20.15", "@babel/parser@^7.21.3": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + +"@jridgewell/sourcemap-codec@^1.4.15": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@vue/compiler-core@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz#7fbf591c1c19e1acd28ffd284526e98b4f581128" + integrity sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g== dependencies: - "@babel/parser" "^7.16.4" - "@vue/shared" "3.2.45" + "@babel/parser" "^7.21.3" + "@vue/shared" "3.3.4" estree-walker "^2.0.2" - source-map "^0.6.1" + source-map-js "^1.0.2" -"@vue/compiler-dom@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.45.tgz#c43cc15e50da62ecc16a42f2622d25dc5fd97dce" - integrity sha512-tyYeUEuKqqZO137WrZkpwfPCdiiIeXYCcJ8L4gWz9vqaxzIQRccTSwSWZ/Axx5YR2z+LvpUbmPNXxuBU45lyRw== +"@vue/compiler-dom@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz#f56e09b5f4d7dc350f981784de9713d823341151" + integrity sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w== dependencies: - "@vue/compiler-core" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/compiler-core" "3.3.4" + "@vue/shared" "3.3.4" -"@vue/compiler-sfc@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.45.tgz#7f7989cc04ec9e7c55acd406827a2c4e96872c70" - integrity sha512-1jXDuWah1ggsnSAOGsec8cFjT/K6TMZ0sPL3o3d84Ft2AYZi2jWJgRMjw4iaK0rBfA89L5gw427H4n1RZQBu6Q== +"@vue/compiler-sfc@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz#b19d942c71938893535b46226d602720593001df" + integrity sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ== dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.45" - "@vue/compiler-dom" "3.2.45" - "@vue/compiler-ssr" "3.2.45" - "@vue/reactivity-transform" "3.2.45" - "@vue/shared" "3.2.45" + "@babel/parser" "^7.20.15" + "@vue/compiler-core" "3.3.4" + "@vue/compiler-dom" "3.3.4" + "@vue/compiler-ssr" "3.3.4" + "@vue/reactivity-transform" "3.3.4" + "@vue/shared" "3.3.4" estree-walker "^2.0.2" - magic-string "^0.25.7" + magic-string "^0.30.0" postcss "^8.1.10" - source-map "^0.6.1" + source-map-js "^1.0.2" -"@vue/compiler-ssr@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.45.tgz#bd20604b6e64ea15344d5b6278c4141191c983b2" - integrity sha512-6BRaggEGqhWht3lt24CrIbQSRD5O07MTmd+LjAn5fJj568+R9eUD2F7wMQJjX859seSlrYog7sUtrZSd7feqrQ== +"@vue/compiler-ssr@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz#9d1379abffa4f2b0cd844174ceec4a9721138777" + integrity sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ== dependencies: - "@vue/compiler-dom" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/compiler-dom" "3.3.4" + "@vue/shared" "3.3.4" -"@vue/reactivity-transform@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.45.tgz#07ac83b8138550c83dfb50db43cde1e0e5e8124d" - integrity sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ== +"@vue/reactivity-transform@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz#52908476e34d6a65c6c21cd2722d41ed8ae51929" + integrity sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw== dependencies: - "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.45" - "@vue/shared" "3.2.45" + "@babel/parser" "^7.20.15" + "@vue/compiler-core" "3.3.4" + "@vue/shared" "3.3.4" estree-walker "^2.0.2" - magic-string "^0.25.7" + magic-string "^0.30.0" -"@vue/reactivity@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.45.tgz#412a45b574de601be5a4a5d9a8cbd4dee4662ff0" - integrity sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A== +"@vue/reactivity@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.3.4.tgz#a27a29c6cd17faba5a0e99fbb86ee951653e2253" + integrity sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ== dependencies: - "@vue/shared" "3.2.45" + "@vue/shared" "3.3.4" -"@vue/runtime-core@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.45.tgz#7ad7ef9b2519d41062a30c6fa001ec43ac549c7f" - integrity sha512-gzJiTA3f74cgARptqzYswmoQx0fIA+gGYBfokYVhF8YSXjWTUA2SngRzZRku2HbGbjzB6LBYSbKGIaK8IW+s0A== +"@vue/runtime-core@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz#4bb33872bbb583721b340f3088888394195967d1" + integrity sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA== dependencies: - "@vue/reactivity" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/reactivity" "3.3.4" + "@vue/shared" "3.3.4" -"@vue/runtime-dom@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.45.tgz#1a2ef6ee2ad876206fbbe2a884554bba2d0faf59" - integrity sha512-cy88YpfP5Ue2bDBbj75Cb4bIEZUMM/mAkDMfqDTpUYVgTf/kuQ2VQ8LebuZ8k6EudgH8pYhsGWHlY0lcxlvTwA== +"@vue/runtime-dom@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz#992f2579d0ed6ce961f47bbe9bfe4b6791251566" + integrity sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ== dependencies: - "@vue/runtime-core" "3.2.45" - "@vue/shared" "3.2.45" - csstype "^2.6.8" - -"@vue/server-renderer@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.45.tgz#ca9306a0c12b0530a1a250e44f4a0abac6b81f3f" - integrity sha512-ebiMq7q24WBU1D6uhPK//2OTR1iRIyxjF5iVq/1a5I1SDMDyDu4Ts6fJaMnjrvD3MqnaiFkKQj+LKAgz5WIK3g== + "@vue/runtime-core" "3.3.4" + "@vue/shared" "3.3.4" + csstype "^3.1.1" + +"@vue/server-renderer@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz#ea46594b795d1536f29bc592dd0f6655f7ea4c4c" + integrity sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ== dependencies: - "@vue/compiler-ssr" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/compiler-ssr" "3.3.4" + "@vue/shared" "3.3.4" -"@vue/shared@3.2.45": - version "3.2.45" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.45.tgz#a3fffa7489eafff38d984e23d0236e230c818bc2" - integrity sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg== +"@vue/shared@3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780" + integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ== bootstrap-icons@^1.9.1: - version "1.10.2" - resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.10.2.tgz#6a5729e0475e007ed82d752225645e4e6fec48d7" - integrity sha512-PTPYadRn1AMGr+QTSxe4ZCc+Wzv9DGZxbi3lNse/dajqV31n2/wl/7NX78ZpkvFgRNmH4ogdIQPQmxAfhEV6nA== + version "1.11.1" + resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.11.1.tgz#79e32494871d8c98e9d14f4bcdc278cee9b1dafd" + integrity sha512-F0DDp7nKUX+x/QtpfRZ+XHFya60ng9nfdpdS59vDDfs4Uhuxp7zym/QavMsu/xx51txkoM9eVmpE7D08N35blw== bootstrap-print-css@^1.0.1: version "1.0.1" @@ -108,19 +113,19 @@ bootstrap-print-css@^1.0.1: integrity sha512-I73Cw87BaxCccTjo3qEbvn7KRb55msMxTuT7mpkAAY4Obq8iG9xCybdxnJqq+RrykLD79O3092AiJwaKiEex7w== codemirror@5: - version "5.65.12" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.12.tgz#294fdf097d10ac5b56a9e011a91eff252afc73ae" - integrity sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw== + version "5.65.15" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.15.tgz#66899278f44a7acde0eb641388cd563fe6dfbe19" + integrity sha512-YC4EHbbwQeubZzxLl5G4nlbLc1T21QTrKGaOal/Pkm9dVDMZXMH7+ieSPEOZCtO9I68i8/oteJKOxzHC2zR+0g== cropperjs@^1.5.12: - version "1.5.12" - resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50" - integrity sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw== + version "1.6.1" + resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.6.1.tgz#fd132021d93b824b1b0f2c2c3b763419fb792d89" + integrity sha512-F4wsi+XkDHCOMrHMYjrTEE4QBOrsHHN5/2VsVAaRq8P7E5z7xQpT75S+f/9WikmBEailas3+yo+6zPIomW+NOA== -csstype@^2.6.8: - version "2.6.21" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e" - integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w== +csstype@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== estree-walker@^2.0.2: version "2.0.2" @@ -132,17 +137,17 @@ jquery-cropper@^1.0.1: resolved "https://registry.yarnpkg.com/jquery-cropper/-/jquery-cropper-1.0.1.tgz#6ba9faf1c2c86c0ac3c648d40554ba53673113cf" integrity sha512-KGlY8b0IJQi2Bxe3lqMKmd5Z2Ce4GrnDE5O8Iciza9xCzXISkL6EqX/jFHwnLL1H6Q4FGjoRguuv3lxezsbKJQ== -magic-string@^0.25.7: - version "0.25.9" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== +magic-string@^0.30.0: + version "0.30.4" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.4.tgz#c2c683265fc18dda49b56fc7318d33ca0332c98c" + integrity sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg== dependencies: - sourcemap-codec "^1.4.8" + "@jridgewell/sourcemap-codec" "^1.4.15" -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== notyf@^3.10.0: version "3.10.0" @@ -155,11 +160,11 @@ picocolors@^1.0.0: integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== postcss@^8.1.10: - version "8.4.19" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc" - integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA== + version "8.4.31" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== dependencies: - nanoid "^3.3.4" + nanoid "^3.3.6" picocolors "^1.0.0" source-map-js "^1.0.2" @@ -178,28 +183,18 @@ source-map-js@^1.0.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sourcemap-codec@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - vue-draggable-next@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/vue-draggable-next/-/vue-draggable-next-2.1.1.tgz#49886da82f116d11b3e4df7674320fdacf5d7e04" - integrity sha512-f5lmA7t6LMaL4viR7dU30zzvqJzaKQs0ymL0Jy9UDT9uiZ2tXF3MzPzEvpTH2UODXZJkT+SnjeV1fXHMsgXLYA== + version "2.2.1" + resolved "https://registry.yarnpkg.com/vue-draggable-next/-/vue-draggable-next-2.2.1.tgz#adbe98c74610cca8f4eb63f92042681f96920451" + integrity sha512-EAMS1IRHF0kZO0o5PMOinsQsXIqsrKT1hKmbICxG3UEtn7zLFkLxlAtajcCcUTisNvQ6TtCB5COjD9a1raNADw== vue@^3.2.31: - version "3.2.45" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.45.tgz#94a116784447eb7dbd892167784619fef379b3c8" - integrity sha512-9Nx/Mg2b2xWlXykmCwiTUCWHbWIj53bnkizBxKai1g61f2Xit700A1ljowpTIM11e3uipOeiPcSqnmBg6gyiaA== + version "3.3.4" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.4.tgz#8ed945d3873667df1d0fcf3b2463ada028f88bd6" + integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw== dependencies: - "@vue/compiler-dom" "3.2.45" - "@vue/compiler-sfc" "3.2.45" - "@vue/runtime-dom" "3.2.45" - "@vue/server-renderer" "3.2.45" - "@vue/shared" "3.2.45" + "@vue/compiler-dom" "3.3.4" + "@vue/compiler-sfc" "3.3.4" + "@vue/runtime-dom" "3.3.4" + "@vue/server-renderer" "3.3.4" + "@vue/shared" "3.3.4"