about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Gemfile8
-rw-r--r--Gemfile.lock34
-rw-r--r--app/javascript/flavours/glitch/styles/_mixins.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/accessibility.scss8
-rw-r--r--app/javascript/flavours/glitch/styles/admin.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/components/accounts.scss4
-rw-r--r--app/javascript/flavours/glitch/styles/components/columns.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/components/composer.scss22
-rw-r--r--app/javascript/flavours/glitch/styles/components/drawer.scss12
-rw-r--r--app/javascript/flavours/glitch/styles/components/index.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/components/media.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/components/modal.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/components/status.scss8
-rw-r--r--app/javascript/flavours/glitch/styles/forms.scss2
-rw-r--r--app/javascript/styles/mastodon/admin.scss16
-rw-r--r--app/lib/language_detector.rb2
-rw-r--r--app/services/fetch_link_card_service.rb15
-rw-r--r--app/validators/note_length_validator.rb2
-rw-r--r--app/validators/status_length_validator.rb8
-rw-r--r--app/views/admin/accounts/index.html.haml2
-rw-r--r--app/views/admin/action_logs/index.html.haml2
-rw-r--r--app/views/admin/email_domain_blocks/index.html.haml2
-rw-r--r--app/views/admin/instances/index.html.haml2
-rw-r--r--config/brakeman.ignore124
-rw-r--r--config/deploy.rb2
-rw-r--r--package.json10
-rw-r--r--spec/services/fetch_link_card_service_spec.rb8
-rw-r--r--spec/validators/note_length_validator_spec.rb33
-rw-r--r--yarn.lock72
29 files changed, 162 insertions, 248 deletions
diff --git a/Gemfile b/Gemfile
index 9e63abd44..b50a957cc 100644
--- a/Gemfile
+++ b/Gemfile
@@ -103,7 +103,7 @@ gem 'json-ld'
 gem 'json-ld-preloaded', '~> 3.1'
 gem 'rdf-normalize', '~> 0.4'
 
-gem 'redcarpet', '~> 3.4'
+gem 'redcarpet', '~> 3.5'
 
 group :development, :test do
   gem 'fabrication', '~> 2.21'
@@ -111,7 +111,7 @@ group :development, :test do
   gem 'i18n-tasks', '~> 0.9', require: false
   gem 'pry-byebug', '~> 3.9'
   gem 'pry-rails', '~> 0.3'
-  gem 'rspec-rails', '~> 4.0'
+  gem 'rspec-rails', '~> 4.1'
 end
 
 group :production, :test do
@@ -127,7 +127,7 @@ group :test do
   gem 'rspec-sidekiq', '~> 3.1'
   gem 'simplecov', '~> 0.21', require: false
   gem 'webmock', '~> 3.12'
-  gem 'parallel_tests', '~> 3.4'
+  gem 'parallel_tests', '~> 3.5'
   gem 'rspec_junit_formatter', '~> 0.4'
 end
 
@@ -145,7 +145,7 @@ group :development do
   gem 'brakeman', '~> 4.10', require: false
   gem 'bundler-audit', '~> 0.7', require: false
 
-  gem 'capistrano', '~> 3.15'
+  gem 'capistrano', '~> 3.16'
   gem 'capistrano-rails', '~> 1.6'
   gem 'capistrano-rbenv', '~> 2.2'
   gem 'capistrano-yarn', '~> 2.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 47be40444..56dc3cbb2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -116,7 +116,7 @@ GEM
       bundler (>= 1.2.0, < 3)
       thor (>= 0.18, < 2)
     byebug (11.1.3)
-    capistrano (3.15.0)
+    capistrano (3.16.0)
       airbrussh (>= 1.0.0)
       i18n
       rake (>= 10.0.0)
@@ -277,7 +277,7 @@ GEM
       rainbow (>= 2.0.0)
     i18n (1.8.9)
       concurrent-ruby (~> 1.0)
-    i18n-tasks (0.9.33)
+    i18n-tasks (0.9.34)
       activesupport (>= 4.0.2)
       ast (>= 2.1.0)
       erubi
@@ -361,7 +361,7 @@ GEM
     net-scp (3.0.0)
       net-ssh (>= 2.6.5, < 7.0.0)
     net-ssh (6.1.0)
-    nio4r (2.5.5)
+    nio4r (2.5.7)
     nokogiri (1.11.1)
       mini_portile2 (~> 2.5.0)
       racc (~> 1.4)
@@ -389,7 +389,7 @@ GEM
     openssl (2.2.0)
     openssl-signature_algorithm (0.4.0)
     orm_adapter (0.5.0)
-    ox (2.14.1)
+    ox (2.14.2)
     paperclip (6.0.0)
       activemodel (>= 4.2.0)
       activesupport (>= 4.2.0)
@@ -400,7 +400,7 @@ GEM
       av (~> 0.9.0)
       paperclip (>= 2.5.2)
     parallel (1.20.1)
-    parallel_tests (3.4.0)
+    parallel_tests (3.5.1)
       parallel
     parser (3.0.0.0)
       ast (~> 2.4.1)
@@ -432,7 +432,7 @@ GEM
     pry-rails (0.3.9)
       pry (>= 0.10.4)
     public_suffix (4.0.6)
-    puma (5.2.1)
+    puma (5.2.2)
       nio4r (~> 2.0)
     pundit (2.1.0)
       activesupport (>= 3.0.0)
@@ -487,7 +487,7 @@ GEM
       link_header (~> 0.0, >= 0.0.8)
     rdf-normalize (0.4.0)
       rdf (~> 3.1)
-    redcarpet (3.5.0)
+    redcarpet (3.5.1)
     redis (4.2.5)
     redis-actionpack (5.2.0)
       actionpack (>= 5, < 7)
@@ -525,10 +525,10 @@ GEM
     rspec-expectations (3.10.1)
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.10.0)
-    rspec-mocks (3.10.1)
+    rspec-mocks (3.10.2)
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.10.0)
-    rspec-rails (4.0.2)
+    rspec-rails (4.1.0)
       actionpack (>= 4.2)
       activesupport (>= 4.2)
       railties (>= 4.2)
@@ -539,7 +539,7 @@ GEM
     rspec-sidekiq (3.1.0)
       rspec-core (~> 3.0, >= 3.0.0)
       sidekiq (>= 2.4.0)
-    rspec-support (3.10.1)
+    rspec-support (3.10.2)
     rspec_junit_formatter (0.4.1)
       rspec-core (>= 2, < 4, != 2.12.0)
     rubocop (1.9.1)
@@ -609,7 +609,7 @@ GEM
       actionpack (>= 4.0)
       activesupport (>= 4.0)
       sprockets (>= 3.0.0)
-    sshkit (1.21.1)
+    sshkit (1.21.2)
       net-scp (>= 1.1.2)
       net-ssh (>= 2.8.0)
     stackprof (0.2.16)
@@ -620,7 +620,7 @@ GEM
     strong_migrations (0.7.6)
       activerecord (>= 5)
     temple (0.8.2)
-    terminal-table (2.0.0)
+    terminal-table (3.0.0)
       unicode-display_width (~> 1.1, >= 1.1.1)
     terrapin (0.6.0)
       climate_control (>= 0.0.3, < 1.0)
@@ -666,7 +666,7 @@ GEM
       safety_net_attestation (~> 0.4.0)
       securecompare (~> 1.0)
       tpm-key_attestation (~> 0.9.0)
-    webmock (3.12.0)
+    webmock (3.12.1)
       addressable (>= 2.3.6)
       crack (>= 0.3.2)
       hashdiff (>= 0.4.0, < 2.0.0)
@@ -703,7 +703,7 @@ DEPENDENCIES
   browser
   bullet (~> 6.1)
   bundler-audit (~> 0.7)
-  capistrano (~> 3.15)
+  capistrano (~> 3.16)
   capistrano-rails (~> 1.6)
   capistrano-rbenv (~> 2.2)
   capistrano-yarn (~> 2.0)
@@ -764,7 +764,7 @@ DEPENDENCIES
   paperclip (~> 6.0)
   paperclip-av-transcoder (~> 0.6)
   parallel (~> 1.20)
-  parallel_tests (~> 3.4)
+  parallel_tests (~> 3.5)
   parslet
   pg (~> 1.2)
   pghero (~> 2.7)
@@ -785,12 +785,12 @@ DEPENDENCIES
   rails-i18n (~> 5.1)
   rails-settings-cached (~> 0.6)
   rdf-normalize (~> 0.4)
-  redcarpet (~> 3.4)
+  redcarpet (~> 3.5)
   redis (~> 4.2)
   redis-namespace (~> 1.8)
   redis-rails (~> 5.0)
   rqrcode (~> 1.2)
-  rspec-rails (~> 4.0)
+  rspec-rails (~> 4.1)
   rspec-sidekiq (~> 3.1)
   rspec_junit_formatter (~> 0.4)
   rubocop (~> 1.9)
diff --git a/app/javascript/flavours/glitch/styles/_mixins.scss b/app/javascript/flavours/glitch/styles/_mixins.scss
index 088b41e76..c92bc8608 100644
--- a/app/javascript/flavours/glitch/styles/_mixins.scss
+++ b/app/javascript/flavours/glitch/styles/_mixins.scss
@@ -55,7 +55,7 @@
   outline: 0;
   box-sizing: border-box;
   width: 100%;
-  border: none;
+  border: 0;
   box-shadow: none;
   font-family: inherit;
   background: $ui-base-color;
diff --git a/app/javascript/flavours/glitch/styles/accessibility.scss b/app/javascript/flavours/glitch/styles/accessibility.scss
index 1a2de2f06..cb27497a4 100644
--- a/app/javascript/flavours/glitch/styles/accessibility.scss
+++ b/app/javascript/flavours/glitch/styles/accessibility.scss
@@ -15,21 +15,21 @@ $emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange'
 .hicolor-privacy-icons {
   .status__visibility-icon.fa-globe,
   .composer--options--dropdown--content--item .fa-globe {
-    color: #1976D2;
+    color: #1976d2;
   }
 
   .status__visibility-icon.fa-unlock,
   .composer--options--dropdown--content--item .fa-unlock {
-    color: #388E3C;
+    color: #388e3c;
   }
 
   .status__visibility-icon.fa-lock,
   .composer--options--dropdown--content--item .fa-lock {
-    color: #FFA000;
+    color: #ffa000;
   }
 
   .status__visibility-icon.fa-envelope,
   .composer--options--dropdown--content--item .fa-envelope {
-    color: #D32F2F;
+    color: #d32f2f;
   }
 }
diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss
index 3cf5ee970..4801a4644 100644
--- a/app/javascript/flavours/glitch/styles/admin.scss
+++ b/app/javascript/flavours/glitch/styles/admin.scss
@@ -267,7 +267,7 @@ $content-width: 840px;
       text-transform: none;
       padding-bottom: 0;
       margin-bottom: 0;
-      border-bottom: none;
+      border-bottom: 0;
     }
 
     & > p {
diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss
index c0bbe5633..6dcfbcb02 100644
--- a/app/javascript/flavours/glitch/styles/components/accounts.scss
+++ b/app/javascript/flavours/glitch/styles/components/accounts.scss
@@ -14,7 +14,7 @@
   }
 
   &.small {
-    border: none;
+    border: 0;
     padding: 0;
 
     & > .account__avatar-wrapper { margin: 0 8px 0 0 }
@@ -278,7 +278,7 @@
 }
 
 .account-gallery__item {
-  border: none;
+  border: 0;
   box-sizing: border-box;
   display: block;
   position: relative;
diff --git a/app/javascript/flavours/glitch/styles/components/columns.scss b/app/javascript/flavours/glitch/styles/components/columns.scss
index 2d080d3b9..90aa5859d 100644
--- a/app/javascript/flavours/glitch/styles/components/columns.scss
+++ b/app/javascript/flavours/glitch/styles/components/columns.scss
@@ -264,7 +264,7 @@
 
   & > button {
     margin: 0;
-    border: none;
+    border: 0;
     padding: 15px;
     color: inherit;
     background: transparent;
diff --git a/app/javascript/flavours/glitch/styles/components/composer.scss b/app/javascript/flavours/glitch/styles/components/composer.scss
index 460f75c1f..fd62bb651 100644
--- a/app/javascript/flavours/glitch/styles/components/composer.scss
+++ b/app/javascript/flavours/glitch/styles/components/composer.scss
@@ -44,7 +44,7 @@
     display: block;
     box-sizing: border-box;
     margin: 0;
-    border: none;
+    border: 0;
     border-radius: 4px;
     padding: 10px;
     width: 100%;
@@ -81,7 +81,9 @@
 
     &:active,
     &:focus,
-    &:hover { text-decoration: none }
+    &:hover {
+      text-decoration: none;
+    }
   }
 }
 
@@ -256,7 +258,7 @@
       display: block;
       box-sizing: border-box;
       margin: 0;
-      border: none;
+      border: 0;
       border-radius: 4px 4px 0 0;
       padding: 10px 32px 0 10px;
       width: 100%;
@@ -277,9 +279,17 @@
         all: unset;
       }
 
-      &:disabled { background: $ui-secondary-color }
-      &:focus { outline: 0 }
-      @include single-column('screen and (max-width: 630px)') { font-size: 16px }
+      &:disabled {
+        background: $ui-secondary-color;
+      }
+
+      &:focus {
+        outline: 0;
+      }
+
+      @include single-column('screen and (max-width: 630px)') {
+        font-size: 16px;
+      }
 
       @include limited-single-column('screen and (max-width: 600px)') {
         height: 100px !important; // prevent auto-resize textarea
diff --git a/app/javascript/flavours/glitch/styles/components/drawer.scss b/app/javascript/flavours/glitch/styles/components/drawer.scss
index 570813831..edc16e250 100644
--- a/app/javascript/flavours/glitch/styles/components/drawer.scss
+++ b/app/javascript/flavours/glitch/styles/components/drawer.scss
@@ -15,10 +15,16 @@
     padding-right: 10px;
   }
 
-  @include single-column('screen and (max-width: 630px)') { flex: auto }
+  @include single-column('screen and (max-width: 630px)') {
+    flex: auto;
+  }
 
   @include limited-single-column('screen and (max-width: 630px)') {
-    &, &:first-child, &:last-child { padding: 0 }
+    &,
+    &:first-child,
+    &:last-child {
+      padding: 0;
+    }
   }
 
   .wide & {
@@ -234,7 +240,7 @@
     display: block;
     width: 100%;
     height: 100%;
-    border: none;
+    border: 0;
     cursor: inherit;
   }
 
diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss
index 40206c696..aada9a928 100644
--- a/app/javascript/flavours/glitch/styles/components/index.scss
+++ b/app/javascript/flavours/glitch/styles/components/index.scss
@@ -1038,7 +1038,7 @@
 .setting-text {
   color: $darker-text-color;
   background: transparent;
-  border: none;
+  border: 0;
   border-bottom: 2px solid $ui-primary-color;
   box-sizing: border-box;
   display: block;
diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss
index f504fa91e..6cbcb05bd 100644
--- a/app/javascript/flavours/glitch/styles/components/media.scss
+++ b/app/javascript/flavours/glitch/styles/components/media.scss
@@ -82,7 +82,7 @@
 }
 
 .media-gallery__item {
-  border: none;
+  border: 0;
   box-sizing: border-box;
   display: block;
   float: left;
diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss
index 0bda305a8..f5acd814e 100644
--- a/app/javascript/flavours/glitch/styles/components/modal.scss
+++ b/app/javascript/flavours/glitch/styles/components/modal.scss
@@ -876,7 +876,7 @@
       box-sizing: border-box;
       display: block;
       width: 100%;
-      border: none;
+      border: 0;
       padding: 10px;
       font-family: 'mastodon-font-monospace', monospace;
       background: $ui-base-color;
diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss
index e067c9335..c1249d0c4 100644
--- a/app/javascript/flavours/glitch/styles/components/status.scss
+++ b/app/javascript/flavours/glitch/styles/components/status.scss
@@ -209,7 +209,7 @@
   display: inline-block;
   border-radius: 2px;
   background: lighten($ui-base-color, 30%);
-  border: none;
+  border: 0;
   color: $inverted-text-color;
   font-weight: 500;
   font-size: 11px;
@@ -389,8 +389,10 @@
       &:after {
         content: "";
         position: absolute;
-        top: 0; bottom: 0;
-        left: 0; right: 0;
+        top: 0;
+        bottom: 0;
+        left: 0;
+        right: 0;
         background: linear-gradient(rgba($ui-base-color, 0), rgba($ui-base-color, 1));
         pointer-events: none;
       }
diff --git a/app/javascript/flavours/glitch/styles/forms.scss b/app/javascript/flavours/glitch/styles/forms.scss
index 0c7cb443b..e641d1709 100644
--- a/app/javascript/flavours/glitch/styles/forms.scss
+++ b/app/javascript/flavours/glitch/styles/forms.scss
@@ -619,7 +619,7 @@ code {
     box-sizing: border-box;
     display: block;
     width: 100%;
-    border: none;
+    border: 0;
     padding: 10px;
     font-family: $font-monospace, monospace;
     background: $ui-base-color;
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index fea64f45c..4801a4644 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -459,22 +459,6 @@ body,
   }
 }
 
-.flavour-screen {
-  display: block;
-  margin: 10px auto;
-  max-width: 100%;
-}
-
-.flavour-description {
-  display: block;
-  font-size: 16px;
-  margin: 10px 0;
-
-  & > p {
-    margin: 10px 0;
-  }
-}
-
 .report-accounts {
   display: flex;
   flex-wrap: wrap;
diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb
index 2cc8ac615..40452eddc 100644
--- a/app/lib/language_detector.rb
+++ b/app/lib/language_detector.rb
@@ -69,7 +69,7 @@ class LanguageDetector
 
   def simplify_text(text)
     new_text = remove_html(text)
-    new_text.gsub!(FetchLinkCardService::URL_PATTERN, '')
+    new_text.gsub!(FetchLinkCardService::URL_PATTERN, '\1')
     new_text.gsub!(Account::MENTION_RE, '')
     new_text.gsub!(Tag::HASHTAG_RE) { |string| string.gsub(/[#_]/, '#' => '', '_' => ' ').gsub(/[a-z][A-Z]|[a-zA-Z][\d]/) { |s| s.insert(1, ' ') }.downcase }
     new_text.gsub!(/:#{CustomEmoji::SHORTCODE_RE_FRAGMENT}:/, '')
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index d4e4931e6..fa1636e41 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -2,12 +2,13 @@
 
 class FetchLinkCardService < BaseService
   URL_PATTERN = %r{
-    (                                                                                                                           #   $1 URL
-      (https?:\/\/)                                                                                                             #   $2 Protocol (required)
-      (#{Twitter::TwitterText::Regex[:valid_domain]})                                                                           #   $3 Domain(s)
-      (?::(#{Twitter::TwitterText::Regex[:valid_port_number]}))?                                                                #   $4 Port number (optional)
-      (/#{Twitter::TwitterText::Regex[:valid_url_path]}*)?                                                                      #   $5 URL Path and anchor
-      (\?#{Twitter::TwitterText::Regex[:valid_url_query_chars]}*#{Twitter::TwitterText::Regex[:valid_url_query_ending_chars]})? #   $6 Query String
+    (#{Twitter::TwitterText::Regex[:valid_url_preceding_chars]})                                                                #   $1 preceeding chars
+    (                                                                                                                           #   $2 URL
+      (https?:\/\/)                                                                                                             #   $3 Protocol (required)
+      (#{Twitter::TwitterText::Regex[:valid_domain]})                                                                           #   $4 Domain(s)
+      (?::(#{Twitter::TwitterText::Regex[:valid_port_number]}))?                                                                #   $5 Port number (optional)
+      (/#{Twitter::TwitterText::Regex[:valid_url_path]}*)?                                                                      #   $6 URL Path and anchor
+      (\?#{Twitter::TwitterText::Regex[:valid_url_query_chars]}*#{Twitter::TwitterText::Regex[:valid_url_query_ending_chars]})? #   $7 Query String
     )
   }iox
 
@@ -63,7 +64,7 @@ class FetchLinkCardService < BaseService
 
   def parse_urls
     if @status.local?
-      urls = @status.text.scan(URL_PATTERN).map { |array| Addressable::URI.parse(array[0]).normalize }
+      urls = @status.text.scan(URL_PATTERN).map { |array| Addressable::URI.parse(array[1]).normalize }
     else
       html  = Nokogiri::HTML(@status.text)
       links = html.css('a')
diff --git a/app/validators/note_length_validator.rb b/app/validators/note_length_validator.rb
index 7ea2bb3e5..554ad49ce 100644
--- a/app/validators/note_length_validator.rb
+++ b/app/validators/note_length_validator.rb
@@ -15,7 +15,7 @@ class NoteLengthValidator < ActiveModel::EachValidator
     return '' if value.nil?
 
     value.dup.tap do |new_text|
-      new_text.gsub!(FetchLinkCardService::URL_PATTERN, 'x' * 23)
+      new_text.gsub!(FetchLinkCardService::URL_PATTERN, StatusLengthValidator::URL_PLACEHOLDER)
       new_text.gsub!(Account::MENTION_RE, '@\2')
     end
   end
diff --git a/app/validators/status_length_validator.rb b/app/validators/status_length_validator.rb
index dcbc4a41a..11997024f 100644
--- a/app/validators/status_length_validator.rb
+++ b/app/validators/status_length_validator.rb
@@ -2,12 +2,6 @@
 
 class StatusLengthValidator < ActiveModel::Validator
   MAX_CHARS = (ENV['MAX_TOOT_CHARS'] || 500).to_i
-  URL_PATTERN = %r{
-    (?:
-      (#{Twitter::TwitterText::Regex[:valid_url_preceding_chars]})
-      (#{FetchLinkCardService::URL_PATTERN})
-    )
-  }iox
   URL_PLACEHOLDER = "\1#{'x' * 23}"
 
   def validate(status)
@@ -35,7 +29,7 @@ class StatusLengthValidator < ActiveModel::Validator
     return '' if @status.text.nil?
 
     @status.text.dup.tap do |new_text|
-      new_text.gsub!(URL_PATTERN, URL_PLACEHOLDER)
+      new_text.gsub!(FetchLinkCardService::URL_PATTERN, URL_PLACEHOLDER)
       new_text.gsub!(Account::MENTION_RE, '@\2')
     end
   end
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index 8eac226e0..398ab4bb4 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -51,6 +51,6 @@
         %th= t('admin.accounts.most_recent_activity')
         %th
     %tbody
-      = render @accounts
+      = render partial: 'account', collection: @accounts
 
 = paginate @accounts
diff --git a/app/views/admin/action_logs/index.html.haml b/app/views/admin/action_logs/index.html.haml
index 937664c4b..347eca166 100644
--- a/app/views/admin/action_logs/index.html.haml
+++ b/app/views/admin/action_logs/index.html.haml
@@ -20,6 +20,6 @@
     = t 'admin.action_logs.empty'
 - else
   .announcements-list
-    = render @action_logs
+    = render partial: 'action_log', collection: @action_logs
 
 = paginate @action_logs
diff --git a/app/views/admin/email_domain_blocks/index.html.haml b/app/views/admin/email_domain_blocks/index.html.haml
index 6015cfac0..fa5d86b67 100644
--- a/app/views/admin/email_domain_blocks/index.html.haml
+++ b/app/views/admin/email_domain_blocks/index.html.haml
@@ -14,6 +14,6 @@
           %th= t('admin.email_domain_blocks.domain')
           %th
       %tbody
-        = render @email_domain_blocks
+        = render partial: 'email_domain_block', collection: @email_domain_blocks
 
 = paginate @email_domain_blocks
diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml
index 5f20e7ec0..7c7958786 100644
--- a/app/views/admin/instances/index.html.haml
+++ b/app/views/admin/instances/index.html.haml
@@ -36,6 +36,6 @@
   %div.muted-hint.center-text
     = t 'admin.instances.empty'
 - else
-  = render @instances
+  = render partial: 'instance', collection: @instances
 
 = paginate @instances
diff --git a/config/brakeman.ignore b/config/brakeman.ignore
index dcbfd02b4..2d47a9aaf 100644
--- a/config/brakeman.ignore
+++ b/config/brakeman.ignore
@@ -41,99 +41,6 @@
       "note": ""
     },
     {
-      "warning_type": "Dynamic Render Path",
-      "warning_code": 15,
-      "fingerprint": "20a660939f2bbf8c665e69f2844031c0564524689a9570a0091ed94846212020",
-      "check_name": "Render",
-      "message": "Render path contains parameter value",
-      "file": "app/views/admin/action_logs/index.html.haml",
-      "line": 26,
-      "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
-      "code": "render(action => Admin::ActionLogFilter.new(filter_params).results.page(params[:page]), {})",
-      "render_path": [
-        {
-          "type": "controller",
-          "class": "Admin::ActionLogsController",
-          "method": "index",
-          "line": 8,
-          "file": "app/controllers/admin/action_logs_controller.rb",
-          "rendered": {
-            "name": "admin/action_logs/index",
-            "file": "app/views/admin/action_logs/index.html.haml"
-          }
-        }
-      ],
-      "location": {
-        "type": "template",
-        "template": "admin/action_logs/index"
-      },
-      "user_input": "params[:page]",
-      "confidence": "Weak",
-      "note": ""
-    },
-    {
-      "warning_type": "Dynamic Render Path",
-      "warning_code": 15,
-      "fingerprint": "371fe16dc4c9d6ab08a20437d65be4825776107a67c38f6d4780a9c703cd44a5",
-      "check_name": "Render",
-      "message": "Render path contains parameter value",
-      "file": "app/views/admin/email_domain_blocks/index.html.haml",
-      "line": 17,
-      "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
-      "code": "render(action => EmailDomainBlock.where(:parent_id => nil).includes(:children).order(:id => :desc).page(params[:page]), {})",
-      "render_path": [
-        {
-          "type": "controller",
-          "class": "Admin::EmailDomainBlocksController",
-          "method": "index",
-          "line": 10,
-          "file": "app/controllers/admin/email_domain_blocks_controller.rb",
-          "rendered": {
-            "name": "admin/email_domain_blocks/index",
-            "file": "app/views/admin/email_domain_blocks/index.html.haml"
-          }
-        }
-      ],
-      "location": {
-        "type": "template",
-        "template": "admin/email_domain_blocks/index"
-      },
-      "user_input": "params[:page]",
-      "confidence": "Weak",
-      "note": ""
-    },
-    {
-      "warning_type": "Dynamic Render Path",
-      "warning_code": 15,
-      "fingerprint": "4704e8093e3e0561bf705f892e8fc6780419f8255f4440b1c0afd09339bd6446",
-      "check_name": "Render",
-      "message": "Render path contains parameter value",
-      "file": "app/views/admin/instances/index.html.haml",
-      "line": 39,
-      "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
-      "code": "render(action => filtered_instances.page(params[:page]), {})",
-      "render_path": [
-        {
-          "type": "controller",
-          "class": "Admin::InstancesController",
-          "method": "index",
-          "line": 10,
-          "file": "app/controllers/admin/instances_controller.rb",
-          "rendered": {
-            "name": "admin/instances/index",
-            "file": "app/views/admin/instances/index.html.haml"
-          }
-        }
-      ],
-      "location": {
-        "type": "template",
-        "template": "admin/instances/index"
-      },
-      "user_input": "params[:page]",
-      "confidence": "Weak",
-      "note": ""
-    },
-    {
       "warning_type": "Redirect",
       "warning_code": 18,
       "fingerprint": "5fad11cd67f905fab9b1d5739d01384a1748ebe78c5af5ac31518201925265a7",
@@ -254,37 +161,6 @@
       "note": ""
     },
     {
-      "warning_type": "Dynamic Render Path",
-      "warning_code": 15,
-      "fingerprint": "9f31d941f3910dba2e9bfcd81aef4513249bd24c02d0f98e13ad44fdeeccd0e8",
-      "check_name": "Render",
-      "message": "Render path contains parameter value",
-      "file": "app/views/admin/accounts/index.html.haml",
-      "line": 54,
-      "link": "https://brakemanscanner.org/docs/warning_types/dynamic_render_path/",
-      "code": "render(action => filtered_accounts.page(params[:page]), {})",
-      "render_path": [
-        {
-          "type": "controller",
-          "class": "Admin::AccountsController",
-          "method": "index",
-          "line": 12,
-          "file": "app/controllers/admin/accounts_controller.rb",
-          "rendered": {
-            "name": "admin/accounts/index",
-            "file": "app/views/admin/accounts/index.html.haml"
-          }
-        }
-      ],
-      "location": {
-        "type": "template",
-        "template": "admin/accounts/index"
-      },
-      "user_input": "params[:page]",
-      "confidence": "Weak",
-      "note": ""
-    },
-    {
       "warning_type": "Redirect",
       "warning_code": 18,
       "fingerprint": "ba568ac09683f98740f663f3d850c31785900215992e8c090497d359a2563d50",
diff --git a/config/deploy.rb b/config/deploy.rb
index c0d72f48f..f844cc871 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-lock '3.15.0'
+lock '3.16.0'
 
 set :repo_url, ENV.fetch('REPO', 'https://github.com/tootsuite/mastodon.git')
 set :branch, ENV.fetch('BRANCH', 'master')
diff --git a/package.json b/package.json
index 1cb3b8650..ed325c0a4 100644
--- a/package.json
+++ b/package.json
@@ -64,10 +64,10 @@
     "@babel/plugin-proposal-class-properties": "^7.8.3",
     "@babel/plugin-proposal-decorators": "^7.13.5",
     "@babel/plugin-transform-react-inline-elements": "^7.12.13",
-    "@babel/plugin-transform-runtime": "^7.13.8",
-    "@babel/preset-env": "^7.13.8",
+    "@babel/plugin-transform-runtime": "^7.13.9",
+    "@babel/preset-env": "^7.13.9",
     "@babel/preset-react": "^7.12.13",
-    "@babel/runtime": "^7.13.8",
+    "@babel/runtime": "^7.13.9",
     "@clusterws/cws": "^3.0.0",
     "@gamestdio/websocket": "^0.3.2",
     "@github/webauthn-json": "^0.5.7",
@@ -88,7 +88,7 @@
     "color-blend": "^3.0.1",
     "compression-webpack-plugin": "^6.1.1",
     "cross-env": "^7.0.3",
-    "css-loader": "^5.1.0",
+    "css-loader": "^5.1.1",
     "cssnano": "^4.1.10",
     "detect-passive-events": "^2.0.3",
     "dotenv": "^8.2.0",
@@ -145,7 +145,7 @@
     "react-select": "^3.2.0",
     "react-sparklines": "^1.7.0",
     "react-swipeable-views": "^0.13.9",
-    "react-textarea-autosize": "^8.3.1",
+    "react-textarea-autosize": "^8.3.2",
     "react-toggle": "^4.1.1",
     "redis": "^3.0.2",
     "redux": "^4.0.5",
diff --git a/spec/services/fetch_link_card_service_spec.rb b/spec/services/fetch_link_card_service_spec.rb
index 8b296cc70..736a6078d 100644
--- a/spec/services/fetch_link_card_service_spec.rb
+++ b/spec/services/fetch_link_card_service_spec.rb
@@ -77,6 +77,14 @@ RSpec.describe FetchLinkCardService, type: :service do
         expect(a_request(:get, 'http://example.com/test-')).to have_been_made.at_least_once
       end
     end
+
+    context do
+      let(:status) { Fabricate(:status, text: 'testhttp://example.com/sjis') }
+
+      it 'does not fetch URLs with not isolated from their surroundings' do
+        expect(a_request(:get, 'http://example.com/sjis')).to_not have_been_made
+      end
+    end
   end
 
   context 'in a remote status' do
diff --git a/spec/validators/note_length_validator_spec.rb b/spec/validators/note_length_validator_spec.rb
new file mode 100644
index 000000000..6e9b4e132
--- /dev/null
+++ b/spec/validators/note_length_validator_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe NoteLengthValidator do
+  subject { NoteLengthValidator.new(attributes: { note: true }, maximum: 500) }
+
+  describe '#validate' do
+    it 'adds an error when text is over 500 characters' do
+      text = 'a' * 520
+      account = double(note: text, errors: double(add: nil))
+
+      subject.validate_each(account, 'note', text)
+      expect(account.errors).to have_received(:add)
+    end
+
+    it 'counts URLs as 23 characters flat' do
+      text   = ('a' * 476) + " http://#{'b' * 30}.com/example"
+      account = double(note: text, errors: double(add: nil))
+
+      subject.validate_each(account, 'note', text)
+      expect(account.errors).to_not have_received(:add)
+    end
+
+    it 'does not count non-autolinkable URLs as 23 characters flat' do
+      text   = ('a' * 476) + "http://#{'b' * 30}.com/example"
+      account = double(note: text, errors: double(add: nil))
+
+      subject.validate_each(account, 'note', text)
+      expect(account.errors).to have_received(:add)
+    end
+  end
+end
diff --git a/yarn.lock b/yarn.lock
index 44c959323..325c4f645 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -765,10 +765,10 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/plugin-transform-runtime@^7.13.8":
-  version "7.13.8"
-  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.8.tgz#8c9a16db6cb6c2a1f748e36ae23558b92d223010"
-  integrity sha512-6UbZ7P0FuuJiiUyRCfDgLw4PIG9bR2x6swHocv4qNZItkhXad0WsN6YX0deILuyZY2++meDKiDMuSVcejDZN0Q==
+"@babel/plugin-transform-runtime@^7.13.9":
+  version "7.13.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.9.tgz#744d3103338a0d6c90dee0497558150b490cee07"
+  integrity sha512-XCxkY/wBI6M6Jj2mlWxkmqbKPweRanszWbF3Tyut+hKh+PHcuIH/rSr/7lmmE7C3WW+HSIm2GT+d5jwmheuB0g==
   dependencies:
     "@babel/helper-module-imports" "^7.12.13"
     "@babel/helper-plugin-utils" "^7.13.0"
@@ -828,10 +828,10 @@
     "@babel/helper-create-regexp-features-plugin" "^7.12.13"
     "@babel/helper-plugin-utils" "^7.12.13"
 
-"@babel/preset-env@^7.13.8":
-  version "7.13.8"
-  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.8.tgz#1133d7ae806d6bf981b7a1a49e336d4d88db1953"
-  integrity sha512-Sso1xOpV4S3ofnxW2DsWTE5ziRk62jEAKLGuQ+EJHC+YHTbFG38QUTixO3JVa1cYET9gkJhO1pMu+/+2dDhKvw==
+"@babel/preset-env@^7.13.9":
+  version "7.13.9"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.9.tgz#3ee5f233316b10d066d7f379c6d1e13a96853654"
+  integrity sha512-mcsHUlh2rIhViqMG823JpscLMesRt3QbMsv1+jhopXEb3W2wXvQ9QoiOlZI9ZbR3XqPtaFpZwEZKYqGJnGMZTQ==
   dependencies:
     "@babel/compat-data" "^7.13.8"
     "@babel/helper-compilation-targets" "^7.13.8"
@@ -939,10 +939,10 @@
   dependencies:
     regenerator-runtime "^0.12.0"
 
-"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
-  version "7.13.8"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.8.tgz#cc886a85c072df1de23670dc1aa59fc116c4017c"
-  integrity sha512-CwQljpw6qSayc0fRG1soxHAKs1CnQMOChm4mlQP6My0kf9upVGizj/KhlTTgyUnETmHpcUXjaluNAkteRFuafg==
+"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.9", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+  version "7.13.9"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.9.tgz#97dbe2116e2630c489f22e0656decd60aaa1fcee"
+  integrity sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA==
   dependencies:
     regenerator-runtime "^0.13.4"
 
@@ -2410,10 +2410,10 @@ bmp-js@^0.1.0:
   resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233"
   integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM=
 
-bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0:
-  version "4.11.9"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828"
-  integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==
+bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
+  version "4.12.0"
+  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
+  integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
 
 bn.js@^5.1.1:
   version "5.1.3"
@@ -2491,7 +2491,7 @@ bricks.js@^1.7.0:
   dependencies:
     knot.js "^1.1.5"
 
-brorand@^1.0.1:
+brorand@^1.0.1, brorand@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
   integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
@@ -3373,10 +3373,10 @@ css-list-helpers@^1.0.1:
   dependencies:
     tcomb "^2.5.0"
 
-css-loader@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.0.tgz#7c39af036c6674712659ca43a43a80d972bff506"
-  integrity sha512-mFs3Xe2UrzRzL0+ML6e7Q2e/Ozp/WpDcam0l1X+rXgkuFjjsNSrjiyimG6malUOZGVuEjzKp1NqEqN3exG7ZqQ==
+css-loader@^5.1.1:
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.1.tgz#9362d444a0f7c08c148a109596715c904e252879"
+  integrity sha512-5FfhpjwtuRgxqmusDidowqmLlcb+1HgnEDMsi2JhiUrZUcoc+cqw+mUtMIF/+OfeMYaaFCLYp1TaIt9H6I/fKA==
   dependencies:
     camelcase "^6.2.0"
     cssesc "^3.0.0"
@@ -3935,17 +3935,17 @@ electron-to-chromium@^1.3.649:
   integrity sha512-gFQe7HBb0lbOMqK2GAS5/1F+B0IMdYiAgB9OT/w1F4M7lgJK2aNOMNOM622aEax+nS1cTMytkiT0uMOkbtFmHw==
 
 elliptic@^6.5.3:
-  version "6.5.3"
-  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
-  integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
+  version "6.5.4"
+  resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
+  integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
   dependencies:
-    bn.js "^4.4.0"
-    brorand "^1.0.1"
+    bn.js "^4.11.9"
+    brorand "^1.1.0"
     hash.js "^1.0.0"
-    hmac-drbg "^1.0.0"
-    inherits "^2.0.1"
-    minimalistic-assert "^1.0.0"
-    minimalistic-crypto-utils "^1.0.0"
+    hmac-drbg "^1.0.1"
+    inherits "^2.0.4"
+    minimalistic-assert "^1.0.1"
+    minimalistic-crypto-utils "^1.0.1"
 
 emittery@^0.7.1:
   version "0.7.1"
@@ -5299,7 +5299,7 @@ history@^4.7.2:
     value-equal "^0.4.0"
     warning "^3.0.0"
 
-hmac-drbg@^1.0.0:
+hmac-drbg@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
   integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
@@ -7154,7 +7154,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
   resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
   integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
 
-minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
+minimalistic-crypto-utils@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
   integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
@@ -8989,10 +8989,10 @@ react-test-renderer@^16.14.0:
     react-is "^16.8.6"
     scheduler "^0.19.1"
 
-react-textarea-autosize@^8.3.1:
-  version "8.3.1"
-  resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.1.tgz#b942a934cc660ecfc645717d1fb84344b69dcb15"
-  integrity sha512-Vk02C3RWKLjx1wSwcVuPwfTuyGIemBB2MjDi01OnBYxKWSJFA/O7IOzr9FrO8AuRlkupk4X6Kjew2mYyEDXi0A==
+react-textarea-autosize@^8.3.2:
+  version "8.3.2"
+  resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.2.tgz#4f9374d357b0a6f6469956726722549124a1b2db"
+  integrity sha512-JrMWVgQSaExQByP3ggI1eA8zF4mF0+ddVuX7acUeK2V7bmrpjVOY72vmLz2IXFJSAXoY3D80nEzrn0GWajWK3Q==
   dependencies:
     "@babel/runtime" "^7.10.2"
     use-composed-ref "^1.0.0"