From af8fe6e1e9d728a4af39941e1bde918b0ca7d204 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 19 Mar 2021 17:15:36 +0100 Subject: [PATCH 01/24] WIP (#15222) --- app/models/concerns/omniauthable.rb | 1 - app/models/user.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb index 79d671d10a..791a949110 100644 --- a/app/models/concerns/omniauthable.rb +++ b/app/models/concerns/omniauthable.rb @@ -68,7 +68,6 @@ module Omniauthable def user_params_from_auth(email, auth) { email: email || "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com", - password: Devise.friendly_token[0, 20], agreement: true, external: true, account_attributes: { diff --git a/app/models/user.rb b/app/models/user.rb index b4508c2ebb..5a149f573e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -468,7 +468,7 @@ class User < ApplicationRecord end def validate_email_dns? - email_changed? && !(Rails.env.test? || Rails.env.development?) + email_changed? && !external? && !(Rails.env.test? || Rails.env.development?) end def invite_text_required? From 8fa11b0e836fc2984fe8a771330d651fc7cc73cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczak?= Date: Fri, 19 Mar 2021 17:15:59 +0100 Subject: [PATCH 02/24] Add missing `en.notification_mailer.status.subject` (#15564) * Add missing `en.notification_mailer.status.subject` * Update en.yml --- config/locales/en.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index beb5683469..4d452af646 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1048,6 +1048,8 @@ en: body: 'Your status was boosted by %{name}:' subject: "%{name} boosted your status" title: New boost + status: + subject: "%{name} just posted" notifications: email_events: Events for e-mail notifications email_events_hint: 'Select events that you want to receive notifications for:' From 0ff4264c3e175226414a3782c91dde696132ed2e Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 20:22:49 +0100 Subject: [PATCH 03/24] Add missing push notification title for polls (#15929) --- config/locales/en.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 4d452af646..a6e54adf63 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1044,6 +1044,8 @@ en: body: 'You were mentioned by %{name} in:' subject: You were mentioned by %{name} title: New mention + poll: + title: A poll has ended reblog: body: 'Your status was boosted by %{name}:' subject: "%{name} boosted your status" From 39a490c70ebad27a1bd5e20c14722750756c79a4 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 20:23:08 +0100 Subject: [PATCH 04/24] Fix custom CSS when CDN_HOST is set (#15927) --- app/views/layouts/application.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 9501207e08..436024ee35 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -31,7 +31,7 @@ = stylesheet_link_tag '/inert.css', skip_pipeline: true, media: 'all', id: 'inert-style' - if Setting.custom_css.present? - = stylesheet_link_tag custom_css_path, media: 'all' + = stylesheet_link_tag custom_css_path, host: request.host, media: 'all' = yield :header_tags From 5d48402be1145201395e7fc297fe32a34638dd98 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 20:23:32 +0100 Subject: [PATCH 05/24] Fixing the hero widget (#15926) * Removing last-child padding conflicts with light theme in hero widget * Add missing background color to widget * Reset widget.scss to default * Hope this works Co-authored-by: koyu --- app/javascript/styles/mastodon-light/diff.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index d4290d7e61..8e6b0cdd5b 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -707,7 +707,6 @@ html { .public-account-bio, .hero-widget__text { background: $account-background-color; - border: 1px solid lighten($ui-base-color, 8%); } .header { From d023eefbcc1e6c2221a53484e58e61ac12eaa1d4 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 23:47:31 +0100 Subject: [PATCH 06/24] Fix push notification title for polls (#15931) --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index a6e54adf63..b364e92373 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1045,7 +1045,7 @@ en: subject: You were mentioned by %{name} title: New mention poll: - title: A poll has ended + subject: A poll by %{name} has ended reblog: body: 'Your status was boosted by %{name}:' subject: "%{name} boosted your status" From 051efed5edd544b4f88c63a1038274ae2db30038 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 23:48:47 +0100 Subject: [PATCH 07/24] Bypass MX validation for explicitly allowed domains (#15930) * Bypass MX validation for explicitly allowed domains This spares some lookups and prevent issues in some edge cases with local domains. * Add tests * Fix test --- app/validators/email_mx_validator.rb | 8 +++++++- spec/models/user_spec.rb | 2 +- spec/validators/email_mx_validator_spec.rb | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/validators/email_mx_validator.rb b/app/validators/email_mx_validator.rb index 9f70a1469a..dceef50290 100644 --- a/app/validators/email_mx_validator.rb +++ b/app/validators/email_mx_validator.rb @@ -10,7 +10,7 @@ class EmailMxValidator < ActiveModel::Validator if domain.blank? user.errors.add(:email, :invalid) - else + elsif !on_allowlist?(domain) ips, hostnames = resolve_mx(domain) if ips.empty? @@ -33,6 +33,12 @@ class EmailMxValidator < ActiveModel::Validator nil end + def on_allowlist?(domain) + return false if Rails.configuration.x.email_domains_whitelist.blank? + + Rails.configuration.x.email_domains_whitelist.include?(domain) + end + def resolve_mx(domain) hostnames = [] ips = [] diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index cded4c99bd..1dae435360 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -206,7 +206,7 @@ RSpec.describe User, type: :model do describe 'whitelist' do around(:each) do |example| - old_whitelist = Rails.configuration.x.email_whitelist + old_whitelist = Rails.configuration.x.email_domains_whitelist Rails.configuration.x.email_domains_whitelist = 'mastodon.space' diff --git a/spec/validators/email_mx_validator_spec.rb b/spec/validators/email_mx_validator_spec.rb index 48e17a4f10..550e91996b 100644 --- a/spec/validators/email_mx_validator_spec.rb +++ b/spec/validators/email_mx_validator_spec.rb @@ -6,6 +6,24 @@ describe EmailMxValidator do describe '#validate' do let(:user) { double(email: 'foo@example.com', errors: double(add: nil)) } + it 'does not add errors if there are no DNS records for an e-mail domain that is explicitly allowed' do + old_whitelist = Rails.configuration.x.email_domains_whitelist + Rails.configuration.x.email_domains_whitelist = 'example.com' + + resolver = double + + allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([]) + allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([]) + allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([]) + allow(resolver).to receive(:timeouts=).and_return(nil) + allow(Resolv::DNS).to receive(:open).and_yield(resolver) + + subject.validate(user) + expect(user.errors).to_not have_received(:add) + + Rails.configuration.x.email_domains_whitelist = old_whitelist + end + it 'adds an error if there are no DNS records for the e-mail domain' do resolver = double From 876840e9efceb4cde0af92e2a0f5d7afe906b5e9 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 23:48:59 +0100 Subject: [PATCH 08/24] Fix brakeman warning (#15870) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As far as I understand, the brakeman warning was a false-positive as `content_tag` properly escapes untrusted HTML. Furthermore, the interpolated string values are built from the “username” part of accounts, which is restricted to a small subset of ASCII that precludes any XML entity or HTML code. This proposed change should be functionally equivalent to the current code, however it is slightly more robust, it's more idiomatic, and Brakeman will stop complaining about it. --- .../admin/action_logs/_action_log.html.haml | 2 +- app/views/admin/reports/_action_log.html.haml | 2 +- config/locales/en.yml | 80 +++++++++---------- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/app/views/admin/action_logs/_action_log.html.haml b/app/views/admin/action_logs/_action_log.html.haml index 59905f3418..a2fce2d114 100644 --- a/app/views/admin/action_logs/_action_log.html.haml +++ b/app/views/admin/action_logs/_action_log.html.haml @@ -4,6 +4,6 @@ = image_tag action_log.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar' .log-entry__content .log-entry__title - = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')).html_safe + = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}_html", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')) .log-entry__timestamp %time.formatted{ datetime: action_log.created_at.iso8601 } diff --git a/app/views/admin/reports/_action_log.html.haml b/app/views/admin/reports/_action_log.html.haml index 024078eb9a..0f7d058679 100644 --- a/app/views/admin/reports/_action_log.html.haml +++ b/app/views/admin/reports/_action_log.html.haml @@ -1,6 +1,6 @@ .speech-bubble.positive .speech-bubble__bubble - = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')).html_safe + = t("admin.action_logs.actions.#{action_log.action}_#{action_log.target_type.underscore}_html", name: content_tag(:span, action_log.account.username, class: 'username'), target: content_tag(:span, log_target(action_log), class: 'target')) .speech-bubble__owner = admin_account_link_to(action_log.account) %time.formatted{ datetime: action_log.created_at.iso8601 }= l action_log.created_at diff --git a/config/locales/en.yml b/config/locales/en.yml index b364e92373..14f1a08e4b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -261,46 +261,46 @@ en: update_domain_block: Update Domain Block update_status: Update Status actions: - assigned_to_self_report: "%{name} assigned report %{target} to themselves" - change_email_user: "%{name} changed the e-mail address of user %{target}" - confirm_user: "%{name} confirmed e-mail address of user %{target}" - create_account_warning: "%{name} sent a warning to %{target}" - create_announcement: "%{name} created new announcement %{target}" - create_custom_emoji: "%{name} uploaded new emoji %{target}" - create_domain_allow: "%{name} allowed federation with domain %{target}" - create_domain_block: "%{name} blocked domain %{target}" - create_email_domain_block: "%{name} blocked e-mail domain %{target}" - create_ip_block: "%{name} created rule for IP %{target}" - demote_user: "%{name} demoted user %{target}" - destroy_announcement: "%{name} deleted announcement %{target}" - destroy_custom_emoji: "%{name} destroyed emoji %{target}" - destroy_domain_allow: "%{name} disallowed federation with domain %{target}" - destroy_domain_block: "%{name} unblocked domain %{target}" - destroy_email_domain_block: "%{name} unblocked e-mail domain %{target}" - destroy_ip_block: "%{name} deleted rule for IP %{target}" - destroy_status: "%{name} removed status by %{target}" - disable_2fa_user: "%{name} disabled two factor requirement for user %{target}" - disable_custom_emoji: "%{name} disabled emoji %{target}" - disable_user: "%{name} disabled login for user %{target}" - enable_custom_emoji: "%{name} enabled emoji %{target}" - enable_user: "%{name} enabled login for user %{target}" - memorialize_account: "%{name} turned %{target}'s account into a memoriam page" - promote_user: "%{name} promoted user %{target}" - remove_avatar_user: "%{name} removed %{target}'s avatar" - reopen_report: "%{name} reopened report %{target}" - reset_password_user: "%{name} reset password of user %{target}" - resolve_report: "%{name} resolved report %{target}" - sensitive_account: "%{name} marked %{target}'s media as sensitive" - silence_account: "%{name} silenced %{target}'s account" - suspend_account: "%{name} suspended %{target}'s account" - unassigned_report: "%{name} unassigned report %{target}" - unsensitive_account: "%{name} unmarked %{target}'s media as sensitive" - unsilence_account: "%{name} unsilenced %{target}'s account" - unsuspend_account: "%{name} unsuspended %{target}'s account" - update_announcement: "%{name} updated announcement %{target}" - update_custom_emoji: "%{name} updated emoji %{target}" - update_domain_block: "%{name} updated domain block for %{target}" - update_status: "%{name} updated status by %{target}" + assigned_to_self_report_html: "%{name} assigned report %{target} to themselves" + change_email_user_html: "%{name} changed the e-mail address of user %{target}" + confirm_user_html: "%{name} confirmed e-mail address of user %{target}" + create_account_warning_html: "%{name} sent a warning to %{target}" + create_announcement_html: "%{name} created new announcement %{target}" + create_custom_emoji_html: "%{name} uploaded new emoji %{target}" + create_domain_allow_html: "%{name} allowed federation with domain %{target}" + create_domain_block_html: "%{name} blocked domain %{target}" + create_email_domain_block_html: "%{name} blocked e-mail domain %{target}" + create_ip_block_html: "%{name} created rule for IP %{target}" + demote_user_html: "%{name} demoted user %{target}" + destroy_announcement_html: "%{name} deleted announcement %{target}" + destroy_custom_emoji_html: "%{name} destroyed emoji %{target}" + destroy_domain_allow_html: "%{name} disallowed federation with domain %{target}" + destroy_domain_block_html: "%{name} unblocked domain %{target}" + destroy_email_domain_block_html: "%{name} unblocked e-mail domain %{target}" + destroy_ip_block_html: "%{name} deleted rule for IP %{target}" + destroy_status_html: "%{name} removed status by %{target}" + disable_2fa_user_html: "%{name} disabled two factor requirement for user %{target}" + disable_custom_emoji_html: "%{name} disabled emoji %{target}" + disable_user_html: "%{name} disabled login for user %{target}" + enable_custom_emoji_html: "%{name} enabled emoji %{target}" + enable_user_html: "%{name} enabled login for user %{target}" + memorialize_account_html: "%{name} turned %{target}'s account into a memoriam page" + promote_user_html: "%{name} promoted user %{target}" + remove_avatar_user_html: "%{name} removed %{target}'s avatar" + reopen_report_html: "%{name} reopened report %{target}" + reset_password_user_html: "%{name} reset password of user %{target}" + resolve_report_html: "%{name} resolved report %{target}" + sensitive_account_html: "%{name} marked %{target}'s media as sensitive" + silence_account_html: "%{name} silenced %{target}'s account" + suspend_account_html: "%{name} suspended %{target}'s account" + unassigned_report_html: "%{name} unassigned report %{target}" + unsensitive_account_html: "%{name} unmarked %{target}'s media as sensitive" + unsilence_account_html: "%{name} unsilenced %{target}'s account" + unsuspend_account_html: "%{name} unsuspended %{target}'s account" + update_announcement_html: "%{name} updated announcement %{target}" + update_custom_emoji_html: "%{name} updated emoji %{target}" + update_domain_block_html: "%{name} updated domain block for %{target}" + update_status_html: "%{name} updated status by %{target}" deleted_status: "(deleted status)" empty: No logs found. filter_by_action: Filter by action From 46d3d3169edad116aba82ba41c08111e18cd3769 Mon Sep 17 00:00:00 2001 From: Sandro Date: Sat, 20 Mar 2021 21:21:57 +0100 Subject: [PATCH 09/24] Docker: Use precompiled jemalloc, format, apply hadolint suggestions (#10823) * Format, apply hadolint suggestions, little nitpicks * Use pre compiled jemalloc * Use tini from package repository --- Dockerfile | 71 +++++++++++++++++------------------------------------- 1 file changed, 22 insertions(+), 49 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1b89a97b74..3b3d6dfcd1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:20.04 as build-dep # Use bash for the shell -SHELL ["/usr/bin/bash", "-c"] +SHELL ["/bin/bash", "-c"] # Install Node v12 (LTS) ENV NODE_VER="12.21.0" @@ -17,35 +17,19 @@ RUN ARCH= && \ *) echo "unsupported architecture"; exit 1 ;; \ esac && \ echo "Etc/UTC" > /etc/localtime && \ - apt update && \ - apt -y install wget python && \ + apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates wget python && \ cd ~ && \ - wget https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-linux-$ARCH.tar.gz && \ + wget -q https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-linux-$ARCH.tar.gz && \ tar xf node-v$NODE_VER-linux-$ARCH.tar.gz && \ rm node-v$NODE_VER-linux-$ARCH.tar.gz && \ mv node-v$NODE_VER-linux-$ARCH /opt/node -# Install jemalloc -ENV JE_VER="5.2.1" -RUN apt update && \ - apt -y install make autoconf gcc g++ && \ - cd ~ && \ - wget https://github.com/jemalloc/jemalloc/archive/$JE_VER.tar.gz && \ - tar xf $JE_VER.tar.gz && \ - cd jemalloc-$JE_VER && \ - ./autogen.sh && \ - ./configure --prefix=/opt/jemalloc && \ - make -j$(nproc) > /dev/null && \ - make install_bin install_include install_lib && \ - cd .. && rm -rf jemalloc-$JE_VER $JE_VER.tar.gz - # Install Ruby ENV RUBY_VER="2.7.2" -ENV CPPFLAGS="-I/opt/jemalloc/include" -ENV LDFLAGS="-L/opt/jemalloc/lib/" -RUN apt update && \ - apt -y install build-essential \ - bison libyaml-dev libgdbm-dev libreadline-dev \ +RUN apt-get update && \ + apt-get install -y --no-install-recommends build-essential \ + bison libyaml-dev libgdbm-dev libreadline-dev libjemalloc-dev \ libncurses5-dev libffi-dev zlib1g-dev libssl-dev && \ cd ~ && \ wget https://cache.ruby-lang.org/pub/ruby/${RUBY_VER%.*}/ruby-$RUBY_VER.tar.gz && \ @@ -55,17 +39,16 @@ RUN apt update && \ --with-jemalloc \ --with-shared \ --disable-install-doc && \ - ln -s /opt/jemalloc/lib/* /usr/lib/ && \ - make -j$(nproc) > /dev/null && \ + make -j"$(nproc)" > /dev/null && \ make install && \ - cd .. && rm -rf ruby-$RUBY_VER.tar.gz ruby-$RUBY_VER + rm -rf ../ruby-$RUBY_VER.tar.gz ../ruby-$RUBY_VER ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin" RUN npm install -g yarn && \ gem install bundler && \ - apt update && \ - apt -y install git libicu-dev libidn11-dev \ + apt-get update && \ + apt-get install -y --no-install-recommends git libicu-dev libidn11-dev \ libpq-dev libprotobuf-dev protobuf-compiler COPY Gemfile* package.json yarn.lock /opt/mastodon/ @@ -73,7 +56,7 @@ COPY Gemfile* package.json yarn.lock /opt/mastodon/ RUN cd /opt/mastodon && \ bundle config set deployment 'true' && \ bundle config set without 'development test' && \ - bundle install -j$(nproc) && \ + bundle install -j"$(nproc)" && \ yarn install --pure-lockfile FROM ubuntu:20.04 @@ -81,7 +64,6 @@ FROM ubuntu:20.04 # Copy over all the langs needed for runtime COPY --from=build-dep /opt/node /opt/node COPY --from=build-dep /opt/ruby /opt/ruby -COPY --from=build-dep /opt/jemalloc /opt/jemalloc # Add more PATHs to the PATH ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin:/opt/mastodon/bin" @@ -89,35 +71,26 @@ ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin:/opt/mastodon/bin" # Create the mastodon user ARG UID=991 ARG GID=991 -RUN apt update && \ +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN apt-get update && \ echo "Etc/UTC" > /etc/localtime && \ - ln -s /opt/jemalloc/lib/* /usr/lib/ && \ - apt install -y whois wget && \ + apt-get install -y --no-install-recommends whois wget && \ addgroup --gid $GID mastodon && \ useradd -m -u $UID -g $GID -d /opt/mastodon mastodon && \ - echo "mastodon:`head /dev/urandom | tr -dc A-Za-z0-9 | head -c 24 | mkpasswd -s -m sha-256`" | chpasswd + echo "mastodon:$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 24 | mkpasswd -s -m sha-256)" | chpasswd && \ + rm -rf /var/lib/apt/lists/* # Install mastodon runtime deps -RUN apt -y --no-install-recommends install \ - libssl1.1 libpq5 imagemagick ffmpeg \ +RUN apt-get update && \ + apt-get -y --no-install-recommends install \ + libssl1.1 libpq5 imagemagick ffmpeg libjemalloc2 \ libicu66 libprotobuf17 libidn11 libyaml-0-2 \ - file ca-certificates tzdata libreadline8 && \ - apt -y install gcc && \ + file ca-certificates tzdata libreadline8 gcc tini && \ ln -s /opt/mastodon /mastodon && \ gem install bundler && \ rm -rf /var/cache && \ rm -rf /var/lib/apt/lists/* -# Add tini -ENV TINI_VERSION="0.19.0" -RUN dpkgArch="$(dpkg --print-architecture)" && \ - ARCH=$dpkgArch && \ - wget https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-$ARCH \ - https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-$ARCH.sha256sum && \ - cat tini-$ARCH.sha256sum | sha256sum -c - && \ - mv tini-$ARCH /tini && rm tini-$ARCH.sha256sum && \ - chmod +x /tini - # Copy over mastodon source, and dependencies from building, and set permissions COPY --chown=mastodon:mastodon . /opt/mastodon COPY --from=build-dep --chown=mastodon:mastodon /opt/mastodon /opt/mastodon @@ -140,5 +113,5 @@ RUN cd ~ && \ # Set the work dir and the container entry point WORKDIR /opt/mastodon -ENTRYPOINT ["/tini", "--"] +ENTRYPOINT ["/usr/bin/tini", "--"] EXPOSE 3000 4000 From 829a598f1d8493a597dc655887e306b21bbbe0d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:35:46 +0100 Subject: [PATCH 10/24] Bump sidekiq-unique-jobs from 7.0.4 to 7.0.7 (#15944) Bumps [sidekiq-unique-jobs](https://github.com/mhenrixon/sidekiq-unique-jobs) from 7.0.4 to 7.0.7. - [Release notes](https://github.com/mhenrixon/sidekiq-unique-jobs/releases) - [Changelog](https://github.com/mhenrixon/sidekiq-unique-jobs/blob/master/CHANGELOG.md) - [Commits](https://github.com/mhenrixon/sidekiq-unique-jobs/compare/v7.0.4...v7.0.7) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 106c13554c..f35a346837 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -108,7 +108,7 @@ GEM msgpack (~> 1.0) brakeman (4.10.1) browser (4.2.0) - brpoplpush-redis_script (0.1.1) + brpoplpush-redis_script (0.1.2) concurrent-ruby (~> 1.0, >= 1.0.5) redis (>= 1.0, <= 5.0) builder (3.2.4) @@ -573,8 +573,8 @@ GEM sidekiq (>= 3) thwait tilt (>= 1.4.0) - sidekiq-unique-jobs (7.0.4) - brpoplpush-redis_script (> 0.0.0, <= 2.0.0) + sidekiq-unique-jobs (7.0.7) + brpoplpush-redis_script (> 0.1.1, <= 2.0.0) concurrent-ruby (~> 1.0, >= 1.0.5) sidekiq (>= 5.0, < 7.0) thor (>= 0.20, < 2.0) From 472d5005c0ee1dcbb17d942e789ca18f960ceaa4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:36:13 +0100 Subject: [PATCH 11/24] Bump blurhash from 0.1.4 to 0.1.5 (#15942) Bumps [blurhash](https://github.com/Gargron/blurhash) from 0.1.4 to 0.1.5. - [Release notes](https://github.com/Gargron/blurhash/releases) - [Commits](https://github.com/Gargron/blurhash/commits/v0.1.5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f35a346837..222eccdc31 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -102,8 +102,8 @@ GEM bindata (2.4.8) binding_of_caller (1.0.0) debug_inspector (>= 0.0.1) - blurhash (0.1.4) - ffi (~> 1.10.0) + blurhash (0.1.5) + ffi (~> 1.14) bootsnap (1.6.0) msgpack (~> 1.0) brakeman (4.10.1) @@ -222,7 +222,7 @@ GEM faraday-net_http (1.0.1) fast_blank (1.0.0) fastimage (2.2.3) - ffi (1.10.0) + ffi (1.14.2) ffi-compiler (1.0.1) ffi (>= 1.0.0) rake From 64942fa31d04a9fb8d488aa0eb2484207d7d2b96 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:37:51 +0100 Subject: [PATCH 12/24] Bump sidekiq from 6.1.3 to 6.2.0 (#15943) Bumps [sidekiq](https://github.com/mperham/sidekiq) from 6.1.3 to 6.2.0. - [Release notes](https://github.com/mperham/sidekiq/releases) - [Changelog](https://github.com/mperham/sidekiq/blob/master/Changes.md) - [Commits](https://github.com/mperham/sidekiq/compare/v6.1.3...v6.2.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index c3f50ec30c..7d75f09027 100644 --- a/Gemfile +++ b/Gemfile @@ -83,7 +83,7 @@ gem 'rqrcode', '~> 1.2' gem 'ruby-progressbar', '~> 1.11' gem 'sanitize', '~> 5.2' gem 'scenic', '~> 1.5' -gem 'sidekiq', '~> 6.1' +gem 'sidekiq', '~> 6.2' gem 'sidekiq-scheduler', '~> 3.0' gem 'sidekiq-unique-jobs', '~> 7.0' gem 'sidekiq-bulk', '~>0.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 222eccdc31..4ca2154dad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -560,7 +560,7 @@ GEM railties (>= 4.0.0) securecompare (1.0.0) semantic_range (2.3.0) - sidekiq (6.1.3) + sidekiq (6.2.0) connection_pool (>= 2.2.2) rack (~> 2.0) redis (>= 4.2.0) @@ -783,7 +783,7 @@ DEPENDENCIES ruby-progressbar (~> 1.11) sanitize (~> 5.2) scenic (~> 1.5) - sidekiq (~> 6.1) + sidekiq (~> 6.2) sidekiq-bulk (~> 0.2.0) sidekiq-scheduler (~> 3.0) sidekiq-unique-jobs (~> 7.0) From b5288798a8a25417b0bf6d4620dcaaef9db36f31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:38:23 +0100 Subject: [PATCH 13/24] Bump ox from 2.14.3 to 2.14.4 (#15941) Bumps [ox](https://github.com/ohler55/ox) from 2.14.3 to 2.14.4. - [Release notes](https://github.com/ohler55/ox/releases) - [Changelog](https://github.com/ohler55/ox/blob/develop/CHANGELOG.md) - [Commits](https://github.com/ohler55/ox/compare/v2.14.3...v2.14.4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4ca2154dad..c718dcd182 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -392,7 +392,7 @@ GEM openssl (2.2.0) openssl-signature_algorithm (0.4.0) orm_adapter (0.5.0) - ox (2.14.3) + ox (2.14.4) paperclip (6.0.0) activemodel (>= 4.2.0) activesupport (>= 4.2.0) From 229968bdff05838b0eea30a4f035995f0895f92e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:38:54 +0100 Subject: [PATCH 14/24] Bump rspec-rails from 5.0.0 to 5.0.1 (#15939) Bumps [rspec-rails](https://github.com/rspec/rspec-rails) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/rspec/rspec-rails/releases) - [Changelog](https://github.com/rspec/rspec-rails/blob/main/Changelog.md) - [Commits](https://github.com/rspec/rspec-rails/compare/v5.0.0...v5.0.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c718dcd182..690b270dcc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -514,7 +514,7 @@ GEM rspec-mocks (3.10.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) - rspec-rails (5.0.0) + rspec-rails (5.0.1) actionpack (>= 5.2) activesupport (>= 5.2) railties (>= 5.2) From 6b5cda6ec310bd07d70740baed2ecd427d2c3d19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:39:19 +0100 Subject: [PATCH 15/24] Bump css-loader from 5.1.2 to 5.1.3 (#15940) Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 5.1.2 to 5.1.3. - [Release notes](https://github.com/webpack-contrib/css-loader/releases) - [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/css-loader/compare/v5.1.2...v5.1.3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fd766cc8c1..f68436721b 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "color-blend": "^3.0.1", "compression-webpack-plugin": "^6.1.1", "cross-env": "^7.0.3", - "css-loader": "^5.1.2", + "css-loader": "^5.1.3", "cssnano": "^4.1.10", "detect-passive-events": "^2.0.3", "dotenv": "^8.2.0", diff --git a/yarn.lock b/yarn.lock index 3cc2c7f83e..f0e6c8ed34 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3373,10 +3373,10 @@ css-list-helpers@^1.0.1: dependencies: tcomb "^2.5.0" -css-loader@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.2.tgz#b93dba498ec948b543b49d4fab5017205d4f5c3e" - integrity sha512-T7vTXHSx0KrVEg/xjcl7G01RcVXpcw4OELwDPvkr7izQNny85A84dK3dqrczuEfBcu7Yg7mdTjJLSTibRUoRZg== +css-loader@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.3.tgz#87f6fc96816b20debe3cf682f85c7e56a963d0d1" + integrity sha512-CoPZvyh8sLiGARK3gqczpfdedbM74klGWurF2CsNZ2lhNaXdLIUks+3Mfax3WBeRuHoglU+m7KG/+7gY6G4aag== dependencies: camelcase "^6.2.0" cssesc "^3.0.0" From 1b3ebcfe53e29e4a9e425b466079081aa92990df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 07:39:39 +0100 Subject: [PATCH 16/24] Bump aws-sdk-s3 from 1.91.0 to 1.92.0 (#15938) Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.91.0 to 1.92.0. - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-ruby/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 7d75f09027..98af92deff 100644 --- a/Gemfile +++ b/Gemfile @@ -17,7 +17,7 @@ gem 'makara', '~> 0.5' gem 'pghero', '~> 2.8' gem 'dotenv-rails', '~> 2.7' -gem 'aws-sdk-s3', '~> 1.91', require: false +gem 'aws-sdk-s3', '~> 1.92', require: false gem 'fog-core', '<= 2.1.0' gem 'fog-openstack', '~> 0.3', require: false gem 'paperclip', '~> 6.0' diff --git a/Gemfile.lock b/Gemfile.lock index 690b270dcc..1a67f893d6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,7 +79,7 @@ GEM cocaine (~> 0.5.3) awrence (1.1.1) aws-eventstream (1.1.1) - aws-partitions (1.432.0) + aws-partitions (1.434.0) aws-sdk-core (3.113.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) @@ -88,7 +88,7 @@ GEM aws-sdk-kms (1.43.0) aws-sdk-core (~> 3, >= 3.112.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.91.0) + aws-sdk-s3 (1.92.0) aws-sdk-core (~> 3, >= 3.112.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) @@ -681,7 +681,7 @@ DEPENDENCIES active_record_query_trace (~> 1.8) addressable (~> 2.7) annotate (~> 3.1) - aws-sdk-s3 (~> 1.91) + aws-sdk-s3 (~> 1.92) better_errors (~> 2.9) binding_of_caller (~> 1.0) blurhash (~> 0.1) From c3aef491d66aec743a3a53e934a494f653745b61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 15:41:47 +0900 Subject: [PATCH 17/24] Bump react-select from 3.2.0 to 4.0.2 (#15624) * Bump react-select from 3.2.0 to 4.0.2 Bumps [react-select](https://github.com/JedWatson/react-select) from 3.2.0 to 4.0.2. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@3.2.0...react-select@4.0.2) Signed-off-by: dependabot[bot] * Add cacheKey to NonceProvider for react-select Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Yamagishi Kazutoshi --- .../components/column_settings.js | 2 +- package.json | 2 +- yarn.lock | 201 ++++++++++-------- 3 files changed, 109 insertions(+), 96 deletions(-) diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js index 27300f020d..de1127b0d5 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js +++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js @@ -59,7 +59,7 @@ class ColumnSettings extends React.PureComponent { {this.modeLabel(mode)} - + Date: Wed, 24 Mar 2021 09:37:41 +0100 Subject: [PATCH 18/24] Switch from deprecated ClusterWS/cws to ws package (#15932) * Switch from deprecated ClusterWS/cws to ws package Fixes #15184 Co-authored-by: Edho Arief * Make bufferutil and utf-8-validate optional dependencies Co-authored-by: Edho Arief --- package.json | 8 ++++++-- streaming/index.js | 22 +++++++++++++++++++--- yarn.lock | 29 ++++++++++++++++++++++++----- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 1a6eb8001e..a8896ecfb4 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,6 @@ "@babel/preset-env": "^7.13.10", "@babel/preset-react": "^7.12.13", "@babel/runtime": "^7.13.10", - "@clusterws/cws": "^3.0.0", "@gamestdio/websocket": "^0.3.2", "@github/webauthn-json": "^0.5.7", "@rails/ujs": "^6.1.3", @@ -169,7 +168,8 @@ "webpack-bundle-analyzer": "^4.4.0", "webpack-cli": "^3.3.12", "webpack-merge": "^5.7.3", - "wicg-inert": "^3.1.1" + "wicg-inert": "^3.1.1", + "ws": "^7.4.4" }, "devDependencies": { "@testing-library/jest-dom": "^5.11.9", @@ -191,5 +191,9 @@ }, "resolutions": { "kind-of": "^6.0.3" + }, + "optionalDependencies": { + "bufferutil": "^4.0.3", + "utf-8-validate": "^5.0.4" } } diff --git a/streaming/index.js b/streaming/index.js index 3279bd94eb..c50d355831 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -9,9 +9,9 @@ const redis = require('redis'); const pg = require('pg'); const log = require('npmlog'); const url = require('url'); -const { WebSocketServer } = require('@clusterws/cws'); const uuid = require('uuid'); const fs = require('fs'); +const WebSocket = require('ws'); const env = process.env.NODE_ENV || 'development'; const alwaysRequireAuth = process.env.LIMITED_FEDERATION_MODE === 'true' || process.env.WHITELIST_MODE === 'true' || process.env.AUTHORIZED_FETCH === 'true'; @@ -766,7 +766,7 @@ const startWorker = (workerId) => { }); }); - const wss = new WebSocketServer({ server, verifyClient: wsVerifyClient }); + const wss = new WebSocket.Server({ server, verifyClient: wsVerifyClient }); /** * @typedef StreamParams @@ -999,6 +999,12 @@ const startWorker = (workerId) => { req.requestId = uuid.v4(); req.remoteAddress = ws._socket.remoteAddress; + ws.isAlive = true; + + ws.on('pong', () => { + ws.isAlive = true; + }); + /** * @type {WebSocketSession} */ @@ -1048,7 +1054,17 @@ const startWorker = (workerId) => { } }); - wss.startAutoPing(30000); + setInterval(() => { + wss.clients.forEach(ws => { + if (ws.isAlive === false) { + ws.terminate(); + return; + } + + ws.isAlive = false; + ws.ping('', false, true); + }); + }, 30000); attachServerWithConfig(server, address => { log.info(`Worker ${workerId} now listening on ${address}`); diff --git a/yarn.lock b/yarn.lock index 236dd346af..1adbca9161 100644 --- a/yarn.lock +++ b/yarn.lock @@ -991,11 +991,6 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@clusterws/cws@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@clusterws/cws/-/cws-3.0.0.tgz#518fc8e7d9066e220f6f6aef3158cc14d5a1e98e" - integrity sha512-6RO7IUbSlTO3l8XPN/9g21YGPF4HjfkidDzchkP0h6iwq5jYtji+KUCgyxcSYiuN7aWu8nGJDjBer7XJilPnOg== - "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -2623,6 +2618,13 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +bufferutil@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.3.tgz#66724b756bed23cd7c28c4d306d7994f9943cc6b" + integrity sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw== + dependencies: + node-gyp-build "^4.2.0" + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -7370,6 +7372,11 @@ node-forge@^0.10.0: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-gyp-build@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" + integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -10980,6 +10987,13 @@ user-home@^2.0.0: dependencies: os-homedir "^1.0.0" +utf-8-validate@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.4.tgz#72a1735983ddf7a05a43a9c6b67c5ce1c910f9b8" + integrity sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q== + dependencies: + node-gyp-build "^4.2.0" + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -11461,6 +11475,11 @@ ws@^7.2.3, ws@^7.3.1: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7" integrity sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ== +ws@^7.4.4: + version "7.4.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" + integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== + xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" From 034f37b85a716872f78a72048a5a225cdcaa840a Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 24 Mar 2021 10:19:07 +0100 Subject: [PATCH 19/24] Fix compose form behavior in mobile view (#15555) * Fix ComposeForm being mounted twice in mobile view Fixes #13094 * Fix compose form focus and pre-selection behavior in mobile view * Split _updateFocusAndSelection out of componentDidUpdate --- .../compose/components/compose_form.js | 8 +++++++ .../features/ui/components/columns_area.js | 21 +++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 8af806ec43..ba2d20cc7e 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -132,7 +132,15 @@ class ComposeForm extends ImmutablePureComponent { } } + componentDidMount () { + this._updateFocusAndSelection({ }); + } + componentDidUpdate (prevProps) { + this._updateFocusAndSelection(prevProps); + } + + _updateFocusAndSelection = (prevProps) => { // This statement does several things: // - If we're beginning a reply, and, // - Replying to zero or one users, places the cursor at the end of the textbox. diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 6837450eb5..85a92fc3a9 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -70,8 +70,12 @@ class ColumnsArea extends ImmutablePureComponent { children: PropTypes.node, }; + // Corresponds to (max-width: 600px + (285px * 1) + (10px * 1)) in SCSS + mediaQuery = 'matchMedia' in window && window.matchMedia('(max-width: 895px)'); + state = { shouldAnimate: false, + renderComposePanel: !(this.mediaQuery && this.mediaQuery.matches), } componentWillReceiveProps() { @@ -85,6 +89,11 @@ class ColumnsArea extends ImmutablePureComponent { this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false); } + if (this.mediaQuery) { + this.mediaQuery.addEventListener('change', this.handleLayoutChange); + this.setState({ renderComposePanel: !this.mediaQuery.matches }); + } + this.lastIndex = getIndex(this.context.router.history.location.pathname); this.isRtlLayout = document.getElementsByTagName('body')[0].classList.contains('rtl'); @@ -114,6 +123,10 @@ class ColumnsArea extends ImmutablePureComponent { if (!this.props.singleColumn) { this.node.removeEventListener('wheel', this.handleWheel); } + + if (this.mediaQuery) { + this.mediaQuery.removeEventListener('change', this.handleLayoutChange); + } } handleChildrenContentChange() { @@ -123,6 +136,10 @@ class ColumnsArea extends ImmutablePureComponent { } } + handleLayoutChange = (e) => { + this.setState({ renderComposePanel: !e.matches }); + } + handleSwipe = (index) => { this.pendingIndex = index; @@ -186,7 +203,7 @@ class ColumnsArea extends ImmutablePureComponent { render () { const { columns, children, singleColumn, isModalOpen, intl } = this.props; - const { shouldAnimate } = this.state; + const { shouldAnimate, renderComposePanel } = this.state; const columnIndex = getIndex(this.context.router.history.location.pathname); @@ -205,7 +222,7 @@ class ColumnsArea extends ImmutablePureComponent {
- + {renderComposePanel && }
From 1c4dee4554fdf0658c370dd7d4edfc49fd0494f7 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 24 Mar 2021 10:19:40 +0100 Subject: [PATCH 20/24] Fix Mastodon not understanding as:Public and Public (#15948) Fixes #5551 --- app/lib/activitypub/activity/announce.rb | 4 +- app/lib/activitypub/activity/create.rb | 6 +- app/lib/activitypub/tag_manager.rb | 4 ++ spec/lib/activitypub/activity/create_spec.rb | 76 +++++++++++++++++++- 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb index 349e8f77e7..ae8b2db754 100644 --- a/app/lib/activitypub/activity/announce.rb +++ b/app/lib/activitypub/activity/announce.rb @@ -43,9 +43,9 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity end def visibility_from_audience - if audience_to.include?(ActivityPub::TagManager::COLLECTIONS[:public]) + if audience_to.any? { |to| ActivityPub::TagManager.instance.public_collection?(to) } :public - elsif audience_cc.include?(ActivityPub::TagManager::COLLECTIONS[:public]) + elsif audience_cc.any? { |cc| ActivityPub::TagManager.instance.public_collection?(cc) } :unlisted elsif audience_to.include?(@account.followers_url) :private diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 6127446763..0fa306cddd 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -123,7 +123,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def process_audience (audience_to + audience_cc).uniq.each do |audience| - next if audience == ActivityPub::TagManager::COLLECTIONS[:public] + next if ActivityPub::TagManager.instance.public_collection?(audience) # Unlike with tags, there is no point in resolving accounts we don't already # know here, because silent mentions would only be used for local access @@ -356,9 +356,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def visibility_from_audience - if audience_to.include?(ActivityPub::TagManager::COLLECTIONS[:public]) + if audience_to.any? { |to| ActivityPub::TagManager.instance.public_collection?(to) } :public - elsif audience_cc.include?(ActivityPub::TagManager::COLLECTIONS[:public]) + elsif audience_cc.any? { |cc| ActivityPub::TagManager.instance.public_collection?(cc) } :unlisted elsif audience_to.include?(@account.followers_url) :private diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index 3f2ae1106b..f6b5e10d39 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -12,6 +12,10 @@ class ActivityPub::TagManager public: 'https://www.w3.org/ns/activitystreams#Public', }.freeze + def public_collection?(uri) + uri == COLLECTIONS[:public] || uri == 'as:Public' || uri == 'Public' + end + def url_for(target) return target.url if target.respond_to?(:local?) && !target.local? diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index d2e9fe33ce..2703c18f39 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -67,7 +67,7 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'public' do + context 'public with explicit public address' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -85,7 +85,43 @@ RSpec.describe ActivityPub::Activity::Create do end end - context 'unlisted' do + context 'public with as:Public' do + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + to: 'as:Public', + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.visibility).to eq 'public' + end + end + + context 'public with Public' do + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + to: 'Public', + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.visibility).to eq 'public' + end + end + + context 'unlisted with explicit public address' do let(:object_json) do { id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, @@ -103,6 +139,42 @@ RSpec.describe ActivityPub::Activity::Create do end end + context 'unlisted with as:Public' do + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + cc: 'as:Public', + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.visibility).to eq 'unlisted' + end + end + + context 'unlisted with Public' do + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + cc: 'Public', + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.visibility).to eq 'unlisted' + end + end + context 'private' do let(:object_json) do { From 82556834cf816030eac0d3f962028cb8dafac2aa Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 24 Mar 2021 10:37:24 +0100 Subject: [PATCH 21/24] Change mastodon:setup to not call assets:precompile in docker (#13942) It appears assets are built during image build, and they shouldn't need to be rebuilt, since we now have reproducible builds. --- lib/tasks/mastodon.rake | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index 2ad1e778ba..72bacb5eb2 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -371,18 +371,20 @@ namespace :mastodon do end end - prompt.say "\n" - prompt.say 'The final step is compiling CSS/JS assets.' - prompt.say 'This may take a while and consume a lot of RAM.' + unless using_docker + prompt.say "\n" + prompt.say 'The final step is compiling CSS/JS assets.' + prompt.say 'This may take a while and consume a lot of RAM.' - if prompt.yes?('Compile the assets now?') - prompt.say 'Running `RAILS_ENV=production rails assets:precompile` ...' - prompt.say "\n\n" + if prompt.yes?('Compile the assets now?') + prompt.say 'Running `RAILS_ENV=production rails assets:precompile` ...' + prompt.say "\n\n" - if !system(env.transform_values(&:to_s).merge({ 'RAILS_ENV' => 'production' }), 'rails assets:precompile') - prompt.error 'That failed! Maybe you need swap space?' - else - prompt.say 'Done!' + if !system(env.transform_values(&:to_s).merge({ 'RAILS_ENV' => 'production' }), 'rails assets:precompile') + prompt.error 'That failed! Maybe you need swap space?' + else + prompt.say 'Done!' + end end end From cbd0ee1d07c0d48e4ed14bd446cd23d334e76da8 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 24 Mar 2021 10:44:31 +0100 Subject: [PATCH 22/24] Update Mastodon to Rails 6.1 (#15910) * Update devise-two-factor to unreleased fork for Rails 6 support Update tests to match new `rotp` version. * Update nsa gem to unreleased fork for Rails 6 support * Update rails to 6.1.3 and rails-i18n to 6.0 * Update to unreleased fork of pluck_each for Ruby 6 support * Run "rails app:update" * Add missing ActiveStorage config file * Use config.ssl_options instead of removed ApplicationController#force_ssl Disabled force_ssl-related tests as they do not seem to be easily testable anymore. * Fix nonce directives by removing Rails 5 specific monkey-patching * Fix fixture_file_upload deprecation warning * Fix yield-based test failing with Rails 6 * Use Rails 6's index_with when possible * Use ActiveRecord::Cache::Store#delete_multi from Rails 6 This will yield better performances when deleting an account * Disable Rails 6.1's automatic preload link headers Since Rails 6.1, ActionView adds preload links for javascript files in the Links header per default. In our case, that will bloat headers too much and potentially cause issues with reverse proxies. Furhermore, we don't need those links, as we already output them as HTML link tags. * Switch to Rails 6.0 default config * Switch to Rails 6.1 default config * Do not include autoload paths in the load path --- Gemfile | 10 +- Gemfile.lock | 181 +++++++++++------- app/controllers/application_controller.rb | 6 - app/lib/delivery_failure_tracker.rb | 2 +- app/lib/feed_manager.rb | 12 +- app/lib/settings/scoped_settings.rb | 2 +- app/models/concerns/account_interactions.rb | 2 +- app/models/report.rb | 2 +- app/services/delete_account_service.rb | 3 +- app/services/import_service.rb | 4 +- bin/setup | 16 +- bin/yarn | 12 +- config/application.rb | 3 +- config/environments/production.rb | 7 + .../application_controller_renderer.rb | 10 +- config/initializers/backtrace_silencers.rb | 7 +- .../initializers/content_security_policy.rb | 12 +- config/initializers/permissions_policy.rb | 11 ++ config/initializers/preload_link_headers.rb | 8 + config/storage.yml | 0 lib/tasks/emojis.rake | 2 +- .../accounts/credentials_controller_spec.rb | 4 +- .../api/v1/media_controller_spec.rb | 10 +- .../application_controller_spec.rb | 14 -- .../settings/imports_controller_spec.rb | 4 +- .../settings/profiles_controller_spec.rb | 4 +- .../confirmations_controller_spec.rb | 2 +- spec/models/setting_spec.rb | 11 +- spec/models/user_spec.rb | 2 +- 29 files changed, 204 insertions(+), 159 deletions(-) create mode 100644 config/initializers/permissions_policy.rb create mode 100644 config/initializers/preload_link_headers.rb create mode 100644 config/storage.yml diff --git a/Gemfile b/Gemfile index 98af92deff..0b2fdf1560 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ ruby '>= 2.5.0', '< 3.0.0' gem 'pkg-config', '~> 1.4' gem 'puma', '~> 5.2' -gem 'rails', '~> 5.2.4.5' +gem 'rails', '~> 6.1.3' gem 'sprockets', '~> 3.7.2' gem 'thor', '~> 1.1' gem 'rack', '~> 2.2.3' @@ -34,7 +34,7 @@ gem 'iso-639' gem 'chewy', '~> 5.2' gem 'cld3', '~> 3.4.1' gem 'devise', '~> 4.7' -gem 'devise-two-factor', '~> 3.1' +gem 'devise-two-factor', git: 'https://github.com/ClearlyClaire/devise-two-factor', ref: '594bb8a32e6f94df7e5ba7c9399eaf9ff25bac0d' group :pam_authentication, optional: true do gem 'devise_pam_authenticatable2', '~> 9.2' @@ -65,7 +65,7 @@ gem 'link_header', '~> 0.0' gem 'mime-types', '~> 3.3.1', require: 'mime/types/columnar' gem 'nilsimsa', git: 'https://github.com/witgo/nilsimsa', ref: 'fd184883048b922b176939f851338d0a4971a532' gem 'nokogiri', '~> 1.11' -gem 'nsa', '~> 0.2' +gem 'nsa', git: 'https://github.com/Gargron/nsa', ref: 'd1079e0cdafdfed7f9f35478d13b9bdaa65965c0' gem 'oj', '~> 3.11' gem 'ox', '~> 2.14' gem 'parslet' @@ -75,7 +75,7 @@ gem 'pundit', '~> 2.1' gem 'premailer-rails' gem 'rack-attack', '~> 6.5' gem 'rack-cors', '~> 1.1', require: 'rack/cors' -gem 'rails-i18n', '~> 5.1' +gem 'rails-i18n', '~> 6.0' gem 'rails-settings-cached', '~> 0.6' gem 'redis', '~> 4.2', require: ['redis', 'redis/connection/hiredis'] gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' @@ -159,4 +159,4 @@ gem 'concurrent-ruby', require: false gem 'connection_pool', require: false gem 'xorcist', '~> 1.1' -gem 'pluck_each', '~> 0.1.3' +gem 'pluck_each', git: 'https://github.com/nsommer/pluck_each', ref: '73be0947c52fc54bf6d7085378db008358aac5eb' diff --git a/Gemfile.lock b/Gemfile.lock index 1a67f893d6..1f7183b9d0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,26 @@ +GIT + remote: https://github.com/ClearlyClaire/devise-two-factor + revision: 594bb8a32e6f94df7e5ba7c9399eaf9ff25bac0d + ref: 594bb8a32e6f94df7e5ba7c9399eaf9ff25bac0d + specs: + devise-two-factor (3.1.0) + activesupport (< 7.0) + attr_encrypted (>= 1.3, < 4, != 2) + devise + railties (< 7.0) + rotp (~> 6) + +GIT + remote: https://github.com/Gargron/nsa + revision: d1079e0cdafdfed7f9f35478d13b9bdaa65965c0 + ref: d1079e0cdafdfed7f9f35478d13b9bdaa65965c0 + specs: + nsa (0.2.8) + activesupport (>= 4.2, < 7) + concurrent-ruby (~> 1.0, >= 1.0.2) + sidekiq (>= 3.5) + statsd-ruby (~> 1.4, >= 1.4.0) + GIT remote: https://github.com/ianheggie/health_check revision: 0b799ead604f900ed50685e9b2d469cd2befba5b @@ -6,6 +29,15 @@ GIT health_check (4.0.0.pre) rails (>= 4.0) +GIT + remote: https://github.com/nsommer/pluck_each + revision: 73be0947c52fc54bf6d7085378db008358aac5eb + ref: 73be0947c52fc54bf6d7085378db008358aac5eb + specs: + pluck_each (0.1.3) + activerecord (>= 6.1.0) + activesupport (>= 6.1.0) + GIT remote: https://github.com/witgo/nilsimsa revision: fd184883048b922b176939f851338d0a4971a532 @@ -16,53 +48,71 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (5.2.4.5) - actionpack (= 5.2.4.5) + actioncable (6.1.3) + actionpack (= 6.1.3) + activesupport (= 6.1.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.4.5) - actionpack (= 5.2.4.5) - actionview (= 5.2.4.5) - activejob (= 5.2.4.5) + actionmailbox (6.1.3) + actionpack (= 6.1.3) + activejob (= 6.1.3) + activerecord (= 6.1.3) + activestorage (= 6.1.3) + activesupport (= 6.1.3) + mail (>= 2.7.1) + actionmailer (6.1.3) + actionpack (= 6.1.3) + actionview (= 6.1.3) + activejob (= 6.1.3) + activesupport (= 6.1.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.4.5) - actionview (= 5.2.4.5) - activesupport (= 5.2.4.5) - rack (~> 2.0, >= 2.0.8) + actionpack (6.1.3) + actionview (= 6.1.3) + activesupport (= 6.1.3) + rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.4.5) - activesupport (= 5.2.4.5) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (6.1.3) + actionpack (= 6.1.3) + activerecord (= 6.1.3) + activestorage (= 6.1.3) + activesupport (= 6.1.3) + nokogiri (>= 1.8.5) + actionview (6.1.3) + activesupport (= 6.1.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) + rails-html-sanitizer (~> 1.1, >= 1.2.0) active_model_serializers (0.10.12) actionpack (>= 4.1, < 6.2) activemodel (>= 4.1, < 6.2) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) active_record_query_trace (1.8) - activejob (5.2.4.5) - activesupport (= 5.2.4.5) + activejob (6.1.3) + activesupport (= 6.1.3) globalid (>= 0.3.6) - activemodel (5.2.4.5) - activesupport (= 5.2.4.5) - activerecord (5.2.4.5) - activemodel (= 5.2.4.5) - activesupport (= 5.2.4.5) - arel (>= 9.0) - activestorage (5.2.4.5) - actionpack (= 5.2.4.5) - activerecord (= 5.2.4.5) + activemodel (6.1.3) + activesupport (= 6.1.3) + activerecord (6.1.3) + activemodel (= 6.1.3) + activesupport (= 6.1.3) + activestorage (6.1.3) + actionpack (= 6.1.3) + activejob (= 6.1.3) + activerecord (= 6.1.3) + activesupport (= 6.1.3) marcel (~> 0.3.1) - activesupport (5.2.4.5) + mimemagic (~> 0.3.2) + activesupport (6.1.3) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) airbrussh (1.4.0) @@ -71,7 +121,6 @@ GEM annotate (3.1.1) activerecord (>= 3.2, < 7.0) rake (>= 10.4, < 14.0) - arel (9.0.0) ast (2.4.2) attr_encrypted (3.1.0) encryptor (~> 3.0.0) @@ -175,12 +224,6 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-two-factor (3.1.0) - activesupport (< 6.1) - attr_encrypted (>= 1.3, < 4, != 2) - devise (~> 4.0) - railties (< 6.1) - rotp (~> 2.0) devise_pam_authenticatable2 (9.2.0) devise (>= 4.0.0) rpam2 (~> 4.0) @@ -370,11 +413,6 @@ GEM racc (~> 1.4) nokogumbo (2.0.4) nokogiri (~> 1.8, >= 1.8.4) - nsa (0.2.7) - activesupport (>= 4.2, < 6) - concurrent-ruby (~> 1.0, >= 1.0.2) - sidekiq (>= 3.5) - statsd-ruby (~> 1.4, >= 1.4.0) oj (3.11.3) omniauth (1.9.1) hashie (>= 3.4.6) @@ -414,9 +452,6 @@ GEM pghero (2.8.0) activerecord (>= 5) pkg-config (1.4.5) - pluck_each (0.1.3) - activerecord (> 3.2.0) - activesupport (> 3.0.0) posix-spawn (0.3.15) premailer (1.14.2) addressable @@ -450,18 +485,20 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.2.4.5) - actioncable (= 5.2.4.5) - actionmailer (= 5.2.4.5) - actionpack (= 5.2.4.5) - actionview (= 5.2.4.5) - activejob (= 5.2.4.5) - activemodel (= 5.2.4.5) - activerecord (= 5.2.4.5) - activestorage (= 5.2.4.5) - activesupport (= 5.2.4.5) - bundler (>= 1.3.0) - railties (= 5.2.4.5) + rails (6.1.3) + actioncable (= 6.1.3) + actionmailbox (= 6.1.3) + actionmailer (= 6.1.3) + actionpack (= 6.1.3) + actiontext (= 6.1.3) + actionview (= 6.1.3) + activejob (= 6.1.3) + activemodel (= 6.1.3) + activerecord (= 6.1.3) + activestorage (= 6.1.3) + activesupport (= 6.1.3) + bundler (>= 1.15.0) + railties (= 6.1.3) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) @@ -472,17 +509,17 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.3.0) loofah (~> 2.3) - rails-i18n (5.1.3) + rails-i18n (6.0.0) i18n (>= 0.7, < 2) - railties (>= 5.0, < 6) + railties (>= 6.0.0, < 7) rails-settings-cached (0.6.6) rails (>= 4.2.0) - railties (5.2.4.5) - actionpack (= 5.2.4.5) - activesupport (= 5.2.4.5) + railties (6.1.3) + actionpack (= 6.1.3) + activesupport (= 6.1.3) method_source rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) + thor (~> 1.0) rainbow (3.0.0) rake (13.0.3) rdf (3.1.13) @@ -500,7 +537,7 @@ GEM actionpack (>= 5.0) railties (>= 5.0) rexml (3.2.4) - rotp (2.1.2) + rotp (6.2.0) rpam2 (4.0.2) rqrcode (1.2.0) chunky_png (~> 1.0) @@ -600,7 +637,7 @@ GEM net-scp (>= 1.1.2) net-ssh (>= 2.8.0) stackprof (0.2.16) - statsd-ruby (1.4.0) + statsd-ruby (1.5.0) stoplight (2.2.1) streamio-ffmpeg (3.0.2) multi_json (~> 1.8) @@ -612,7 +649,6 @@ GEM terrapin (0.6.0) climate_control (>= 0.0.3, < 1.0) thor (1.1.0) - thread_safe (0.3.6) thwait (0.2.0) e2mmap tilt (2.0.10) @@ -632,8 +668,8 @@ GEM twitter-text (3.1.0) idn-ruby unf (~> 0.1.0) - tzinfo (1.2.9) - thread_safe (~> 0.1) + tzinfo (2.0.4) + concurrent-ruby (~> 1.0) tzinfo-data (1.2021.1) tzinfo (>= 1.0.0) unf (0.1.4) @@ -672,6 +708,7 @@ GEM xorcist (1.1.2) xpath (3.2.0) nokogiri (~> 1.8) + zeitwerk (2.4.2) PLATFORMS ruby @@ -703,7 +740,7 @@ DEPENDENCIES concurrent-ruby connection_pool devise (~> 4.7) - devise-two-factor (~> 3.1) + devise-two-factor! devise_pam_authenticatable2 (~> 9.2) discard (~> 1.2) doorkeeper (~> 5.5) @@ -741,7 +778,7 @@ DEPENDENCIES net-ldap (~> 0.17) nilsimsa! nokogiri (~> 1.11) - nsa (~> 0.2) + nsa! oj (~> 3.11) omniauth (~> 1.9) omniauth-cas (~> 2.0) @@ -756,7 +793,7 @@ DEPENDENCIES pg (~> 1.2) pghero (~> 2.8) pkg-config (~> 1.4) - pluck_each (~> 0.1.3) + pluck_each! posix-spawn premailer-rails private_address_check (~> 0.5) @@ -767,9 +804,9 @@ DEPENDENCIES rack (~> 2.2.3) rack-attack (~> 6.5) rack-cors (~> 1.1) - rails (~> 5.2.4.5) + rails (~> 6.1.3) rails-controller-testing (~> 1.0) - rails-i18n (~> 5.1) + rails-i18n (~> 6.0) rails-settings-cached (~> 0.6) rdf-normalize (~> 0.4) redis (~> 4.2) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5b7eec94f7..6361d4b276 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,8 +5,6 @@ class ApplicationController < ActionController::Base # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception - force_ssl if: :https_enabled? - include Localized include UserTrackingConcern include SessionTrackingConcern @@ -42,10 +40,6 @@ class ApplicationController < ActionController::Base private - def https_enabled? - Rails.env.production? && !request.path.start_with?('/health') && !request.headers["Host"].end_with?(".onion") - end - def authorized_fetch_mode? ENV['AUTHORIZED_FETCH'] == 'true' || Rails.configuration.x.whitelist_mode end diff --git a/app/lib/delivery_failure_tracker.rb b/app/lib/delivery_failure_tracker.rb index 25fa694d22..2cd6ef7adf 100644 --- a/app/lib/delivery_failure_tracker.rb +++ b/app/lib/delivery_failure_tracker.rb @@ -29,7 +29,7 @@ class DeliveryFailureTracker class << self def without_unavailable(urls) - unavailable_domains_map = Rails.cache.fetch('unavailable_domains') { UnavailableDomain.pluck(:domain).each_with_object({}) { |domain, hash| hash[domain] = true } } + unavailable_domains_map = Rails.cache.fetch('unavailable_domains') { UnavailableDomain.pluck(:domain).index_with(true) } urls.reject do |url| host = Addressable::URI.parse(url).normalized_host diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 165338437b..43aeecb353 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -533,12 +533,12 @@ class FeedManager arr end - crutches[:following] = Follow.where(account_id: receiver_id, target_account_id: statuses.map(&:in_reply_to_account_id).compact).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true } - crutches[:hiding_reblogs] = Follow.where(account_id: receiver_id, target_account_id: statuses.map { |s| s.account_id if s.reblog? }.compact, show_reblogs: false).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true } - crutches[:blocking] = Block.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true } - crutches[:muting] = Mute.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true } - crutches[:domain_blocking] = AccountDomainBlock.where(account_id: receiver_id, domain: statuses.map { |s| s.reblog&.account&.domain }.compact).pluck(:domain).each_with_object({}) { |domain, mapping| mapping[domain] = true } - crutches[:blocked_by] = Block.where(target_account_id: receiver_id, account_id: statuses.map { |s| s.reblog&.account_id }.compact).pluck(:account_id).each_with_object({}) { |id, mapping| mapping[id] = true } + crutches[:following] = Follow.where(account_id: receiver_id, target_account_id: statuses.map(&:in_reply_to_account_id).compact).pluck(:target_account_id).index_with(true) + crutches[:hiding_reblogs] = Follow.where(account_id: receiver_id, target_account_id: statuses.map { |s| s.account_id if s.reblog? }.compact, show_reblogs: false).pluck(:target_account_id).index_with(true) + crutches[:blocking] = Block.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).index_with(true) + crutches[:muting] = Mute.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).index_with(true) + crutches[:domain_blocking] = AccountDomainBlock.where(account_id: receiver_id, domain: statuses.map { |s| s.reblog&.account&.domain }.compact).pluck(:domain).index_with(true) + crutches[:blocked_by] = Block.where(target_account_id: receiver_id, account_id: statuses.map { |s| s.reblog&.account_id }.compact).pluck(:account_id).index_with(true) crutches end diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb index acabf0c8e0..1e18d6d463 100644 --- a/app/lib/settings/scoped_settings.rb +++ b/app/lib/settings/scoped_settings.rb @@ -63,7 +63,7 @@ module Settings class << self def default_settings - defaulting = DEFAULTING_TO_UNSCOPED.each_with_object({}) { |k, h| h[k] = Setting[k] } + defaulting = DEFAULTING_TO_UNSCOPED.index_with { |k| Setting[k] } Setting.default_settings.merge!(defaulting) end end diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb index 974f57820d..51e8e04a80 100644 --- a/app/models/concerns/account_interactions.rb +++ b/app/models/concerns/account_interactions.rb @@ -67,7 +67,7 @@ module AccountInteractions private def follow_mapping(query, field) - query.pluck(field).each_with_object({}) { |id, mapping| mapping[id] = true } + query.pluck(field).index_with(true) end end diff --git a/app/models/report.rb b/app/models/report.rb index cd08120e41..ef41547d99 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -32,7 +32,7 @@ class Report < ApplicationRecord scope :unresolved, -> { where(action_taken: false) } scope :resolved, -> { where(action_taken: true) } - scope :with_accounts, -> { includes([:account, :target_account, :action_taken_by_account, :assigned_account].each_with_object({}) { |k, h| h[k] = { user: [:invite_request, :invite] } }) } + scope :with_accounts, -> { includes([:account, :target_account, :action_taken_by_account, :assigned_account].index_with({ user: [:invite_request, :invite] })) } validates :comment, length: { maximum: 1000 } diff --git a/app/services/delete_account_service.rb b/app/services/delete_account_service.rb index 802799ccd9..182f0e1277 100644 --- a/app/services/delete_account_service.rb +++ b/app/services/delete_account_service.rb @@ -188,8 +188,7 @@ class DeleteAccountService < BaseService ids = favourites.pluck(:status_id) StatusStat.where(status_id: ids).update_all('favourites_count = GREATEST(0, favourites_count - 1)') Chewy.strategy.current.update(StatusesIndex::Status, ids) if Chewy.enabled? - # Rails.cache.delete_multi would be better, but we don't have it yet - ids.each { |id| Rails.cache.delete("statuses/#{id}") } + Rails.cache.delete_multi(ids.map { |id| "statuses/#{id}" }) favourites.delete_all end end diff --git a/app/services/import_service.rb b/app/services/import_service.rb index b115322831..74ad5b79f4 100644 --- a/app/services/import_service.rb +++ b/app/services/import_service.rb @@ -45,7 +45,7 @@ class ImportService < BaseService items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#domain'].strip } if @import.overwrite? - presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true } + presence_hash = items.index_with(true) @account.domain_blocks.find_each do |domain_block| if presence_hash[domain_block.domain] @@ -96,7 +96,7 @@ class ImportService < BaseService items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#uri'].strip } if @import.overwrite? - presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true } + presence_hash = items.index_with(true) @account.bookmarks.find_each do |bookmark| if presence_hash[bookmark.status.uri] diff --git a/bin/setup b/bin/setup index fc77b08090..90700ac4f9 100755 --- a/bin/setup +++ b/bin/setup @@ -1,6 +1,5 @@ #!/usr/bin/env ruby -require 'fileutils' -include FileUtils +require "fileutils" # path to your application root. APP_ROOT = File.expand_path('..', __dir__) @@ -9,22 +8,25 @@ def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") end -chdir APP_ROOT do - # This script is a starting point to setup your application. +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. # Add necessary setup steps to this file. puts '== Installing dependencies ==' system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') - system!('yarn install') + + # Install JavaScript dependencies + system! 'bin/yarn' # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') - # cp 'config/database.yml.sample', 'config/database.yml' + # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' # end puts "\n== Preparing database ==" - system! 'bin/rails db:setup' + system! 'bin/rails db:prepare' puts "\n== Removing old logs and tempfiles ==" system! 'bin/rails log:clear tmp:clear' diff --git a/bin/yarn b/bin/yarn index 460dd565b4..9fab2c3507 100755 --- a/bin/yarn +++ b/bin/yarn @@ -1,9 +1,15 @@ #!/usr/bin/env ruby APP_ROOT = File.expand_path('..', __dir__) Dir.chdir(APP_ROOT) do - begin - exec "yarnpkg", *ARGV - rescue Errno::ENOENT + yarn = ENV["PATH"].split(File::PATH_SEPARATOR). + select { |dir| File.expand_path(dir) != __dir__ }. + product(["yarn", "yarn.cmd", "yarn.ps1"]). + map { |dir, file| File.expand_path(file, dir) }. + find { |file| File.executable?(file) } + + if yarn + exec yarn, *ARGV + else $stderr.puts "Yarn executable was not detected in the system." $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" exit 1 diff --git a/config/application.rb b/config/application.rb index 3267fa71be..c911e76dcf 100644 --- a/config/application.rb +++ b/config/application.rb @@ -39,7 +39,8 @@ require_relative '../lib/mastodon/redis_config' module Mastodon class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.2 + config.load_defaults 6.1 + config.add_autoload_paths_to_load_path = false # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers diff --git a/config/environments/production.rb b/config/environments/production.rb index 81a67902ea..6df0a33651 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -44,6 +44,13 @@ Rails.application.configure do # Allow to specify public IP of reverse proxy if it's needed config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split.map { |item| IPAddr.new(item) } if ENV['TRUSTED_PROXY_IP'].present? + config.force_ssl = true + config.ssl_options = { + redirect: { + exclude: -> request { request.path.start_with?('/health') || request.headers["Host"].end_with?('.onion') } + } + } + # Use the lowest log level to ensure availability of diagnostic information # when problems arise. config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info').to_sym diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb index 51639b67a0..89d2efab2b 100644 --- a/config/initializers/application_controller_renderer.rb +++ b/config/initializers/application_controller_renderer.rb @@ -1,6 +1,8 @@ # Be sure to restart your server when you modify this file. -# ApplicationController.renderer.defaults.merge!( -# http_host: 'example.org', -# https: false -# ) +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index 59385cdf37..33699c3091 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -1,7 +1,8 @@ # Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } +# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code +# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". +Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index 98dc711e1b..92645ff288 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -49,17 +49,7 @@ end Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } -# Monkey-patching Rails 5 -module ActionDispatch - class ContentSecurityPolicy - def nonce_directive?(directive) - directive == 'style-src' - end - end -end - -# Rails 6 would require the following instead: -# Rails.application.config.content_security_policy_nonce_directives = %w(style-src) +Rails.application.config.content_security_policy_nonce_directives = %w(style-src) PgHero::HomeController.content_security_policy do |p| p.script_src :self, :unsafe_inline, assets_host diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb new file mode 100644 index 0000000000..00f64d71b0 --- /dev/null +++ b/config/initializers/permissions_policy.rb @@ -0,0 +1,11 @@ +# Define an application-wide HTTP permissions policy. For further +# information see https://developers.google.com/web/updates/2018/06/feature-policy +# +# Rails.application.config.permissions_policy do |f| +# f.camera :none +# f.gyroscope :none +# f.microphone :none +# f.usb :none +# f.fullscreen :self +# f.payment :self, "https://secure.example.com" +# end diff --git a/config/initializers/preload_link_headers.rb b/config/initializers/preload_link_headers.rb new file mode 100644 index 0000000000..9f21c45ecf --- /dev/null +++ b/config/initializers/preload_link_headers.rb @@ -0,0 +1,8 @@ +# Since Rails 6.1, ActionView adds preload links for javascript files +# in the Links header per default. + +# In our case, that will bloat headers too much and potentially cause +# issues with reverse proxies. Furhermore, we don't need those links, +# as we already output them as HTML link tags. + +Rails.application.config.action_view.preload_links_header = false diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/tasks/emojis.rake b/lib/tasks/emojis.rake index 01ae955643..c8655cc478 100644 --- a/lib/tasks/emojis.rake +++ b/lib/tasks/emojis.rake @@ -69,7 +69,7 @@ namespace :emojis do end end - existence_maps = grouped_codes.map { |c| c.map { |cc| [cc, File.exist?(Rails.root.join('public', 'emoji', codepoints_to_filename(cc) + '.svg'))] }.to_h } + existence_maps = grouped_codes.map { |c| c.index_with { |cc| File.exist?(Rails.root.join('public', 'emoji', codepoints_to_filename(cc) + '.svg')) } } map = {} existence_maps.each do |group| diff --git a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb index ebd462a039..9fb0d87700 100644 --- a/spec/controllers/api/v1/accounts/credentials_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/credentials_controller_spec.rb @@ -30,8 +30,8 @@ describe Api::V1::Accounts::CredentialsController do patch :update, params: { display_name: "Alice Isn't Dead", note: "Hi!\n\nToot toot!", - avatar: fixture_file_upload('files/avatar.gif', 'image/gif'), - header: fixture_file_upload('files/attachment.jpg', 'image/jpeg'), + avatar: fixture_file_upload('avatar.gif', 'image/gif'), + header: fixture_file_upload('attachment.jpg', 'image/jpeg'), source: { privacy: 'unlisted', sensitive: true, diff --git a/spec/controllers/api/v1/media_controller_spec.rb b/spec/controllers/api/v1/media_controller_spec.rb index 4e30372084..3eb015a1ca 100644 --- a/spec/controllers/api/v1/media_controller_spec.rb +++ b/spec/controllers/api/v1/media_controller_spec.rb @@ -15,7 +15,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do context 'when imagemagick cant identify the file type' do before do expect_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Errors::NotIdentifiedByImageMagickError) - post :create, params: { file: fixture_file_upload('files/attachment.jpg', 'image/jpeg') } + post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } end it 'returns http 422' do @@ -26,7 +26,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do context 'when there is a generic error' do before do expect_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Error) - post :create, params: { file: fixture_file_upload('files/attachment.jpg', 'image/jpeg') } + post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } end it 'returns http 422' do @@ -37,7 +37,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do context 'image/jpeg' do before do - post :create, params: { file: fixture_file_upload('files/attachment.jpg', 'image/jpeg') } + post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') } end it 'returns http success' do @@ -59,7 +59,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do context 'image/gif' do before do - post :create, params: { file: fixture_file_upload('files/attachment.gif', 'image/gif') } + post :create, params: { file: fixture_file_upload('attachment.gif', 'image/gif') } end it 'returns http success' do @@ -81,7 +81,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do context 'video/webm' do before do - post :create, params: { file: fixture_file_upload('files/attachment.webm', 'video/webm') } + post :create, params: { file: fixture_file_upload('attachment.webm', 'video/webm') } end it do diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index e73a08a0e9..458298a6b9 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -42,20 +42,6 @@ describe ApplicationController, type: :controller do include_examples 'respond_with_error', 422 end - it "does not force ssl if Rails.env.production? is not 'true'" do - routes.draw { get 'success' => 'anonymous#success' } - allow(Rails.env).to receive(:production?).and_return(false) - get 'success' - expect(response).to have_http_status(200) - end - - it "forces ssl if Rails.env.production? is 'true'" do - routes.draw { get 'success' => 'anonymous#success' } - allow(Rails.env).to receive(:production?).and_return(true) - get 'success' - expect(response).to redirect_to('https://test.host/success') - end - describe 'helper_method :current_account' do it 'returns nil if not signed in' do expect(controller.view_context.current_account).to be_nil diff --git a/spec/controllers/settings/imports_controller_spec.rb b/spec/controllers/settings/imports_controller_spec.rb index 7a9b021957..b8caf59413 100644 --- a/spec/controllers/settings/imports_controller_spec.rb +++ b/spec/controllers/settings/imports_controller_spec.rb @@ -21,7 +21,7 @@ RSpec.describe Settings::ImportsController, type: :controller do post :create, params: { import: { type: 'following', - data: fixture_file_upload('files/imports.txt') + data: fixture_file_upload('imports.txt') } } @@ -34,7 +34,7 @@ RSpec.describe Settings::ImportsController, type: :controller do post :create, params: { import: { type: 'blocking', - data: fixture_file_upload('files/imports.txt') + data: fixture_file_upload('imports.txt') } } diff --git a/spec/controllers/settings/profiles_controller_spec.rb b/spec/controllers/settings/profiles_controller_spec.rb index 5b1fe3acad..1ac286254f 100644 --- a/spec/controllers/settings/profiles_controller_spec.rb +++ b/spec/controllers/settings/profiles_controller_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Settings::ProfilesController, type: :controller do account = Fabricate(:account, user: @user, display_name: 'AvatarTest') expect(account.avatar.instance.avatar_file_name).to be_nil - put :update, params: { account: { avatar: fixture_file_upload('files/avatar.gif', 'image/gif') } } + put :update, params: { account: { avatar: fixture_file_upload('avatar.gif', 'image/gif') } } expect(response).to redirect_to(settings_profile_path) expect(account.reload.avatar.instance.avatar_file_name).not_to be_nil expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id) @@ -44,7 +44,7 @@ RSpec.describe Settings::ProfilesController, type: :controller do it 'gives the user an error message' do allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async) account = Fabricate(:account, user: @user, display_name: 'AvatarTest') - put :update, params: { account: { avatar: fixture_file_upload('files/4096x4097.png', 'image/png') } } + put :update, params: { account: { avatar: fixture_file_upload('4096x4097.png', 'image/png') } } expect(response.body).to include('images are not supported') end end diff --git a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb index cdfeef8d6a..7b86513bef 100644 --- a/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb +++ b/spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb @@ -11,7 +11,7 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do subject expect(assigns(:confirmation)).to be_instance_of Form::TwoFactorConfirmation - expect(assigns(:provision_url)).to eq 'otpauth://totp/local-part@domain?secret=thisisasecretforthespecofnewview&issuer=cb6e6126.ngrok.io' + expect(assigns(:provision_url)).to eq 'otpauth://totp/cb6e6126.ngrok.io:local-part%40domain?secret=thisisasecretforthespecofnewview&issuer=cb6e6126.ngrok.io' expect(assigns(:qrcode)).to be_instance_of RQRCode::QRCode expect(response).to have_http_status(200) expect(response).to render_template(:new) diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index 1cc5286748..3ccc21d6c4 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -99,11 +99,12 @@ RSpec.describe Setting, type: :model do end it 'does not query the database' do - expect do |callback| - ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do - described_class[key] - end - end.not_to yield_control + callback = double + allow(callback).to receive(:call) + ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do + described_class[key] + end + expect(callback).not_to have_received(:call) end it 'returns the cached value' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 1dae435360..5db249be2a 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -175,7 +175,7 @@ RSpec.describe User, type: :model do user = Fabricate(:user) ActiveJob::Base.queue_adapter = :test - expect { user.send_confirmation_instructions }.to have_enqueued_job(ActionMailer::DeliveryJob) + expect { user.send_confirmation_instructions }.to have_enqueued_job(ActionMailer::MailDeliveryJob) end end From 297a3cf904f3d95ceaed64b57713997b2b285f87 Mon Sep 17 00:00:00 2001 From: Yurii Izorkin Date: Wed, 24 Mar 2021 12:46:13 +0300 Subject: [PATCH 23/24] templates/systemd/mastodon: enable sandbox mode (#15937) --- dist/mastodon-sidekiq.service | 27 +++++++++++++++++++++++++++ dist/mastodon-streaming.service | 27 +++++++++++++++++++++++++++ dist/mastodon-web.service | 27 +++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/dist/mastodon-sidekiq.service b/dist/mastodon-sidekiq.service index 721a866090..0bb0a800fe 100644 --- a/dist/mastodon-sidekiq.service +++ b/dist/mastodon-sidekiq.service @@ -12,6 +12,33 @@ Environment="MALLOC_ARENA_MAX=2" ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 25 TimeoutSec=15 Restart=always +# Capabilities +CapabilityBoundingSet= +# Security +NoNewPrivileges=true +# Sandboxing +ProtectSystem=strict +PrivateTmp=true +PrivateDevices=true +PrivateUsers=true +ProtectHostname=true +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectControlGroups=true +RestrictAddressFamilies=AF_INET +RestrictAddressFamilies=AF_INET6 +RestrictAddressFamilies=AF_NETLINK +RestrictAddressFamilies=AF_UNIX +RestrictNamespaces=true +LockPersonality=true +RestrictRealtime=true +RestrictSUIDSGID=true +PrivateMounts=true +ProtectClock=true +# System Call Filtering +SystemCallArchitectures=native +SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @reboot @resources @setuid @swap [Install] WantedBy=multi-user.target diff --git a/dist/mastodon-streaming.service b/dist/mastodon-streaming.service index c324fccf46..1443ca1c88 100644 --- a/dist/mastodon-streaming.service +++ b/dist/mastodon-streaming.service @@ -12,6 +12,33 @@ Environment="STREAMING_CLUSTER_NUM=1" ExecStart=/usr/bin/node ./streaming TimeoutSec=15 Restart=always +# Capabilities +CapabilityBoundingSet= +# Security +NoNewPrivileges=true +# Sandboxing +ProtectSystem=strict +PrivateTmp=true +PrivateDevices=true +PrivateUsers=true +ProtectHostname=true +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectControlGroups=true +RestrictAddressFamilies=AF_INET +RestrictAddressFamilies=AF_INET6 +RestrictAddressFamilies=AF_NETLINK +RestrictAddressFamilies=AF_UNIX +RestrictNamespaces=true +LockPersonality=true +RestrictRealtime=true +RestrictSUIDSGID=true +PrivateMounts=true +ProtectClock=true +# System Call Filtering +SystemCallArchitectures=native +SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @reboot @resources @setuid @swap [Install] WantedBy=multi-user.target diff --git a/dist/mastodon-web.service b/dist/mastodon-web.service index 30fcbec1e0..3383f33e3a 100644 --- a/dist/mastodon-web.service +++ b/dist/mastodon-web.service @@ -12,6 +12,33 @@ ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb ExecReload=/bin/kill -SIGUSR1 $MAINPID TimeoutSec=15 Restart=always +# Capabilities +CapabilityBoundingSet= +# Security +NoNewPrivileges=true +# Sandboxing +ProtectSystem=strict +PrivateTmp=true +PrivateDevices=true +PrivateUsers=true +ProtectHostname=true +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectControlGroups=true +RestrictAddressFamilies=AF_INET +RestrictAddressFamilies=AF_INET6 +RestrictAddressFamilies=AF_NETLINK +RestrictAddressFamilies=AF_UNIX +RestrictNamespaces=true +LockPersonality=true +RestrictRealtime=true +RestrictSUIDSGID=true +PrivateMounts=true +ProtectClock=true +# System Call Filtering +SystemCallArchitectures=native +SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @reboot @resources @setuid @swap [Install] WantedBy=multi-user.target From 88d69d3261c2f02278d07dc302ff7fc15bd68e8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Mar 2021 10:53:23 +0100 Subject: [PATCH 24/24] Bump brakeman from 4.10.1 to 5.0.0 (#15656) Bumps [brakeman](https://github.com/presidentbeef/brakeman) from 4.10.1 to 5.0.0. - [Release notes](https://github.com/presidentbeef/brakeman/releases) - [Changelog](https://github.com/presidentbeef/brakeman/blob/main/CHANGES.md) - [Commits](https://github.com/presidentbeef/brakeman/compare/v4.10.1...v5.0.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 0b2fdf1560..4682275a09 100644 --- a/Gemfile +++ b/Gemfile @@ -140,7 +140,7 @@ group :development do gem 'memory_profiler' gem 'rubocop', '~> 1.11', require: false gem 'rubocop-rails', '~> 2.9', require: false - gem 'brakeman', '~> 4.10', require: false + gem 'brakeman', '~> 5.0', require: false gem 'bundler-audit', '~> 0.8', require: false gem 'capistrano', '~> 3.16' diff --git a/Gemfile.lock b/Gemfile.lock index 1f7183b9d0..a62305dc05 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -155,7 +155,7 @@ GEM ffi (~> 1.14) bootsnap (1.6.0) msgpack (~> 1.0) - brakeman (4.10.1) + brakeman (5.0.0) browser (4.2.0) brpoplpush-redis_script (0.1.2) concurrent-ruby (~> 1.0, >= 1.0.5) @@ -723,7 +723,7 @@ DEPENDENCIES binding_of_caller (~> 1.0) blurhash (~> 0.1) bootsnap (~> 1.6.0) - brakeman (~> 4.10) + brakeman (~> 5.0) browser bullet (~> 6.1) bundler-audit (~> 0.8)