diff --git a/Dockerfile b/Dockerfile index a22efe6723..77a402a32b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM ubuntu:18.04 as build-dep SHELL ["bash", "-c"] # Install Node v12 (LTS) -ENV NODE_VER="12.14.0" +ENV NODE_VER="12.16.1" RUN ARCH= && \ dpkgArch="$(dpkg --print-architecture)" && \ case "${dpkgArch##*-}" in \ diff --git a/Gemfile b/Gemfile index 46757eadfe..d0bff213a4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ # frozen_string_literal: true source 'https://rubygems.org' -ruby '>= 2.4.0', '< 3.0.0' +ruby '>= 2.5.0', '< 3.0.0' gem 'pkg-config', '~> 1.4' @@ -35,7 +35,7 @@ gem 'browser' gem 'charlock_holmes', '~> 0.7.7' gem 'iso-639' gem 'chewy', '~> 5.1' -gem 'cld3', '~> 3.2.6' +gem 'cld3', '~> 3.3.0' gem 'devise', '~> 4.7' gem 'devise-two-factor', '~> 3.1' @@ -84,7 +84,7 @@ gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock' gem 'rqrcode', '~> 1.1' gem 'ruby-progressbar', '~> 1.10' gem 'sanitize', '~> 5.1' -gem 'sidekiq', '~> 5.2' +gem 'sidekiq', '~> 6.0' gem 'sidekiq-scheduler', '~> 3.0' gem 'sidekiq-unique-jobs', '~> 6.0' gem 'sidekiq-bulk', '~>0.2.0' @@ -145,7 +145,7 @@ group :development do gem 'brakeman', '~> 4.7', require: false gem 'bundler-audit', '~> 0.6', require: false - gem 'capistrano', '~> 3.11' + gem 'capistrano', '~> 3.12' gem 'capistrano-rails', '~> 1.4' gem 'capistrano-rbenv', '~> 2.1' gem 'capistrano-yarn', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 49b2a8fe8f..48915ab7c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -128,7 +128,7 @@ GEM bundler (>= 1.2.0, < 3) thor (~> 0.18) byebug (11.1.1) - capistrano (3.11.2) + capistrano (3.12.1) airbrussh (>= 1.0.0) i18n rake (>= 10.0.0) @@ -160,7 +160,7 @@ GEM elasticsearch (>= 2.0.0) elasticsearch-dsl chunky_png (1.3.11) - cld3 (3.2.6) + cld3 (3.3.0) ffi (>= 1.1.0, < 1.12.0) climate_control (0.2.0) cocaine (0.5.8) @@ -214,7 +214,7 @@ GEM encryptor (3.0.0) equatable (0.6.1) erubi (1.9.0) - et-orbi (1.1.6) + et-orbi (1.2.3) tzinfo excon (0.71.0) fabrication (2.21.0) @@ -241,8 +241,8 @@ GEM fog-json (>= 1.0) ipaddress (>= 0.8) formatador (0.2.5) - fugit (1.1.6) - et-orbi (~> 1.1, >= 1.1.6) + fugit (1.3.3) + et-orbi (~> 1.1, >= 1.1.8) raabro (~> 1.1) fuubar (2.5.0) rspec-core (~> 3.0) @@ -265,8 +265,8 @@ GEM railties (>= 4.0.1) hamster (3.0.0) concurrent-ruby (~> 1.0) - hashdiff (1.0.0) - hashie (3.6.0) + hashdiff (1.0.1) + hashie (4.1.0) highline (2.0.3) hiredis (0.6.3) hkdf (0.3.0) @@ -304,9 +304,9 @@ GEM jmespath (1.4.0) json (2.3.0) json-canonicalization (0.2.0) - json-ld (3.1.0) + json-ld (3.1.1) htmlentities (~> 4.3) - json-canonicalization (~> 0.1) + json-canonicalization (~> 0.2) link_header (~> 0.0, >= 0.0.8) multi_json (~> 1.14) rack (~> 2.0) @@ -384,8 +384,8 @@ GEM sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) oj (3.10.3) - omniauth (1.9.0) - hashie (>= 3.4.6, < 3.7.0) + omniauth (1.9.1) + hashie (>= 3.4.6) rack (>= 1.6.2, < 3) omniauth-cas (1.1.1) addressable (~> 2.3) @@ -445,7 +445,7 @@ GEM rack (>= 1.0, < 3) rack-cors (1.1.1) rack (>= 2.0.0) - rack-protection (2.0.7) + rack-protection (2.0.8.1) rack rack-proxy (0.6.5) rack @@ -556,32 +556,34 @@ GEM ruby-progressbar (1.10.1) ruby-saml (1.9.0) nokogiri (>= 1.5.10) - rufus-scheduler (3.5.2) - fugit (~> 1.1, >= 1.1.5) + rufus-scheduler (3.6.0) + fugit (~> 1.1, >= 1.1.6) safe_yaml (1.0.5) sanitize (5.1.0) crass (~> 1.0.2) nokogiri (>= 1.8.0) nokogumbo (~> 2.0) - sidekiq (5.2.7) - connection_pool (~> 2.2, >= 2.2.2) - rack (>= 1.5.0) - rack-protection (>= 1.5.0) - redis (>= 3.3.5, < 5) + sidekiq (6.0.4) + connection_pool (>= 2.2.2) + rack (>= 2.0.0) + rack-protection (>= 2.0.0) + redis (>= 4.1.0) sidekiq-bulk (0.2.0) sidekiq - sidekiq-scheduler (3.0.0) + sidekiq-scheduler (3.0.1) + e2mmap redis (>= 3, < 5) rufus-scheduler (~> 3.2) sidekiq (>= 3) + thwait tilt (>= 1.4.0) - sidekiq-unique-jobs (6.0.18) + sidekiq-unique-jobs (6.0.20) concurrent-ruby (~> 1.0, >= 1.0.5) sidekiq (>= 4.0, < 7.0) thor (~> 0) simple-navigation (4.1.0) activesupport (>= 2.3.2) - simple_form (5.0.1) + simple_form (5.0.2) actionpack (>= 5.0) activemodel (>= 5.0) simplecov (0.18.2) @@ -595,7 +597,7 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sshkit (1.20.0) + sshkit (1.21.0) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) stackprof (0.2.15) @@ -640,7 +642,7 @@ GEM uniform_notifier (1.13.0) warden (1.2.8) rack (>= 2.0.6) - webmock (3.8.0) + webmock (3.8.3) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -675,14 +677,14 @@ DEPENDENCIES browser bullet (~> 6.1) bundler-audit (~> 0.6) - capistrano (~> 3.11) + capistrano (~> 3.12) capistrano-rails (~> 1.4) capistrano-rbenv (~> 2.1) capistrano-yarn (~> 2.0) capybara (~> 3.31) charlock_holmes (~> 0.7.7) chewy (~> 5.1) - cld3 (~> 3.2.6) + cld3 (~> 3.3.0) climate_control (~> 0.2) concurrent-ruby connection_pool @@ -767,7 +769,7 @@ DEPENDENCIES rubocop-rails (~> 2.4) ruby-progressbar (~> 1.10) sanitize (~> 5.1) - sidekiq (~> 5.2) + sidekiq (~> 6.0) sidekiq-bulk (~> 0.2.0) sidekiq-scheduler (~> 3.0) sidekiq-unique-jobs (~> 6.0) diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb index f5735421c7..bec9ed88b2 100644 --- a/app/chewy/statuses_index.rb +++ b/app/chewy/statuses_index.rb @@ -47,6 +47,11 @@ class StatusesIndex < Chewy::Index data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } end + crutch :bookmarks do |collection| + data = ::Bookmark.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id) + data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) } + end + root date_detection: false do field :id, type: 'long' field :account_id, type: 'long' diff --git a/app/controllers/admin/email_domain_blocks_controller.rb b/app/controllers/admin/email_domain_blocks_controller.rb index 9fe85064e3..c259197262 100644 --- a/app/controllers/admin/email_domain_blocks_controller.rb +++ b/app/controllers/admin/email_domain_blocks_controller.rb @@ -6,12 +6,12 @@ module Admin def index authorize :email_domain_block, :index? - @email_domain_blocks = EmailDomainBlock.page(params[:page]) + @email_domain_blocks = EmailDomainBlock.where(parent_id: nil).includes(:children).order(id: :desc).page(params[:page]) end def new authorize :email_domain_block, :create? - @email_domain_block = EmailDomainBlock.new + @email_domain_block = EmailDomainBlock.new(domain: params[:_domain]) end def create @@ -21,6 +21,28 @@ module Admin if @email_domain_block.save log_action :create, @email_domain_block + + if @email_domain_block.with_dns_records? + hostnames = [] + ips = [] + + Resolv::DNS.open do |dns| + dns.timeouts = 1 + + hostnames = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s } + + ([@email_domain_block.domain] + hostnames).uniq.each do |hostname| + ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s }) + ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::AAAA).to_a.map { |e| e.address.to_s }) + end + end + + (hostnames + ips).each do |hostname| + another_email_domain_block = EmailDomainBlock.new(domain: hostname, parent: @email_domain_block) + log_action :create, another_email_domain_block if another_email_domain_block.save + end + end + redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.created_msg') else render :new @@ -41,7 +63,7 @@ module Admin end def resource_params - params.require(:email_domain_block).permit(:domain) + params.require(:email_domain_block).permit(:domain, :with_dns_records) end end end diff --git a/app/controllers/admin/warning_presets_controller.rb b/app/controllers/admin/warning_presets_controller.rb index 37be842c5b..b376f8d9b1 100644 --- a/app/controllers/admin/warning_presets_controller.rb +++ b/app/controllers/admin/warning_presets_controller.rb @@ -7,7 +7,7 @@ module Admin def index authorize :account_warning_preset, :index? - @warning_presets = AccountWarningPreset.all + @warning_presets = AccountWarningPreset.alphabetic @warning_preset = AccountWarningPreset.new end @@ -19,7 +19,7 @@ module Admin if @warning_preset.save redirect_to admin_warning_presets_path else - @warning_presets = AccountWarningPreset.all + @warning_presets = AccountWarningPreset.alphabetic render :index end end @@ -52,7 +52,7 @@ module Admin end def warning_preset_params - params.require(:account_warning_preset).permit(:text) + params.require(:account_warning_preset).permit(:title, :text) end end end diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb index 850702ccac..1daa1ed0d3 100644 --- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb @@ -25,7 +25,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController end def hide_results? - (@account.user_hides_network? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account)) + (@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account)) end def default_accounts diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb index 830dcd8a1f..6fc23cf75e 100644 --- a/app/controllers/api/v1/accounts/following_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb @@ -25,7 +25,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController end def hide_results? - (@account.user_hides_network? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account)) + (@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account)) end def default_accounts diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb index d87d7b9466..0bb3d0d27b 100644 --- a/app/controllers/api/v1/media_controller.rb +++ b/app/controllers/api/v1/media_controller.rb @@ -3,25 +3,42 @@ class Api::V1::MediaController < Api::BaseController before_action -> { doorkeeper_authorize! :write, :'write:media' } before_action :require_user! + before_action :set_media_attachment, except: [:create] + before_action :check_processing, except: [:create] def create - @media = current_account.media_attachments.create!(media_params) - render json: @media, serializer: REST::MediaAttachmentSerializer + @media_attachment = current_account.media_attachments.create!(media_attachment_params) + render json: @media_attachment, serializer: REST::MediaAttachmentSerializer rescue Paperclip::Errors::NotIdentifiedByImageMagickError render json: file_type_error, status: 422 rescue Paperclip::Error render json: processing_error, status: 500 end + def show + render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment + end + def update - @media = current_account.media_attachments.where(status_id: nil).find(params[:id]) - @media.update!(media_params) - render json: @media, serializer: REST::MediaAttachmentSerializer + @media_attachment.update!(media_attachment_params) + render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment end private - def media_params + def status_code_for_media_attachment + @media_attachment.not_processed? ? 206 : 200 + end + + def set_media_attachment + @media_attachment = current_account.media_attachments.unattached.find(params[:id]) + end + + def check_processing + render json: processing_error, status: 422 if @media_attachment.processing_failed? + end + + def media_attachment_params params.permit(:file, :description, :focus) end diff --git a/app/controllers/api/v2/media_controller.rb b/app/controllers/api/v2/media_controller.rb new file mode 100644 index 0000000000..0c1baf01d0 --- /dev/null +++ b/app/controllers/api/v2/media_controller.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class Api::V2::MediaController < Api::V1::MediaController + def create + @media_attachment = current_account.media_attachments.create!({ delay_processing: true }.merge(media_attachment_params)) + render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: 202 + rescue Paperclip::Errors::NotIdentifiedByImageMagickError + render json: file_type_error, status: 422 + rescue Paperclip::Error + render json: processing_error, status: 500 + end +end diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index a5dfffd6dd..eb223c3f7c 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -29,7 +29,8 @@ class FollowerAccountsController < ApplicationController render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, - content_type: 'application/activity+json' + content_type: 'application/activity+json', + fields: restrict_fields_to end end end @@ -72,4 +73,12 @@ class FollowerAccountsController < ApplicationController ) end end + + def restrict_fields_to + if page_requested? || !@account.user_hides_network? + # Return all fields + else + %i(id type totalItems) + end + end end diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index ff23d97f96..4ddccf607b 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -29,7 +29,8 @@ class FollowingAccountsController < ApplicationController render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, - content_type: 'application/activity+json' + content_type: 'application/activity+json', + fields: restrict_fields_to end end end @@ -72,4 +73,12 @@ class FollowingAccountsController < ApplicationController ) end end + + def restrict_fields_to + if page_requested? || !@account.user_hides_network? + # Return all fields + else + %i(id type totalItems) + end + end end diff --git a/app/javascript/core/admin.js b/app/javascript/core/admin.js index e4d683dd09..09da9efd39 100644 --- a/app/javascript/core/admin.js +++ b/app/javascript/core/admin.js @@ -1,6 +1,6 @@ // This file will be loaded on admin pages, regardless of theme. -import { delegate } from 'rails-ujs'; +import { delegate } from '@rails/ujs'; import ready from '../mastodon/ready'; const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]'; diff --git a/app/javascript/core/public.js b/app/javascript/core/public.js index 0f42221398..344c051819 100644 --- a/app/javascript/core/public.js +++ b/app/javascript/core/public.js @@ -3,7 +3,7 @@ import createHistory from 'history/createBrowserHistory'; import ready from '../mastodon/ready'; -const { delegate } = require('rails-ujs'); +const { delegate } = require('@rails/ujs'); const { length } = require('stringz'); delegate(document, '.webapp-btn', 'click', ({ target, button }) => { diff --git a/app/javascript/core/settings.js b/app/javascript/core/settings.js index e0cb944e0f..e02c91cc76 100644 --- a/app/javascript/core/settings.js +++ b/app/javascript/core/settings.js @@ -1,7 +1,7 @@ // This file will be loaded on settings pages, regardless of theme. import escapeTextContentForBrowser from 'escape-html'; -const { delegate } = require('rails-ujs'); +const { delegate } = require('@rails/ujs'); import emojify from '../mastodon/features/emoji/emoji'; delegate(document, '#account_display_name', 'input', ({ target }) => { diff --git a/app/javascript/flavours/glitch/packs/common.js b/app/javascript/flavours/glitch/packs/common.js index 94a4e6ee4e..1fedc890a3 100644 --- a/app/javascript/flavours/glitch/packs/common.js +++ b/app/javascript/flavours/glitch/packs/common.js @@ -1,4 +1,4 @@ -import { start } from 'rails-ujs'; +import { start } from '@rails/ujs'; start(); diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js index d8a97704f4..066479fa67 100644 --- a/app/javascript/flavours/glitch/packs/public.js +++ b/app/javascript/flavours/glitch/packs/public.js @@ -5,7 +5,7 @@ import loadKeyboardExtensions from 'flavours/glitch/util/load_keyboard_extension function main() { const IntlMessageFormat = require('intl-messageformat').default; const { timeAgoString } = require('flavours/glitch/components/relative_timestamp'); - const { delegate } = require('rails-ujs'); + const { delegate } = require('@rails/ujs'); const emojify = require('flavours/glitch/util/emoji').default; const { getLocale } = require('locales'); const { messages } = getLocale(); diff --git a/app/javascript/flavours/glitch/packs/settings.js b/app/javascript/flavours/glitch/packs/settings.js index edf1b82e09..8a9f23505d 100644 --- a/app/javascript/flavours/glitch/packs/settings.js +++ b/app/javascript/flavours/glitch/packs/settings.js @@ -3,7 +3,7 @@ import ready from 'flavours/glitch/util/ready'; import loadKeyboardExtensions from 'flavours/glitch/util/load_keyboard_extensions'; function main() { - const { delegate } = require('rails-ujs'); + const { delegate } = require('@rails/ujs'); delegate(document, '.sidebar__toggle__icon', 'click', () => { const target = document.querySelector('.sidebar ul'); diff --git a/app/javascript/flavours/glitch/util/log_out.js b/app/javascript/flavours/glitch/util/log_out.js index 8e16592937..42dcee03ec 100644 --- a/app/javascript/flavours/glitch/util/log_out.js +++ b/app/javascript/flavours/glitch/util/log_out.js @@ -1,4 +1,4 @@ -import Rails from 'rails-ujs'; +import Rails from '@rails/ujs'; import { signOutLink } from 'flavours/glitch/util/backend_links'; export const logOut = () => { diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index c3c6ff1a1d..6b73fc90e0 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -230,12 +230,31 @@ export function uploadCompose(files) { // Account for disparity in size of original image and resized data total += file.size - f.size; - return api(getState).post('/api/v1/media', data, { + return api(getState).post('/api/v2/media', data, { onUploadProgress: function({ loaded }){ progress[i] = loaded; dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total)); }, - }).then(({ data }) => dispatch(uploadComposeSuccess(data, f))); + }).then(({ status, data }) => { + // If server-side processing of the media attachment has not completed yet, + // poll the server until it is, before showing the media attachment as uploaded + + if (status === 200) { + dispatch(uploadComposeSuccess(data, f)); + } else if (status === 202) { + const poll = () => { + api(getState).get(`/api/v1/media/${data.id}`).then(response => { + if (response.status === 200) { + dispatch(uploadComposeSuccess(response.data, f)); + } else if (response.status === 206) { + setTimeout(() => poll(), 1000); + } + }).catch(error => dispatch(uploadComposeFail(error))); + }; + + poll(); + } + }); }).catch(error => dispatch(uploadComposeFail(error))); }; }; diff --git a/app/javascript/mastodon/common.js b/app/javascript/mastodon/common.js index fba21316a7..6818aa5d54 100644 --- a/app/javascript/mastodon/common.js +++ b/app/javascript/mastodon/common.js @@ -1,4 +1,4 @@ -import Rails from 'rails-ujs'; +import Rails from '@rails/ujs'; export function start() { require('font-awesome/css/font-awesome.css'); diff --git a/app/javascript/mastodon/components/domain.js b/app/javascript/mastodon/components/domain.js index 85729ca943..697065d874 100644 --- a/app/javascript/mastodon/components/domain.js +++ b/app/javascript/mastodon/components/domain.js @@ -5,7 +5,7 @@ import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; const messages = defineMessages({ - unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' }, + unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' }, }); export default @injectIntl diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js index 3a490e78ea..65ca43911c 100644 --- a/app/javascript/mastodon/components/scrollable_list.js +++ b/app/javascript/mastodon/components/scrollable_list.js @@ -82,15 +82,19 @@ export default class ScrollableList extends PureComponent { lastScrollWasSynthetic = false; scrollToTopOnMouseIdle = false; + _getScrollingElement = () => { + if (this.props.bindToDocument) { + return (document.scrollingElement || document.body); + } else { + return this.node; + } + } + setScrollTop = newScrollTop => { if (this.getScrollTop() !== newScrollTop) { this.lastScrollWasSynthetic = true; - if (this.props.bindToDocument) { - document.scrollingElement.scrollTop = newScrollTop; - } else { - this.node.scrollTop = newScrollTop; - } + this._getScrollingElement().scrollTop = newScrollTop; } }; @@ -151,15 +155,15 @@ export default class ScrollableList extends PureComponent { } getScrollTop = () => { - return this.props.bindToDocument ? document.scrollingElement.scrollTop : this.node.scrollTop; + return this._getScrollingElement().scrollTop; } getScrollHeight = () => { - return this.props.bindToDocument ? document.scrollingElement.scrollHeight : this.node.scrollHeight; + return this._getScrollingElement().scrollHeight; } getClientHeight = () => { - return this.props.bindToDocument ? document.scrollingElement.clientHeight : this.node.clientHeight; + return this._getScrollingElement().clientHeight; } updateScrollBottom = (snapshot) => { diff --git a/app/javascript/mastodon/containers/domain_container.js b/app/javascript/mastodon/containers/domain_container.js index 813178bbf6..8a8ba1df12 100644 --- a/app/javascript/mastodon/containers/domain_container.js +++ b/app/javascript/mastodon/containers/domain_container.js @@ -6,7 +6,7 @@ import Domain from '../components/domain'; import { openModal } from '../actions/modal'; const messages = defineMessages({ - blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' }, + blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Block entire domain' }, }); const makeMapStateToProps = () => { diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 35cc3952f8..92780a70b3 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -39,7 +39,7 @@ const messages = defineMessages({ favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, - domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' }, + domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' }, mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' }, unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, @@ -142,7 +142,7 @@ class Header extends ImmutablePureComponent { if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) { info.push(); } else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) { - info.push(); + info.push(); } if (me !== account.get('id')) { diff --git a/app/javascript/mastodon/features/compose/components/action_bar.js b/app/javascript/mastodon/features/compose/components/action_bar.js index dd2632796c..07d92bb7e7 100644 --- a/app/javascript/mastodon/features/compose/components/action_bar.js +++ b/app/javascript/mastodon/features/compose/components/action_bar.js @@ -16,6 +16,7 @@ const messages = defineMessages({ mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' }, logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }, + bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' }, }); export default @injectIntl @@ -42,6 +43,7 @@ class ActionBar extends React.PureComponent { menu.push(null); menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' }); menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' }); + menu.push({ text: intl.formatMessage(messages.bookmarks), to: '/bookmarks' }); menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' }); menu.push(null); menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' }); diff --git a/app/javascript/mastodon/features/domain_blocks/index.js b/app/javascript/mastodon/features/domain_blocks/index.js index 06533d5ac9..a6d9889124 100644 --- a/app/javascript/mastodon/features/domain_blocks/index.js +++ b/app/javascript/mastodon/features/domain_blocks/index.js @@ -13,8 +13,8 @@ import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_bloc import ScrollableList from '../../components/scrollable_list'; const messages = defineMessages({ - heading: { id: 'column.domain_blocks', defaultMessage: 'Hidden domains' }, - unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' }, + heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' }, + unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' }, }); const mapStateToProps = state => ({ @@ -55,7 +55,7 @@ class Blocks extends ImmutablePureComponent { ); } - const emptyMessage = ; + const emptyMessage = ; return ( diff --git a/app/javascript/mastodon/features/getting_started/components/announcements.js b/app/javascript/mastodon/features/getting_started/components/announcements.js index fb4a6bf0d1..ec57c41b2b 100644 --- a/app/javascript/mastodon/features/getting_started/components/announcements.js +++ b/app/javascript/mastodon/features/getting_started/components/announcements.js @@ -389,7 +389,7 @@ class Announcements extends ImmutablePureComponent { _markAnnouncementAsRead () { const { dismissAnnouncement, announcements } = this.props; const { index } = this.state; - const announcement = announcements.get(index); + const announcement = announcements.get(index) || announcements.get(index - 1); if (!announcement.get('read')) dismissAnnouncement(announcement.get('id')); } @@ -407,7 +407,7 @@ class Announcements extends ImmutablePureComponent { render () { const { announcements, intl } = this.props; - const { index } = this.state; + const index = this.state.index < announcements.size ? this.state.index : announcements.size - 1; if (announcements.isEmpty()) { return null; diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index 2fec247c16..7a82fa13ac 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -166,7 +166,7 @@ export default class DetailedStatus extends ImmutablePureComponent { reblogIcon = 'lock'; } - if (status.get('visibility') === 'private') { + if (['private', 'direct'].includes(status.get('visibility'))) { reblogLink = ; } else if (this.context.router) { reblogLink = ( diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 93cfa24314..225b7ade2a 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -523,7 +523,7 @@ { "descriptors": [ { - "defaultMessage": "Hide entire domain", + "defaultMessage": "Block entire domain", "id": "confirmations.domain_block.confirm" }, { @@ -737,7 +737,7 @@ "id": "navigation_bar.blocks" }, { - "defaultMessage": "Hidden domains", + "defaultMessage": "Blocked domains", "id": "navigation_bar.domain_blocks" }, { @@ -773,7 +773,7 @@ "id": "account.muted" }, { - "defaultMessage": "Domain hidden", + "defaultMessage": "Domain blocked", "id": "account.domain_blocked" }, { @@ -917,6 +917,10 @@ { "defaultMessage": "Logout", "id": "navigation_bar.logout" + }, + { + "defaultMessage": "Bookmarks", + "id": "navigation_bar.bookmarks" } ], "path": "app/javascript/mastodon/features/compose/components/action_bar.json" @@ -1466,7 +1470,7 @@ { "descriptors": [ { - "defaultMessage": "Hidden domains", + "defaultMessage": "Blocked domains", "id": "column.domain_blocks" }, { @@ -1474,7 +1478,7 @@ "id": "account.unblock_domain" }, { - "defaultMessage": "There are no hidden domains yet.", + "defaultMessage": "There are no blocked domains yet.", "id": "empty_column.domain_blocks" } ], @@ -2957,4 +2961,4 @@ ], "path": "app/javascript/mastodon/features/video/index.json" } -] +] \ No newline at end of file diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 3ec9519039..703bbcaac4 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -7,7 +7,7 @@ "account.blocked": "Blocked", "account.cancel_follow_request": "Cancel follow request", "account.direct": "Direct message @{name}", - "account.domain_blocked": "Domain hidden", + "account.domain_blocked": "Domain blocked", "account.edit_profile": "Edit profile", "account.endorse": "Feature on profile", "account.follow": "Follow", @@ -57,7 +57,7 @@ "column.community": "Local timeline", "column.direct": "Direct messages", "column.directory": "Browse profiles", - "column.domain_blocks": "Hidden domains", + "column.domain_blocks": "Blocked domains", "column.favourites": "Favourites", "column.follow_requests": "Follow requests", "column.home": "Home", @@ -107,7 +107,7 @@ "confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete_list.confirm": "Delete", "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", - "confirmations.domain_block.confirm": "Hide entire domain", + "confirmations.domain_block.confirm": "Block entire domain", "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", "confirmations.logout.confirm": "Log out", "confirmations.logout.message": "Are you sure you want to log out?", @@ -150,7 +150,7 @@ "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", - "empty_column.domain_blocks": "There are no hidden domains yet.", + "empty_column.domain_blocks": "There are no blocked domains yet.", "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", @@ -269,7 +269,7 @@ "navigation_bar.compose": "Compose new toot", "navigation_bar.direct": "Direct messages", "navigation_bar.discover": "Discover", - "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.domain_blocks": "Blocked domains", "navigation_bar.edit_profile": "Edit profile", "navigation_bar.favourites": "Favourites", "navigation_bar.filters": "Muted words", diff --git a/app/javascript/mastodon/utils/log_out.js b/app/javascript/mastodon/utils/log_out.js index b43417f4b4..3a4cc8ecb1 100644 --- a/app/javascript/mastodon/utils/log_out.js +++ b/app/javascript/mastodon/utils/log_out.js @@ -1,4 +1,4 @@ -import Rails from 'rails-ujs'; +import Rails from '@rails/ujs'; export const logOut = () => { const form = document.createElement('form'); diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js index 13cb5d548b..dc85164d0a 100644 --- a/app/javascript/packs/public.js +++ b/app/javascript/packs/public.js @@ -8,7 +8,7 @@ start(); function main() { const IntlMessageFormat = require('intl-messageformat').default; const { timeAgoString } = require('../mastodon/components/relative_timestamp'); - const { delegate } = require('rails-ujs'); + const { delegate } = require('@rails/ujs'); const emojify = require('../mastodon/features/emoji/emoji').default; const { getLocale } = require('../mastodon/locales'); const { messages } = getLocale(); diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb index 302072bccb..05a06726d7 100644 --- a/app/lib/language_detector.rb +++ b/app/lib/language_detector.rb @@ -52,8 +52,10 @@ class LanguageDetector def detect_language_code(text) return if unreliable_input?(text) + result = @identifier.find_language(text) - iso6391(result.language.to_s).to_sym if result.reliable? + + iso6391(result.language.to_s).to_sym if result&.reliable? end def iso6391(bcp47) diff --git a/app/models/account.rb b/app/models/account.rb index 73421ee5a5..82d4d10def 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -46,6 +46,7 @@ # silenced_at :datetime # suspended_at :datetime # trust_level :integer +# hide_collections :boolean # class Account < ApplicationRecord @@ -325,6 +326,14 @@ class Account < ApplicationRecord save! end + def hides_followers? + hide_collections? || user_hides_network? + end + + def hides_following? + hide_collections? || user_hides_network? + end + def object_type :person end diff --git a/app/models/account_warning_preset.rb b/app/models/account_warning_preset.rb index ba8ceabb35..c20f683cff 100644 --- a/app/models/account_warning_preset.rb +++ b/app/models/account_warning_preset.rb @@ -8,8 +8,11 @@ # text :text default(""), not null # created_at :datetime not null # updated_at :datetime not null +# title :string default(""), not null # class AccountWarningPreset < ApplicationRecord validates :text, presence: true + + scope :alphabetic, -> { order(title: :asc, text: :asc) } end diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb index e9da003a30..b30a823699 100644 --- a/app/models/admin/account_action.rb +++ b/app/models/admin/account_action.rb @@ -62,8 +62,6 @@ class Admin::AccountAction def process_action! case type - when 'none' - handle_resolve! when 'disable' handle_disable! when 'silence' @@ -105,16 +103,6 @@ class Admin::AccountAction end end - def handle_resolve! - if with_report? && report.account_id == -99 && target_account.trust_level == Account::TRUST_LEVELS[:untrusted] - # This is an automated report and it is being dismissed, so it's - # a false positive, in which case update the account's trust level - # to prevent further spam checks - - target_account.update(trust_level: Account::TRUST_LEVELS[:trusted]) - end - end - def handle_disable! authorize(target_account.user, :disable?) log_action(:disable, target_account.user) diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb index 43ff8ac12e..18b872c1e6 100644 --- a/app/models/concerns/attachmentable.rb +++ b/app/models/concerns/attachmentable.rb @@ -74,7 +74,7 @@ module Attachmentable self.class.attachment_definitions.each_key do |attachment_name| attachment = send(attachment_name) - next if attachment.blank? || attachment.queued_for_write[:original].blank? + next if attachment.blank? || attachment.queued_for_write[:original].blank? || attachment.options[:preserve_files] attachment.instance_write :file_name, SecureRandom.hex(8) + File.extname(attachment.instance_read(:file_name)) end diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb index bc70dea254..f50fa46ba7 100644 --- a/app/models/email_domain_block.rb +++ b/app/models/email_domain_block.rb @@ -7,13 +7,27 @@ # domain :string default(""), not null # created_at :datetime not null # updated_at :datetime not null +# parent_id :bigint(8) # class EmailDomainBlock < ApplicationRecord include DomainNormalizable + belongs_to :parent, class_name: 'EmailDomainBlock', optional: true + has_many :children, class_name: 'EmailDomainBlock', foreign_key: :parent_id, inverse_of: :parent, dependent: :destroy + validates :domain, presence: true, uniqueness: true, domain: true + def with_dns_records=(val) + @with_dns_records = ActiveModel::Type::Boolean.new.cast(val) + end + + def with_dns_records? + @with_dns_records + end + + alias with_dns_records with_dns_records? + def self.block?(email) _, domain = email.split('@', 2) diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 2813d92002..59427a8cc2 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -19,12 +19,14 @@ # description :text # scheduled_status_id :bigint(8) # blurhash :string +# processing :integer # class MediaAttachment < ApplicationRecord self.inheritance_column = nil enum type: [:image, :gifv, :video, :unknown, :audio] + enum processing: [:queued, :in_progress, :complete, :failed], _prefix: true MAX_DESCRIPTION_LENGTH = 1_500 @@ -55,47 +57,6 @@ class MediaAttachment < ApplicationRecord }, }.freeze - VIDEO_STYLES = { - small: { - convert_options: { - output: { - 'loglevel' => 'fatal', - vf: 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease', - }, - }, - format: 'png', - time: 0, - file_geometry_parser: FastGeometryParser, - blurhash: BLURHASH_OPTIONS, - }, - - original: { - keep_same_format: true, - convert_options: { - output: { - 'loglevel' => 'fatal', - 'map_metadata' => '-1', - 'c:v' => 'copy', - 'c:a' => 'copy', - }, - }, - }, - }.freeze - - AUDIO_STYLES = { - original: { - format: 'mp3', - content_type: 'audio/mpeg', - convert_options: { - output: { - 'loglevel' => 'fatal', - 'map_metadata' => '-1', - 'q:a' => 2, - }, - }, - }, - }.freeze - VIDEO_FORMAT = { format: 'mp4', content_type: 'video/mp4', @@ -116,6 +77,54 @@ class MediaAttachment < ApplicationRecord }, }.freeze + VIDEO_PASSTHROUGH_OPTIONS = { + video_codecs: ['h264'], + audio_codecs: ['aac', nil], + colorspaces: ['yuv420p'], + options: { + format: 'mp4', + convert_options: { + output: { + 'loglevel' => 'fatal', + 'map_metadata' => '-1', + 'c:v' => 'copy', + 'c:a' => 'copy', + }, + }, + }, + }.freeze + + VIDEO_STYLES = { + small: { + convert_options: { + output: { + 'loglevel' => 'fatal', + vf: 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease', + }, + }, + format: 'png', + time: 0, + file_geometry_parser: FastGeometryParser, + blurhash: BLURHASH_OPTIONS, + }, + + original: VIDEO_FORMAT.merge(passthrough_options: VIDEO_PASSTHROUGH_OPTIONS), + }.freeze + + AUDIO_STYLES = { + original: { + format: 'mp3', + content_type: 'audio/mpeg', + convert_options: { + output: { + 'loglevel' => 'fatal', + 'map_metadata' => '-1', + 'q:a' => 2, + }, + }, + }, + }.freeze + VIDEO_CONVERTED_STYLES = { small: VIDEO_STYLES[:small], original: VIDEO_FORMAT, @@ -124,6 +133,9 @@ class MediaAttachment < ApplicationRecord IMAGE_LIMIT = (ENV['MAX_IMAGE_SIZE'] || 10.megabytes).to_i VIDEO_LIMIT = (ENV['MAX_VIDEO_SIZE'] || 40.megabytes).to_i + MAX_VIDEO_MATRIX_LIMIT = 2_304_000 # 1920x1200px + MAX_VIDEO_FRAME_RATE = 60 + belongs_to :account, inverse_of: :media_attachments, optional: true belongs_to :status, inverse_of: :media_attachments, optional: true belongs_to :scheduled_status, inverse_of: :media_attachments, optional: true @@ -156,6 +168,10 @@ class MediaAttachment < ApplicationRecord remote_url.blank? end + def not_processed? + processing.present? && !processing_complete? + end + def needs_redownload? file.blank? && remote_url.present? end @@ -203,12 +219,21 @@ class MediaAttachment < ApplicationRecord "#{x},#{y}" end + attr_writer :delay_processing + + def delay_processing? + @delay_processing + end + + after_commit :enqueue_processing, on: :create after_commit :reset_parent_cache, on: :update before_create :prepare_description, unless: :local? before_create :set_shortcode + before_create :set_processing before_post_process :set_type_and_extension + before_post_process :check_video_dimensions before_save :set_meta @@ -277,6 +302,21 @@ class MediaAttachment < ApplicationRecord end end + def set_processing + self.processing = delay_processing? ? :queued : :complete + end + + def check_video_dimensions + return unless (video? || gifv?) && file.queued_for_write[:original].present? + + movie = FFMPEG::Movie.new(file.queued_for_write[:original].path) + + return unless movie.valid? + + raise Mastodon::DimensionsValidationError, "#{movie.width}x#{movie.height} videos are not supported" if movie.width * movie.height > MAX_VIDEO_MATRIX_LIMIT + raise Mastodon::DimensionsValidationError, "#{movie.frame_rate.to_i}fps videos are not supported" if movie.frame_rate > MAX_VIDEO_FRAME_RATE + end + def set_meta meta = populate_meta @@ -322,9 +362,11 @@ class MediaAttachment < ApplicationRecord }.compact end - def reset_parent_cache - return if status_id.nil? + def enqueue_processing + PostProcessMediaWorker.perform_async(id) if delay_processing? + end - Rails.cache.delete("statuses/#{status_id}") + def reset_parent_cache + Rails.cache.delete("statuses/#{status_id}") if status_id.present? end end diff --git a/app/models/report.rb b/app/models/report.rb index fb2e040ee8..356c23d68b 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -59,6 +59,14 @@ class Report < ApplicationRecord end def resolve!(acting_account) + if account_id == -99 && target_account.trust_level == Account::TRUST_LEVELS[:untrusted] + # This is an automated report and it is being dismissed, so it's + # a false positive, in which case update the account's trust level + # to prevent further spam checks + + target_account.update(trust_level: Account::TRUST_LEVELS[:trusted]) + end + RemovalWorker.push_bulk(Status.with_discarded.discarded.where(id: status_ids).pluck(:id)) { |status_id| [status_id, { immediate: true }] } update!(action_taken: true, action_taken_by_account_id: acting_account.id) end diff --git a/app/models/status.rb b/app/models/status.rb index b2d3c3f3b5..a78717d0cb 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -148,10 +148,12 @@ class Status < ApplicationRecord ids += mentions.where(account: Account.local).pluck(:account_id) ids += favourites.where(account: Account.local).pluck(:account_id) ids += reblogs.where(account: Account.local).pluck(:account_id) + ids += bookmarks.where(account: Account.local).pluck(:account_id) else ids += preloaded.mentions[id] || [] ids += preloaded.favourites[id] || [] ids += preloaded.reblogs[id] || [] + ids += preloaded.bookmarks[id] || [] end ids.uniq diff --git a/app/serializers/rest/media_attachment_serializer.rb b/app/serializers/rest/media_attachment_serializer.rb index 1b3498ea4e..cc10e30015 100644 --- a/app/serializers/rest/media_attachment_serializer.rb +++ b/app/serializers/rest/media_attachment_serializer.rb @@ -12,7 +12,9 @@ class REST::MediaAttachmentSerializer < ActiveModel::Serializer end def url - if object.needs_redownload? + if object.not_processed? + nil + elsif object.needs_redownload? media_proxy_url(object.id, :original) else full_asset_url(object.file.url(:original)) diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index d5ede03886..7b4c53d50c 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -94,6 +94,7 @@ class ActivityPub::ProcessAccountService < BaseService @account.statuses_count = outbox_total_items if outbox_total_items.present? @account.following_count = following_total_items if following_total_items.present? @account.followers_count = followers_total_items if followers_total_items.present? + @account.hide_collections = following_private? || followers_private? @account.moved_to_account = @json['movedTo'].present? ? moved_account : nil end @@ -166,26 +167,36 @@ class ActivityPub::ProcessAccountService < BaseService end def outbox_total_items - collection_total_items('outbox') + collection_info('outbox').first end def following_total_items - collection_total_items('following') + collection_info('following').first end def followers_total_items - collection_total_items('followers') + collection_info('followers').first end - def collection_total_items(type) - return if @json[type].blank? + def following_private? + !collection_info('following').last + end + + def followers_private? + !collection_info('followers').last + end + + def collection_info(type) + return [nil, nil] if @json[type].blank? return @collections[type] if @collections.key?(type) collection = fetch_resource_without_id_validation(@json[type]) - @collections[type] = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil + total_items = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil + has_first_page = collection.is_a?(Hash) && collection['first'].present? + @collections[type] = [total_items, has_first_page] rescue HTTP::Error, OpenSSL::SSL::SSLError - @collections[type] = nil + @collections[type] = [nil, nil] end def moved_account diff --git a/app/services/fetch_resource_service.rb b/app/services/fetch_resource_service.rb index abe7766d4f..880cdde922 100644 --- a/app/services/fetch_resource_service.rb +++ b/app/services/fetch_resource_service.rb @@ -5,6 +5,8 @@ class FetchResourceService < BaseService ACCEPT_HEADER = 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams", text/html;q=0.1' + attr_reader :response_code + def call(url) return if url.blank? @@ -27,6 +29,7 @@ class FetchResourceService < BaseService end def process_response(response, terminal = false) + @response_code = response.code return nil if response.code != 200 if ['application/activity+json', 'application/ld+json'].include?(response.mime_type) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 5d3b8d725d..5b181b1934 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -110,6 +110,7 @@ class PostStatusService < BaseService @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?) + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?) end def language_from_option(str) diff --git a/app/services/resolve_url_service.rb b/app/services/resolve_url_service.rb index 1a2b0d60cb..78080d878f 100644 --- a/app/services/resolve_url_service.rb +++ b/app/services/resolve_url_service.rb @@ -12,7 +12,7 @@ class ResolveURLService < BaseService process_local_url elsif !fetched_resource.nil? process_url - elsif @on_behalf_of.present? + else process_url_from_db end end @@ -30,6 +30,8 @@ class ResolveURLService < BaseService end def process_url_from_db + return unless @on_behalf_of.present? && [401, 403, 404].include?(fetch_resource_service.response_code) + # It may happen that the resource is a private toot, and thus not fetchable, # but we can return the toot if we already know about it. status = Status.find_by(uri: @url) || Status.find_by(url: @url) @@ -40,7 +42,11 @@ class ResolveURLService < BaseService end def fetched_resource - @fetched_resource ||= FetchResourceService.new.call(@url) + @fetched_resource ||= fetch_resource_service.call(@url) + end + + def fetch_resource_service + @_fetch_resource_service ||= FetchResourceService.new end def resource_url diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml index 20fbeef335..aa88b1448b 100644 --- a/app/views/admin/account_actions/new.html.haml +++ b/app/views/admin/account_actions/new.html.haml @@ -21,7 +21,7 @@ - unless @warning_presets.empty? .fields-group - = f.input :warning_preset_id, collection: @warning_presets, label_method: :text, wrapper: :with_block_label + = f.input :warning_preset_id, collection: @warning_presets, label_method: ->(warning_preset) { [warning_preset.title.presence, truncate(warning_preset.text)].compact.join(' - ') }, wrapper: :with_block_label .fields-group = f.input :text, as: :text, wrapper: :with_block_label, hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index a30b78db2c..744d17d1fa 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -96,10 +96,17 @@ = table_link_to 'angle-double-down', t('admin.accounts.demote'), demote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:demote, @account.user) %tr - %th= t('admin.accounts.email') - %td= @account.user_email + %th{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= t('admin.accounts.email') + %td{ rowspan: can?(:create, :email_domain_block) ? 3 : 2 }= @account.user_email %td= table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(@account.id) if can?(:change_email, @account.user) + %tr + %td= table_link_to 'search', t('admin.accounts.search_same_email_domain'), admin_accounts_path(email: "%@#{@account.user_email.split('@').last}") + + - if can?(:create, :email_domain_block) + %tr + %td= table_link_to 'ban', t('admin.accounts.add_email_domain_block'), new_admin_email_domain_block_path(_domain: @account.user_email.split('@').last) + - if @account.user_unconfirmed_email.present? %tr %th= t('admin.accounts.unconfirmed_email') @@ -204,7 +211,7 @@ = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@account.id, type: 'suspend'), class: 'button button--destructive' if can?(:suspend, @account) - unless @account.local? - - if DomainBlock.where(domain: @account.domain).exists? + - if DomainBlock.rule_for(@account.domain) = link_to t('admin.domain_blocks.view'), admin_instance_path(@account.domain), class: 'button' - else = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @account.domain), class: 'button button--destructive' diff --git a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml index bf66c9001d..41ab8c1712 100644 --- a/app/views/admin/email_domain_blocks/_email_domain_block.html.haml +++ b/app/views/admin/email_domain_blocks/_email_domain_block.html.haml @@ -3,3 +3,13 @@ %samp= email_domain_block.domain %td = table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(email_domain_block), method: :delete + +- email_domain_block.children.each do |child_email_domain_block| + %tr + %td + %samp= child_email_domain_block.domain + %span.muted-hint + = surround '(', ')' do + = t('admin.email_domain_blocks.from_html', domain: content_tag(:samp, email_domain_block.domain)) + %td + = table_link_to 'trash', t('admin.email_domain_blocks.delete'), admin_email_domain_block_path(child_email_domain_block), method: :delete diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml index f372fa5120..4a346f2406 100644 --- a/app/views/admin/email_domain_blocks/new.html.haml +++ b/app/views/admin/email_domain_blocks/new.html.haml @@ -5,7 +5,10 @@ = render 'shared/error_messages', object: @email_domain_block .fields-group - = f.input :domain, wrapper: :with_label, label: t('admin.email_domain_blocks.domain') + = f.input :domain, wrapper: :with_block_label, label: t('admin.email_domain_blocks.domain') + + .fields-group + = f.input :with_dns_records, as: :boolean, wrapper: :with_label .actions = f.button :button, t('.create'), type: :submit diff --git a/app/views/admin/warning_presets/_warning_preset.html.haml b/app/views/admin/warning_presets/_warning_preset.html.haml new file mode 100644 index 0000000000..a58199c804 --- /dev/null +++ b/app/views/admin/warning_presets/_warning_preset.html.haml @@ -0,0 +1,10 @@ +.announcements-list__item + = link_to edit_admin_warning_preset_path(warning_preset), class: 'announcements-list__item__title' do + = warning_preset.title.presence || truncate(warning_preset.text) + + .announcements-list__item__action-bar + .announcements-list__item__meta + = truncate(warning_preset.text) + + %div + = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(warning_preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, warning_preset) diff --git a/app/views/admin/warning_presets/edit.html.haml b/app/views/admin/warning_presets/edit.html.haml index 9522746cd1..b5c5107ef4 100644 --- a/app/views/admin/warning_presets/edit.html.haml +++ b/app/views/admin/warning_presets/edit.html.haml @@ -4,6 +4,9 @@ = simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |f| = render 'shared/error_messages', object: @warning_preset + .fields-group + = f.input :title, wrapper: :with_block_label + .fields-group = f.input :text, wrapper: :with_block_label diff --git a/app/views/admin/warning_presets/index.html.haml b/app/views/admin/warning_presets/index.html.haml index 45913ef733..dbc23fa308 100644 --- a/app/views/admin/warning_presets/index.html.haml +++ b/app/views/admin/warning_presets/index.html.haml @@ -5,6 +5,9 @@ = simple_form_for @warning_preset, url: admin_warning_presets_path do |f| = render 'shared/error_messages', object: @warning_preset + .fields-group + = f.input :title, wrapper: :with_block_label + .fields-group = f.input :text, wrapper: :with_block_label @@ -13,18 +16,9 @@ %hr.spacer/ -- unless @warning_presets.empty? - .table-wrapper - %table.table - %thead - %tr - %th= t('simple_form.labels.account_warning_preset.text') - %th - %tbody - - @warning_presets.each do |preset| - %tr - %td - = Formatter.instance.linkify(preset.text) - %td - = table_link_to 'pencil', t('admin.warning_presets.edit'), edit_admin_warning_preset_path(preset) - = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } +- if @warning_presets.empty? + %div.muted-hint.center-text + = t 'admin.warning_presets.empty' +- else + .announcements-list + = render partial: 'warning_preset', collection: @warning_presets diff --git a/app/workers/backup_worker.rb b/app/workers/backup_worker.rb index e4c609d706..7b0b52844d 100644 --- a/app/workers/backup_worker.rb +++ b/app/workers/backup_worker.rb @@ -9,8 +9,12 @@ class BackupWorker backup_id = msg['args'].first ActiveRecord::Base.connection_pool.with_connection do - backup = Backup.find(backup_id) - backup&.destroy + begin + backup = Backup.find(backup_id) + backup.destroy + rescue ActiveRecord::RecordNotFound + true + end end end diff --git a/app/workers/post_process_media_worker.rb b/app/workers/post_process_media_worker.rb new file mode 100644 index 0000000000..d3ebda194a --- /dev/null +++ b/app/workers/post_process_media_worker.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +class PostProcessMediaWorker + include Sidekiq::Worker + + sidekiq_options retry: 1, dead: false + + sidekiq_retries_exhausted do |msg| + media_attachment_id = msg['args'].first + + ActiveRecord::Base.connection_pool.with_connection do + begin + media_attachment = MediaAttachment.find(media_attachment_id) + media_attachment.processing = :failed + media_attachment.save + rescue ActiveRecord::RecordNotFound + true + end + end + + Sidekiq.logger.error("Processing media attachment #{media_attachment_id} failed with #{msg['error_message']}") + end + + def perform(media_attachment_id) + media_attachment = MediaAttachment.find(media_attachment_id) + media_attachment.processing = :in_progress + media_attachment.save + media_attachment.file.reprocess_original! + media_attachment.processing = :complete + media_attachment.save + rescue ActiveRecord::RecordNotFound + true + end +end diff --git a/config/application.rb b/config/application.rb index 1baa166ce6..cd599eefce 100644 --- a/config/application.rb +++ b/config/application.rb @@ -7,6 +7,7 @@ require 'rails/all' Bundler.require(*Rails.groups) require_relative '../app/lib/exceptions' +require_relative '../lib/paperclip/attachment_extensions' require_relative '../lib/paperclip/lazy_thumbnail' require_relative '../lib/paperclip/gif_transcoder' require_relative '../lib/paperclip/video_transcoder' diff --git a/config/deploy.rb b/config/deploy.rb index 4dc36c65c2..79550baedf 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -lock '3.11.2' +lock '3.12.1' set :repo_url, ENV.fetch('REPO', 'https://github.com/tootsuite/mastodon.git') set :branch, ENV.fetch('BRANCH', 'master') diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 7f8a40d7ba..288453a046 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -19,4 +19,4 @@ Sidekiq.configure_client do |config| config.redis = redis_params end -Sidekiq::Logging.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s) +Sidekiq.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index f5a6f067db..5c73967d69 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -562,7 +562,6 @@ ar: warning_presets: add_new: إضافة واحد جديد delete: حذف - edit: تعديل edit_preset: تعديل نموذج التحذير title: إدارة نماذج التحذير admin_mailer: diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 1c30b6b7a7..22782ae162 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -573,7 +573,6 @@ ca: warning_presets: add_new: Afegeix-ne un de nou delete: Esborra - edit: Edita edit_preset: Edita l'avís predeterminat title: Gestiona les configuracions predefinides dels avisos admin_mailer: diff --git a/config/locales/co.yml b/config/locales/co.yml index 24f7f45fc9..d9127a385b 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -573,7 +573,6 @@ co: warning_presets: add_new: Aghjunghje delete: Sguassà - edit: Cambià edit_preset: Cambià a preselezzione d'avertimentu title: Amministrà e preselezzione d'avertimentu admin_mailer: diff --git a/config/locales/cs.yml b/config/locales/cs.yml index bab669e7e7..23161ec5cb 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -588,7 +588,6 @@ cs: warning_presets: add_new: Přidat nové delete: Smazat - edit: Upravit edit_preset: Upravit předlohu pro varování title: Spravovat předlohy pro varování admin_mailer: diff --git a/config/locales/cy.yml b/config/locales/cy.yml index afca0212a0..a9e8a26da6 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -605,7 +605,6 @@ cy: warning_presets: add_new: Ychwanegu newydd delete: Dileu - edit: Golygu edit_preset: Golygu rhagosodiad rhybudd title: Rheoli rhagosodiadau rhybudd admin_mailer: diff --git a/config/locales/da.yml b/config/locales/da.yml index 1cdf7722e3..c978029b3f 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -489,7 +489,6 @@ da: most_recent: Seneste warning_presets: delete: Slet - edit: Rediger admin_mailer: new_report: body: "%{reporter} har anmeldt %{target}" diff --git a/config/locales/de.yml b/config/locales/de.yml index 50f9944733..6907efc60d 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -573,7 +573,6 @@ de: warning_presets: add_new: Neu hinzufügen delete: Löschen - edit: Bearbeiten edit_preset: Warnungsvorlage bearbeiten title: Warnungsvorlagen verwalten admin_mailer: diff --git a/config/locales/el.yml b/config/locales/el.yml index 85c7bc6483..dd9c93172f 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -573,7 +573,6 @@ el: warning_presets: add_new: Πρόσθεση νέου delete: Διαγραφή - edit: Ενημέρωση edit_preset: Ενημέρωση προκαθορισμένης προειδοποίησης title: Διαχείριση προκαθορισμένων προειδοποιήσεων admin_mailer: diff --git a/config/locales/en.yml b/config/locales/en.yml index a1dc1c3266..f07a554f12 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -92,6 +92,7 @@ en: delete: Delete destroyed_msg: Moderation note successfully destroyed! accounts: + add_email_domain_block: Blacklist e-mail domain approve: Approve approve_all: Approve all are_you_sure: Are you sure? @@ -172,6 +173,7 @@ en: staff: Staff user: User search: Search + search_same_email_domain: Other users with the same e-mail domain search_same_ip: Other users with the same IP shared_inbox_url: Shared inbox URL show: @@ -359,6 +361,7 @@ en: destroyed_msg: Successfully deleted e-mail domain from blacklist domain: Domain empty: No e-mail domains currently blacklisted. + from_html: from %{domain} new: create: Add domain title: New e-mail blacklist entry @@ -589,7 +592,6 @@ en: warning_presets: add_new: Add new delete: Delete - edit: Edit edit_preset: Edit warning preset title: Manage warning presets admin_mailer: @@ -867,6 +869,7 @@ en: media_attachments: validations: images_and_video: Cannot attach a video to a status that already contains images + not_ready: Cannot attach files that have not finished processing. Try again in a moment! too_many: Cannot attach more than 4 files migrations: acct: Moved to diff --git a/config/locales/en_GB.yml b/config/locales/en_GB.yml index 0742559edd..1375ebb33e 100644 --- a/config/locales/en_GB.yml +++ b/config/locales/en_GB.yml @@ -474,7 +474,6 @@ en_GB: warning_presets: add_new: Add new delete: Delete - edit: Edit edit_preset: Edit warning preset title: Manage warning presets admin_mailer: diff --git a/config/locales/eo.yml b/config/locales/eo.yml index b3cb2b5232..32771b4c44 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -557,7 +557,6 @@ eo: warning_presets: add_new: Aldoni novan delete: Forigi - edit: Redakti edit_preset: Redakti avertan antaŭagordon title: Administri avertajn antaŭagordojn admin_mailer: diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 6eec00cb69..67fb83de27 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -573,7 +573,6 @@ es-AR: warning_presets: add_new: Agregar nuevo delete: Eliminar - edit: Editar edit_preset: Editar preajuste de advertencia title: Administrar preajustes de advertencia admin_mailer: diff --git a/config/locales/es.yml b/config/locales/es.yml index a261430182..3acf29b155 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -573,7 +573,6 @@ es: warning_presets: add_new: Añadir nuevo delete: Borrar - edit: Editar edit_preset: Editar aviso predeterminado title: Editar configuración predeterminada de avisos admin_mailer: diff --git a/config/locales/et.yml b/config/locales/et.yml index 716da90101..8e3d566224 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -576,7 +576,6 @@ et: warning_presets: add_new: Lisa uus delete: Kustuta - edit: Redigeeri edit_preset: Redigeeri hoiatuse eelseadistust title: Halda hoiatuste eelseadistusi admin_mailer: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 3ca68d321e..e44fc61b00 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -573,7 +573,6 @@ eu: warning_presets: add_new: Gehitu berria delete: Ezabatu - edit: Editatu edit_preset: Editatu abisu aurre-ezarpena title: Kudeatu abisu aurre-ezarpenak admin_mailer: diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 02bbd29381..aca4df69bb 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -575,7 +575,6 @@ fa: warning_presets: add_new: افزودن تازه delete: زدودن - edit: ویرایش edit_preset: ویرایش هشدار پیش‌فرض title: مدیریت هشدارهای پیش‌فرض admin_mailer: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index bf79bc0ff4..c1d8cc2bf3 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -573,7 +573,6 @@ fr: warning_presets: add_new: Ajouter un nouveau delete: Effacer - edit: Éditer edit_preset: Éditer les avertissements prédéfinis title: Gérer les avertissements prédéfinis admin_mailer: diff --git a/config/locales/gl.yml b/config/locales/gl.yml index c3a33932d9..9f0f16b5bf 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -573,7 +573,6 @@ gl: warning_presets: add_new: Engadir novo delete: Eliminar - edit: Editar edit_preset: Editar aviso preestablecido title: Xestionar avisos preestablecidos admin_mailer: diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 2d7f3a137c..c6b619dd26 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -575,7 +575,6 @@ hu: warning_presets: add_new: Új hozzáadása delete: Törlés - edit: Szerkesztés edit_preset: Figyelmeztetés szerkesztése title: Figyelmeztetések admin_mailer: diff --git a/config/locales/id.yml b/config/locales/id.yml index ca222946cb..bfa71184fd 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -565,7 +565,6 @@ id: warning_presets: add_new: Tambah baru delete: Hapus - edit: Sunting edit_preset: Sunting preset peringatan title: Kelola preset peringatan admin_mailer: diff --git a/config/locales/is.yml b/config/locales/is.yml index d6cf23966d..336533d52b 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -573,7 +573,6 @@ is: warning_presets: add_new: Bæta við nýju delete: Eyða - edit: Breyta edit_preset: Breyta forstilltri aðvörun title: Sýsla með forstilltar aðvaranir admin_mailer: diff --git a/config/locales/it.yml b/config/locales/it.yml index 2ccdc076cd..636ae89244 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -573,7 +573,6 @@ it: warning_presets: add_new: Aggiungi nuovo delete: Cancella - edit: Modifica edit_preset: Modifica avviso predefinito title: Gestisci avvisi predefiniti admin_mailer: diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 00e76a8da5..130ad250d5 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -565,7 +565,6 @@ ja: warning_presets: add_new: 追加 delete: 削除 - edit: 編集 edit_preset: プリセット警告文を編集 title: プリセット警告文を管理 admin_mailer: diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 03f4d8c13d..b398bebd9c 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -330,7 +330,6 @@ kab: warning_presets: add_new: Rnu amaynut delete: Kkes - edit: Ẓreg admin_mailer: new_report: subject: Aneqqis amaynut i %{instance} (#%{id}) diff --git a/config/locales/kk.yml b/config/locales/kk.yml index 416a5fc7dc..bb7a57e878 100644 --- a/config/locales/kk.yml +++ b/config/locales/kk.yml @@ -555,7 +555,6 @@ kk: warning_presets: add_new: Add nеw delete: Deletе - edit: Еdit edit_preset: Edit warning prеset title: Manage warning presеts admin_mailer: diff --git a/config/locales/ko.yml b/config/locales/ko.yml index e70fbef21c..6ca0b2acc0 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -567,7 +567,6 @@ ko: warning_presets: add_new: 새로 추가 delete: 삭제 - edit: 편집 edit_preset: 경고 틀 수정 title: 경고 틀 관리 admin_mailer: diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 9af094c019..5a4542ea8c 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -410,7 +410,6 @@ lt: warning_presets: add_new: Pridėti naują delete: Ištrinti - edit: Keisti edit_preset: Keisti įspėjimo nustatymus title: Valdyti įspėjimo nustatymus admin_mailer: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 976072368a..f688d5dbdb 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -573,7 +573,6 @@ nl: warning_presets: add_new: Nieuwe toevoegen delete: Verwijderen - edit: Bewerken edit_preset: Voorinstelling van waarschuwing bewerken title: Voorinstellingen van waarschuwingen beheren admin_mailer: diff --git a/config/locales/nn.yml b/config/locales/nn.yml index fd61f2156f..07b6397c6d 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -566,7 +566,6 @@ nn: warning_presets: add_new: Legg til ny delete: Slett - edit: Rediger edit_preset: Endr åtvaringsoppsett title: Handsam åtvaringsoppsett admin_mailer: diff --git a/config/locales/no.yml b/config/locales/no.yml index 256ed99a37..4a1b859dc0 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -561,7 +561,6 @@ warning_presets: add_new: Legg til ny delete: Slett - edit: Rediger admin_mailer: new_pending_account: body: Detaljer om den nye kontoen er nedenfor. Du kan godkjenne eller avvise denne søknaden. diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 4a60227ab6..d3f3a10073 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -558,7 +558,6 @@ oc: warning_presets: add_new: N’ajustar un nòu delete: Escafar - edit: Modificar edit_preset: Modificar lo tèxt predefinit d’avertiment title: Gerir los tèxtes predefinits admin_mailer: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 6f04720c55..4281153f02 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -541,7 +541,6 @@ pl: warning_presets: add_new: Dodaj nowy delete: Usuń - edit: Edytuj edit_preset: Edytuj szablon ostrzeżenia title: Zarządzaj szablonami ostrzeżeń admin_mailer: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index abea40130c..419ea5a73f 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -573,7 +573,6 @@ pt-BR: warning_presets: add_new: Adicionar novo delete: Excluir - edit: Editar edit_preset: Editar o aviso pré-definido title: Gerenciar os avisos pré-definidos admin_mailer: diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 477c9d3a36..9d3a503b14 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -573,7 +573,6 @@ pt-PT: warning_presets: add_new: Adicionar novo delete: Apagar - edit: Editar edit_preset: Editar o aviso predefinido title: Gerir os avisos predefinidos admin_mailer: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 6196ac3ebd..f1547ddf28 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -594,7 +594,6 @@ ru: warning_presets: add_new: Добавить delete: Удалить - edit: Изменить edit_preset: Удалить шаблон предупреждения title: Управление шаблонами предупреждений admin_mailer: diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index cf8f7120dc..141ef574b4 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -8,6 +8,7 @@ en: acct: Specify the username@domain of the account you want to move to account_warning_preset: text: You can use toot syntax, such as URLs, hashtags and mentions + title: Optional. Not visible to the recipient admin_account_action: include_statuses: The user will see which toots have caused the moderation action or warning send_email_notification: The user will receive an explanation of what happened with their account @@ -58,6 +59,9 @@ en: whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word domain_allow: domain: This domain will be able to fetch data from this server and incoming data from it will be processed and stored + email_domain_block: + domain: This can be the domain name that shows up in the e-mail address, the MX record that domain resolves to, or IP of the server that MX record resolves to. Those will be checked upon user sign-up and the sign-up will be rejected. + with_dns_records: An attempt to resolve the given domain's DNS records will be made and the results will also be blacklisted featured_tag: name: 'You might want to use one of these:' form_challenge: @@ -83,6 +87,7 @@ en: acct: Handle of the new account account_warning_preset: text: Preset text + title: Title admin_account_action: include_statuses: Include reported toots in the e-mail send_email_notification: Notify the user per e-mail @@ -163,6 +168,8 @@ en: username: Username username_or_email: Username or Email whole_word: Whole word + email_domain_block: + with_dns_records: Include MX records and IPs of the domain featured_tag: name: Hashtag interactions: diff --git a/config/locales/sk.yml b/config/locales/sk.yml index dbee6bb12f..2986f83d8c 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -574,7 +574,6 @@ sk: warning_presets: add_new: Pridaj nové delete: Vymaž - edit: Uprav edit_preset: Uprav varovnú predlohu title: Spravuj varovné predlohy admin_mailer: diff --git a/config/locales/sl.yml b/config/locales/sl.yml index afb928f117..91720c6028 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -485,7 +485,6 @@ sl: warning_presets: add_new: Dodaj novo delete: Izbriši - edit: Uredi edit_preset: Uredi prednastavitev opozoril title: Upravljaj prednastavitev opozoril admin_mailer: diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 6a7a945c4e..0e20902ff7 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -415,7 +415,6 @@ sq: warning_presets: add_new: Shtoni të ri delete: Fshije - edit: Përpunoni edit_preset: Përpunoni sinjalizim të paracaktuar title: Administroni sinjalizime të paracaktuara admin_mailer: diff --git a/config/locales/sr.yml b/config/locales/sr.yml index c686812157..d7fb6f74d6 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -431,7 +431,6 @@ sr: warning_presets: add_new: Додај нови delete: Избриши - edit: Уреди edit_preset: Уреди пресет упозорења title: Управљај пресетима упозорења admin_mailer: diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 0094ff06bc..4b67ff19ca 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -448,7 +448,6 @@ sv: warning_presets: add_new: Lägg till ny delete: Radera - edit: Redigera admin_mailer: new_report: body: "%{reporter} har rapporterat %{target}" diff --git a/config/locales/th.yml b/config/locales/th.yml index 7d6ec0b136..53267c8052 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -488,7 +488,6 @@ th: warning_presets: add_new: เพิ่มใหม่ delete: ลบ - edit: แก้ไข edit_preset: แก้ไขคำเตือนที่ตั้งไว้ล่วงหน้า title: จัดการคำเตือนที่ตั้งไว้ล่วงหน้า admin_mailer: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index cde7f1c83f..1dcf9cceaa 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -573,7 +573,6 @@ tr: warning_presets: add_new: Yeni ekle delete: Sil - edit: Düzenle edit_preset: Uyarı ön-ayarını düzenle title: Uyarı ön-ayarlarını yönet admin_mailer: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 967a027174..3df83e7560 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -591,7 +591,6 @@ uk: warning_presets: add_new: Додати новий delete: Видалити - edit: Редагувати edit_preset: Редагувати шаблон попередження title: Управління шаблонами попереджень admin_mailer: diff --git a/config/locales/vi.yml b/config/locales/vi.yml index ec8e853fe8..cba7734178 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -534,7 +534,6 @@ vi: warning_presets: add_new: Thêm mới delete: Xóa bỏ - edit: Biên tập edit_preset: Chỉnh sửa cảnh báo đặt trước title: Quản lý cài đặt trước cảnh báo admin_mailer: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index d6618dbbe2..54230fb2f0 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -565,7 +565,6 @@ zh-CN: warning_presets: add_new: 添加新条目 delete: 删除 - edit: 编辑 edit_preset: 编辑预置警告 title: 管理预设警告 admin_mailer: diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index ffd5ba5e95..fd988e443d 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -409,7 +409,6 @@ zh-HK: warning_presets: add_new: 新增 delete: 刪除 - edit: 編輯 admin_mailer: new_report: body: "%{reporter} 舉報了用戶 %{target}" diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 5b25688edb..984bbcf13e 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -408,7 +408,6 @@ zh-TW: warning_presets: add_new: 新增 delete: 刪除 - edit: 編輯 admin_mailer: new_report: body: "%{reporter} 檢舉了使用者 %{target}" diff --git a/config/routes.rb b/config/routes.rb index 103abc6c15..7530c5b1fc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -346,7 +346,7 @@ Rails.application.routes.draw do end end - resources :media, only: [:create, :update] + resources :media, only: [:create, :update, :show] resources :blocks, only: [:index] resources :mutes, only: [:index] do collection do @@ -463,6 +463,7 @@ Rails.application.routes.draw do end namespace :v2 do + resources :media, only: [:create] get '/search', to: 'search#index', as: :search end diff --git a/db/migrate/20191212163405_add_hide_collections_to_accounts.rb b/db/migrate/20191212163405_add_hide_collections_to_accounts.rb new file mode 100644 index 0000000000..fa99b32e5c --- /dev/null +++ b/db/migrate/20191212163405_add_hide_collections_to_accounts.rb @@ -0,0 +1,5 @@ +class AddHideCollectionsToAccounts < ActiveRecord::Migration[5.2] + def change + add_column :accounts, :hide_collections, :boolean + end +end diff --git a/db/migrate/20200306035625_add_processing_to_media_attachments.rb b/db/migrate/20200306035625_add_processing_to_media_attachments.rb new file mode 100644 index 0000000000..131ffa52ae --- /dev/null +++ b/db/migrate/20200306035625_add_processing_to_media_attachments.rb @@ -0,0 +1,5 @@ +class AddProcessingToMediaAttachments < ActiveRecord::Migration[5.2] + def change + add_column :media_attachments, :processing, :integer + end +end diff --git a/db/migrate/20200312144258_add_title_to_account_warning_presets.rb b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb new file mode 100644 index 0000000000..46a5350e7c --- /dev/null +++ b/db/migrate/20200312144258_add_title_to_account_warning_presets.rb @@ -0,0 +1,15 @@ +require Rails.root.join('lib', 'mastodon', 'migration_helpers') + +class AddTitleToAccountWarningPresets < ActiveRecord::Migration[5.2] + include Mastodon::MigrationHelpers + + disable_ddl_transaction! + + def up + safety_assured { add_column_with_default :account_warning_presets, :title, :string, default: '', allow_null: false } + end + + def down + remove_column :account_warning_presets, :title + end +end diff --git a/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb b/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb new file mode 100644 index 0000000000..03915040c8 --- /dev/null +++ b/db/migrate/20200312185443_add_parent_id_to_email_domain_blocks.rb @@ -0,0 +1,5 @@ +class AddParentIdToEmailDomainBlocks < ActiveRecord::Migration[5.2] + def change + add_reference :email_domain_blocks, :parent, null: true, default: nil, foreign_key: { on_delete: :cascade, to_table: :email_domain_blocks }, index: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 73ac78b809..392cc739ca 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_01_26_203551) do +ActiveRecord::Schema.define(version: 2020_03_12_185443) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -114,6 +114,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do t.text "text", default: "", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "title", default: "", null: false end create_table "account_warnings", force: :cascade do |t| @@ -170,6 +171,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do t.datetime "silenced_at" t.datetime "suspended_at" t.integer "trust_level" + t.boolean "hide_collections" t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower", unique: true t.index ["moved_to_account_id"], name: "index_accounts_on_moved_to_account_id" @@ -334,6 +336,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do t.string "domain", default: "", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.bigint "parent_id" t.index ["domain"], name: "index_email_domain_blocks_on_domain", unique: true end @@ -460,6 +463,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do t.text "description" t.bigint "scheduled_status_id" t.string "blurhash" + t.integer "processing" t.index ["account_id"], name: "index_media_attachments_on_account_id" t.index ["scheduled_status_id"], name: "index_media_attachments_on_scheduled_status_id" t.index ["shortcode"], name: "index_media_attachments_on_shortcode", unique: true @@ -869,6 +873,7 @@ ActiveRecord::Schema.define(version: 2020_01_26_203551) do add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade add_foreign_key "conversation_mutes", "conversations", on_delete: :cascade add_foreign_key "custom_filters", "accounts", on_delete: :cascade + add_foreign_key "email_domain_blocks", "email_domain_blocks", column: "parent_id", on_delete: :cascade add_foreign_key "favourites", "accounts", name: "fk_5eb6c2b873", on_delete: :cascade add_foreign_key "favourites", "statuses", name: "fk_b0e856845e", on_delete: :cascade add_foreign_key "featured_tags", "accounts", on_delete: :cascade diff --git a/lib/paperclip/attachment_extensions.rb b/lib/paperclip/attachment_extensions.rb new file mode 100644 index 0000000000..3b308af5f9 --- /dev/null +++ b/lib/paperclip/attachment_extensions.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Paperclip + module AttachmentExtensions + # We overwrite this method to support delayed processing in + # Sidekiq. Since we process the original file to reduce disk + # usage, and we still want to generate thumbnails straight + # away, it's the only style we need to exclude + def process_style?(style_name, style_args) + if style_name == :original && instance.respond_to?(:delay_processing?) && instance.delay_processing? + false + else + style_args.empty? || style_args.include?(style_name) + end + end + + def reprocess_original! + old_original_path = path(:original) + reprocess!(:original) + new_original_path = path(:original) + + if new_original_path != old_original_path + @queued_for_delete << old_original_path + flush_deletes + end + end + end +end + +Paperclip::Attachment.prepend(Paperclip::AttachmentExtensions) diff --git a/lib/paperclip/video_transcoder.rb b/lib/paperclip/video_transcoder.rb index 66f7feda56..4d9544231e 100644 --- a/lib/paperclip/video_transcoder.rb +++ b/lib/paperclip/video_transcoder.rb @@ -5,12 +5,22 @@ module Paperclip # to check when uploaded videos are actually gifv's class VideoTranscoder < Paperclip::Processor def make - meta = ::Av.cli.identify(@file.path) + movie = FFMPEG::Movie.new(@file.path) - attachment.instance.type = MediaAttachment.types[:gifv] unless meta[:audio_encode] - options[:format] = File.extname(attachment.instance.file_file_name)[1..-1] if options[:keep_same_format] + attachment.instance.type = MediaAttachment.types[:gifv] unless movie.audio_codec - Paperclip::Transcoder.make(file, options, attachment) + Paperclip::Transcoder.make(file, actual_options(movie), attachment) + end + + private + + def actual_options(movie) + opts = options[:passthrough_options] + if opts && opts[:video_codecs].include?(movie.video_codec) && opts[:audio_codecs].include?(movie.audio_codec) && opts[:colorspaces].include?(movie.colorspace) + opts[:options] + else + options + end end end end diff --git a/package.json b/package.json index 9e221eefaf..be4eb877f1 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "classnames": "^2.2.5", "compression-webpack-plugin": "^3.1.0", "copy-webpack-plugin": "^5.1.1", - "cross-env": "^6.0.3", + "cross-env": "^7.0.2", "css-loader": "^3.4.2", "cssnano": "^4.1.10", "detect-passive-events": "^1.0.2", @@ -96,7 +96,7 @@ "exif-js": "^2.3.0", "express": "^4.17.1", "favico.js": "^0.3.10", - "file-loader": "^5.0.2", + "file-loader": "^5.1.0", "font-awesome": "^4.7.0", "glob": "^7.1.6", "history": "^4.10.1", @@ -113,7 +113,7 @@ "mark-loader": "^0.1.6", "marky": "^1.2.1", "mini-css-extract-plugin": "^0.9.0", - "mkdirp": "^0.5.1", + "mkdirp": "^1.0.3", "npmlog": "^4.1.2", "object-assign": "^4.1.1", "object-fit-images": "^3.2.3", @@ -126,11 +126,11 @@ "promise.prototype.finally": "^3.1.2", "prop-types": "^15.5.10", "punycode": "^2.1.0", - "rails-ujs": "^5.2.4", + "@rails/ujs": "^6.0.2", "react": "^16.12.0", - "react-dom": "^16.12.0", + "react-dom": "^16.13.0", "react-hotkeys": "^1.1.4", - "react-immutable-proptypes": "^2.1.0", + "react-immutable-proptypes": "^2.2.0", "react-immutable-pure-component": "^1.1.1", "react-intl": "^2.9.0", "react-masonry-infinite": "^1.2.2", @@ -146,7 +146,7 @@ "react-swipeable-views": "^0.13.9", "react-textarea-autosize": "^7.1.2", "react-toggle": "^4.1.1", - "redis": "^2.7.1", + "redis": "^3.0.2", "redux": "^4.0.5", "redux-immutable": "^4.0.0", "redux-thunk": "^2.2.0", @@ -154,7 +154,7 @@ "requestidlecallback": "^0.3.0", "reselect": "^4.0.0", "rimraf": "^3.0.2", - "sass": "^1.25.0", + "sass": "^1.26.3", "sass-loader": "^8.0.2", "stacktrace-js": "^2.0.2", "stringz": "^2.0.0", @@ -170,22 +170,22 @@ "webpack-bundle-analyzer": "^3.6.0", "webpack-cli": "^3.3.11", "webpack-merge": "^4.2.1", - "wicg-inert": "^3.0.0" + "wicg-inert": "^3.0.2" }, "devDependencies": { "babel-eslint": "^10.0.3", - "babel-jest": "^24.9.0", + "babel-jest": "^25.1.0", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", "eslint": "^6.8.0", "eslint-plugin-import": "~2.20.1", "eslint-plugin-jsx-a11y": "~6.2.3", "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.17.0", + "eslint-plugin-react": "~7.19.0", "jest": "^24.9.0", "raf": "^3.4.1", "react-intl-translations-manager": "^5.0.3", - "react-test-renderer": "^16.12.0", + "react-test-renderer": "^16.13.0", "sass-lint": "^1.13.1", "webpack-dev-server": "^3.10.3", "yargs": "^15.1.0" diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb index b428299eeb..49d3e97074 100644 --- a/spec/controllers/admin/reports_controller_spec.rb +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -46,6 +46,26 @@ describe Admin::ReportsController do end end + describe 'POST #resolve' do + it 'resolves the report' do + report = Fabricate(:report) + + put :resolve, params: { id: report } + expect(response).to redirect_to(admin_reports_path) + report.reload + expect(report.action_taken_by_account).to eq user.account + expect(report.action_taken).to eq true + end + + it 'sets trust level when the report is an antispam one' do + report = Fabricate(:report, account: Account.representative) + + put :resolve, params: { id: report } + report.reload + expect(report.target_account.trust_level).to eq Account::TRUST_LEVELS[:trusted] + end + end + describe 'POST #reopen' do it 'reopens the report' do report = Fabricate(:report) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6fbceca539..40ddf1f95d 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -15,7 +15,7 @@ ActiveRecord::Migration.maintain_test_schema! WebMock.disable_net_connect!(allow: Chewy.settings[:host]) Redis.current = Redis::Namespace.new("mastodon_test#{ENV['TEST_ENV_NUMBER']}", redis: Redis.current) Sidekiq::Testing.inline! -Sidekiq::Logging.logger = nil +Sidekiq.logger = nil Devise::Test::ControllerHelpers.module_eval do alias_method :original_sign_in, :sign_in diff --git a/yarn.lock b/yarn.lock index aaacea1672..f562cf45f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,7 +18,7 @@ invariant "^2.2.4" semver "^5.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.8.6": +"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.5", "@babel/core@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.6.tgz#27d7df9258a45c2e686b6f18b6c659e563aa4636" integrity sha512-Sheg7yEJD51YHAvLEV/7Uvw95AeWqYPL3Vk3zGujJKIhJ+8oLw2ALaf3hbucILhKsgSoADOvtKRJuNVdcJkOrg== @@ -261,7 +261,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.8.6": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.7.5", "@babel/parser@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.6.tgz#ba5c9910cddb77685a008e3c587af8d27b67962c" integrity sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g== @@ -355,6 +355,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-bigint@^7.0.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + "@babel/plugin-syntax-decorators@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz#8d2c15a9f1af624b0025f961682a9d53d3001bda" @@ -787,6 +794,14 @@ "@babel/plugin-transform-react-jsx-self" "^7.8.3" "@babel/plugin-transform-react-jsx-source" "^7.8.3" +"@babel/runtime-corejs3@^7.8.3": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.8.7.tgz#8209d9dff2f33aa2616cb319c83fe159ffb07b8c" + integrity sha512-sc7A+H4I8kTd7S61dgB9RomXu/C+F4IrRr4Ytze4dnfx7AXEpCrejSNpjx7vq6y/Bak9S6Kbk65a/WgMLtg43Q== + dependencies: + core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + "@babel/runtime@7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c" @@ -808,7 +823,7 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/template@^7.0.0", "@babel/template@^7.8.3", "@babel/template@^7.8.6": +"@babel/template@^7.0.0", "@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== @@ -817,7 +832,7 @@ "@babel/parser" "^7.8.6" "@babel/types" "^7.8.6" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== @@ -936,6 +951,21 @@ resolved "https://registry.yarnpkg.com/@gamestdio/websocket/-/websocket-0.3.2.tgz#321ba0976ee30fd14e51dbf8faa85ce7b325f76a" integrity sha512-J3n5SKim+ZoLbe44hRGI/VYAwSMCeIJuBy+FfP6EZaujEpNchPRFcIsVQLWAwpU1bP2Ji63rC+rEUOd1vjUB6Q== +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" + integrity sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" + integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + "@jest/console@^24.7.1": version "24.7.1" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" @@ -1093,6 +1123,28 @@ source-map "^0.6.1" write-file-atomic "2.4.1" +"@jest/transform@^25.1.0": + version "25.1.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.1.0.tgz#221f354f512b4628d88ce776d5b9e601028ea9da" + integrity sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^25.1.0" + babel-plugin-istanbul "^6.0.0" + chalk "^3.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.3" + jest-haste-map "^25.1.0" + jest-regex-util "^25.1.0" + jest-util "^25.1.0" + micromatch "^4.0.2" + pirates "^4.0.1" + realpath-native "^1.1.0" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + "@jest/types@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" @@ -1102,6 +1154,21 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" +"@jest/types@^25.1.0": + version "25.1.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.1.0.tgz#b26831916f0d7c381e11dbb5e103a72aed1b4395" + integrity sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + +"@rails/ujs@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-6.0.2.tgz#8d32452d51c5e115374a218fb5475803dc17f4c0" + integrity sha512-KSQjJG8yzSWC1IT+UtFQglefABU37hpJ7uAz39K1/iWtoaJaI9ydGIaxxpJBT/PmYv4kS6lCSjXq13DELeJocw== + "@types/babel__core@^7.1.0", "@types/babel__core@^7.1.2": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" @@ -1218,6 +1285,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^15.0.0": + version "15.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" + integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg== + dependencies: + "@types/yargs-parser" "*" + "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -1571,6 +1645,14 @@ ansi-styles@^4.0.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1587,6 +1669,14 @@ anymatch@^3.0.1: normalize-path "^3.0.0" picomatch "^2.0.4" +anymatch@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -1848,6 +1938,19 @@ babel-jest@^24.9.0: chalk "^2.4.2" slash "^2.0.0" +babel-jest@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.1.0.tgz#206093ac380a4b78c4404a05b3277391278f80fb" + integrity sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg== + dependencies: + "@jest/transform" "^25.1.0" + "@jest/types" "^25.1.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^25.1.0" + chalk "^3.0.0" + slash "^3.0.0" + babel-loader@^8.0.6: version "8.0.6" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" @@ -1890,6 +1993,17 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.0.0" test-exclude "^5.0.0" +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" + babel-plugin-jest-hoist@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" @@ -1897,6 +2011,13 @@ babel-plugin-jest-hoist@^24.9.0: dependencies: "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz#fb62d7b3b53eb36c97d1bc7fec2072f9bd115981" + integrity sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw== + dependencies: + "@types/babel__traverse" "^7.0.6" + babel-plugin-lodash@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz#4f6844358a1340baed182adbeffa8df9967bc196" @@ -1955,6 +2076,15 @@ babel-preset-jest@^24.9.0: "@babel/plugin-syntax-object-rest-spread" "^7.0.0" babel-plugin-jest-hoist "^24.9.0" +babel-preset-jest@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz#d0aebfebb2177a21cde710996fce8486d34f1d33" + integrity sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ== + dependencies: + "@babel/plugin-syntax-bigint" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^25.1.0" + babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" @@ -2105,7 +2235,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.2: +braces@^3.0.1, braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -2408,6 +2538,14 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -2819,6 +2957,11 @@ core-js-compat@^3.6.2: browserslist "^4.8.3" semver "7.0.0" +core-js-pure@^3.0.0: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a" + integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== + core-js@^2.4.0: version "2.6.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" @@ -2891,12 +3034,12 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-env@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-6.0.3.tgz#4256b71e49b3a40637a0ce70768a6ef5c72ae941" - integrity sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag== +cross-env@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" + integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== dependencies: - cross-spawn "^7.0.0" + cross-spawn "^7.0.1" cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" @@ -2909,7 +3052,7 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== @@ -3330,6 +3473,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= +denque@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" + integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -3521,11 +3669,6 @@ dotenv@^8.2.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== -double-ended-queue@^2.1.0-0: - version "2.1.0-0" - resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" - integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= - duplexer@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" @@ -3596,6 +3739,11 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -3706,7 +3854,7 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.1.1" -es-abstract@^1.13.0, es-abstract@^1.15.0, es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.5.1: +es-abstract@^1.13.0, es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.5.1: version "1.17.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" integrity sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug== @@ -3864,11 +4012,6 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-eslint-plugin@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz#a7a00f15a886957d855feacaafee264f039e62d5" - integrity sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg== - eslint-plugin-import@~2.20.1: version "2.20.1" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3" @@ -3907,21 +4050,23 @@ eslint-plugin-promise@~4.2.1: resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== -eslint-plugin-react@~7.17.0: - version "7.17.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz#a31b3e134b76046abe3cd278e7482bd35a1d12d7" - integrity sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A== +eslint-plugin-react@~7.19.0: + version "7.19.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz#6d08f9673628aa69c5559d33489e855d83551666" + integrity sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ== dependencies: - array-includes "^3.0.3" + array-includes "^3.1.1" doctrine "^2.1.0" - eslint-plugin-eslint-plugin "^2.1.0" has "^1.0.3" jsx-ast-utils "^2.2.3" - object.entries "^1.1.0" - object.fromentries "^2.0.1" - object.values "^1.1.0" + object.entries "^1.1.1" + object.fromentries "^2.0.2" + object.values "^1.1.1" prop-types "^15.7.2" - resolve "^1.13.1" + resolve "^1.15.1" + semver "^6.3.0" + string.prototype.matchall "^4.0.2" + xregexp "^4.3.0" eslint-scope@^4.0.3: version "4.0.3" @@ -4359,12 +4504,12 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" -file-loader@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-5.0.2.tgz#7f3d8b4ac85a5e8df61338cfec95d7405f971caa" - integrity sha512-QMiQ+WBkGLejKe81HU8SZ9PovsU/5uaLo0JdTCEXOYv7i7jfAjHZi1tcwp9tSASJPOmmHZtbdCervFmXMH/Dcg== +file-loader@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-5.1.0.tgz#cb56c070efc0e40666424309bd0d9e45ac6f2bb8" + integrity sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg== dependencies: - loader-utils "^1.2.3" + loader-utils "^1.4.0" schema-utils "^2.5.0" file-type@^10.5.0: @@ -4624,6 +4769,11 @@ fsevents@^2.0.6: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a" integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ== +fsevents@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" + integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -4844,7 +4994,7 @@ graceful-fs@^4.1.6: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graceful-fs@^4.2.2: +graceful-fs@^4.2.2, graceful-fs@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -5370,6 +5520,15 @@ internal-ip@^4.3.0: default-gateway "^4.2.0" ipaddr.js "^1.9.0" +internal-slot@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3" + integrity sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g== + dependencies: + es-abstract "^1.17.0-next.1" + has "^1.0.3" + side-channel "^1.0.2" + interpret@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" @@ -5772,7 +5931,7 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -5834,6 +5993,11 @@ istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba" integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw== +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== + istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971" @@ -5847,6 +6011,19 @@ istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1: istanbul-lib-coverage "^2.0.3" semver "^5.5.0" +istanbul-lib-instrument@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz#61f13ac2c96cfefb076fe7131156cc05907874e6" + integrity sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg== + dependencies: + "@babel/core" "^7.7.5" + "@babel/parser" "^7.7.5" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" + istanbul-lib-report@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4" @@ -6000,6 +6177,24 @@ jest-haste-map@^24.9.0: optionalDependencies: fsevents "^1.2.7" +jest-haste-map@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.1.0.tgz#ae12163d284f19906260aa51fd405b5b2e5a4ad3" + integrity sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw== + dependencies: + "@jest/types" "^25.1.0" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.3" + jest-serializer "^25.1.0" + jest-util "^25.1.0" + jest-worker "^25.1.0" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.1.2" + jest-jasmine2@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" @@ -6076,6 +6271,11 @@ jest-regex-util@^24.9.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== +jest-regex-util@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.1.0.tgz#efaf75914267741838e01de24da07b2192d16d87" + integrity sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w== + jest-resolve-dependencies@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" @@ -6155,6 +6355,11 @@ jest-serializer@^24.9.0: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== +jest-serializer@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.1.0.tgz#73096ba90e07d19dec4a0c1dd89c355e2f129e5d" + integrity sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA== + jest-snapshot@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" @@ -6192,6 +6397,16 @@ jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.1.0.tgz#7bc56f7b2abd534910e9fa252692f50624c897d9" + integrity sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw== + dependencies: + "@jest/types" "^25.1.0" + chalk "^3.0.0" + is-ci "^2.0.0" + mkdirp "^0.5.1" + jest-validate@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" @@ -6530,7 +6745,7 @@ loader-utils@0.2.x: json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: +loader-utils@1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== @@ -6539,6 +6754,15 @@ loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2. emojis-list "^2.0.0" json5 "^1.0.1" +loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -6794,6 +7018,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -6967,6 +7199,11 @@ mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "0.0.8" +mkdirp@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" + integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== + moo@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/moo/-/moo-0.4.3.tgz#3f847a26f31cf625a956a87f2b10fbc013bfd10e" @@ -7345,16 +7582,6 @@ object.entries@^1.1.0, object.entries@^1.1.1: function-bind "^1.1.1" has "^1.0.3" -object.fromentries@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704" - integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.15.0" - function-bind "^1.1.1" - has "^1.0.3" - object.fromentries@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" @@ -7866,6 +8093,11 @@ picomatch@^2.0.4: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== +picomatch@^2.0.5: + version "2.2.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" + integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -8549,11 +8781,6 @@ railroad-diagrams@^1.0.0: resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234= -rails-ujs@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/rails-ujs/-/rails-ujs-5.2.4.tgz#31056ccd62d868f7d044395f31d77a4440550ceb" - integrity sha512-Mzu6bnTBKn4IuJvP7BDJRy4lzvR1zMWVDeTdPwDubXBfxpFEKqwOi5Nb6tfE2SYtTd+bb3PRETf40I94jgKw3w== - randexp@0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" @@ -8602,15 +8829,15 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^16.12.0: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11" - integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw== +react-dom@^16.13.0: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866" + integrity sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.18.0" + scheduler "^0.19.0" react-event-listener@^0.6.0: version "0.6.5" @@ -8632,10 +8859,12 @@ react-hotkeys@^1.1.4: mousetrap "^1.5.2" prop-types "^15.6.0" -react-immutable-proptypes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4" - integrity sha1-Aj1vObsVyXwHHp5g0A0TbqxfoLQ= +react-immutable-proptypes@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz#cce96d68cc3c18e89617cbf3092d08e35126af4a" + integrity sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ== + dependencies: + invariant "^2.2.2" react-immutable-pure-component@^1.1.1: version "1.2.3" @@ -8830,15 +9059,15 @@ react-swipeable-views@^0.13.9: react-swipeable-views-utils "^0.13.9" warning "^4.0.1" -react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0: - version "16.12.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.12.0.tgz#11417ffda579306d4e841a794d32140f3da1b43f" - integrity sha512-Vj/teSqt2oayaWxkbhQ6gKis+t5JrknXfPVo+aIJ8QwYAqMPH77uptOdrlphyxl8eQI/rtkOYg86i/UWkpFu0w== +react-test-renderer@^16.0.0-0, react-test-renderer@^16.13.0: + version "16.13.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.13.0.tgz#39ba3bf72cedc8210c3f81983f0bb061b14a3014" + integrity sha512-NQ2S9gdMUa7rgPGpKGyMcwl1d6D9MCF0lftdI3kts6kkiX+qvpC955jNjAZXlIDTjnN9jwFI8A8XhRh/9v0spA== dependencies: object-assign "^4.1.1" prop-types "^15.6.2" react-is "^16.8.6" - scheduler "^0.18.0" + scheduler "^0.19.0" react-textarea-autosize@^7.1.2: version "7.1.2" @@ -8962,24 +9191,32 @@ realpath-native@^1.1.0: dependencies: util.promisify "^1.0.0" -redis-commands@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.4.0.tgz#52f9cf99153efcce56a8f86af986bd04e988602f" - integrity sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw== +redis-commands@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.5.0.tgz#80d2e20698fe688f227127ff9e5164a7dd17e785" + integrity sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg== -redis-parser@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" - integrity sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs= +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= -redis@^2.7.1: - version "2.8.0" - resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02" - integrity sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A== +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= dependencies: - double-ended-queue "^2.1.0-0" - redis-commands "^1.2.0" - redis-parser "^2.6.0" + redis-errors "^1.0.0" + +redis@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/redis/-/redis-3.0.2.tgz#bd47067b8a4a3e6a2e556e57f71cc82c7360150a" + integrity sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ== + dependencies: + denque "^1.4.1" + redis-commands "^1.5.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" redux-immutable@^4.0.0: version "4.0.0" @@ -9031,6 +9268,11 @@ regenerator-runtime@^0.13.2: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== +regenerator-runtime@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz#e96bf612a3362d12bb69f7e8f74ffeab25c7ac91" + integrity sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g== + regenerator-transform@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.0.tgz#2ca9aaf7a2c239dd32e4761218425b8c7a86ecaf" @@ -9053,6 +9295,14 @@ regexp.prototype.flags@^1.2.0: dependencies: define-properties "^1.1.2" +regexp.prototype.flags@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" + integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -9222,6 +9472,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + resolve-pathname@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879" @@ -9242,10 +9497,10 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16" - integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w== +resolve@^1.12.0, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== dependencies: path-parse "^1.0.6" @@ -9428,10 +9683,10 @@ sass-loader@^8.0.2: schema-utils "^2.6.1" semver "^6.3.0" -sass@^1.25.0: - version "1.25.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.25.0.tgz#f8bd7dfbb39d6b0305e27704a8ebe637820693f3" - integrity sha512-uQMjye0Y70SEDGO56n0j91tauqS9E1BmpKHtiYNQScXDHeaE9uHwNEqQNFf4Bes/3DHMNinB6u79JsG10XWNyw== +sass@^1.26.3: + version "1.26.3" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.26.3.tgz#412df54486143b76b5a65cdf7569e86f44659f46" + integrity sha512-5NMHI1+YFYw4sN3yfKjpLuV9B5l7MqQ6FlkTcC4FT+oHbBRUZoSjHrrt/mE0nFXJyY2kQtU9ou9HxvFVjLFuuw== dependencies: chokidar ">=2.0.0 <4.0.0" @@ -9448,6 +9703,14 @@ scheduler@^0.18.0: loose-envify "^1.1.0" object-assign "^4.1.1" +scheduler@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.0.tgz#a715d56302de403df742f4a9be11975b32f5698d" + integrity sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" @@ -9636,6 +9899,14 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +side-channel@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947" + integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA== + dependencies: + es-abstract "^1.17.0-next.1" + object-inspect "^1.7.0" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -9663,6 +9934,11 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -10021,6 +10297,18 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string.prototype.matchall@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e" + integrity sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + has-symbols "^1.0.1" + internal-slot "^1.0.2" + regexp.prototype.flags "^1.3.0" + side-channel "^1.0.2" + string.prototype.trim@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" @@ -10160,7 +10448,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== @@ -10321,6 +10609,15 @@ test-exclude@^5.0.0: read-pkg-up "^4.0.0" require-main-filename "^1.0.1" +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -10522,6 +10819,13 @@ type@^2.0.0: resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -11024,10 +11328,10 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wicg-inert@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/wicg-inert/-/wicg-inert-3.0.0.tgz#4f5797172fbf7ff01effd3839b52872e35d3cba2" - integrity sha512-sZsYZ8pk8y6CgDLkTxivfhLDBvZuDWTWBawU8OuDdO0Id6AOd1Gqjkvt9g9Ni7rgHIS7UbRvbLSv1z7MSJDYCA== +wicg-inert@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/wicg-inert/-/wicg-inert-3.0.2.tgz#46d8b01142c1bda8f6fa5d78e2754ba56f6f70be" + integrity sha512-L2eSi1fx1M+WLLUccwzAulgK5hZtllRDvYk3UB/fe1ZqdkZS6dz718o6xfe3JUtBEJJnqvI6NF8m1bAHlg3JUg== wide-align@^1.1.0: version "1.1.3" @@ -11093,6 +11397,16 @@ write-file-atomic@2.4.1: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + write@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" @@ -11126,6 +11440,13 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xregexp@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.3.0.tgz#7e92e73d9174a99a59743f67a4ce879a04b5ae50" + integrity sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g== + dependencies: + "@babel/runtime-corejs3" "^7.8.3" + xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"