Merge pull request #1183 from ThibG/glitch-soc/merge-upstream

Merge upstream changes
This commit is contained in:
ThibG 2019-07-30 15:40:28 +02:00 committed by GitHub
commit 4ecfa8f298
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 781 additions and 222 deletions

View file

@ -15,7 +15,7 @@ gem 'makara', '~> 0.4'
gem 'pghero', '~> 2.2' gem 'pghero', '~> 2.2'
gem 'dotenv-rails', '~> 2.7' gem 'dotenv-rails', '~> 2.7'
gem 'aws-sdk-s3', '~> 1.45', require: false gem 'aws-sdk-s3', '~> 1.46', require: false
gem 'fog-core', '<= 2.1.0' gem 'fog-core', '<= 2.1.0'
gem 'fog-openstack', '~> 0.3', require: false gem 'fog-openstack', '~> 0.3', require: false
gem 'paperclip', '~> 6.0' gem 'paperclip', '~> 6.0'
@ -53,7 +53,7 @@ gem 'html2text'
gem 'htmlentities', '~> 4.3' gem 'htmlentities', '~> 4.3'
gem 'http', '~> 3.3' gem 'http', '~> 3.3'
gem 'http_accept_language', '~> 2.1' gem 'http_accept_language', '~> 2.1'
gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2' gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2', submodules: true
gem 'httplog', '~> 1.3' gem 'httplog', '~> 1.3'
gem 'idn-ruby', require: 'idn' gem 'idn-ruby', require: 'idn'
gem 'kaminari', '~> 1.1' gem 'kaminari', '~> 1.1'
@ -113,7 +113,7 @@ group :production, :test do
end end
group :test do group :test do
gem 'capybara', '~> 3.26' gem 'capybara', '~> 3.27'
gem 'climate_control', '~> 0.2' gem 'climate_control', '~> 0.2'
gem 'faker', '~> 1.9' gem 'faker', '~> 1.9'
gem 'microformats', '~> 4.1' gem 'microformats', '~> 4.1'
@ -135,7 +135,7 @@ group :development do
gem 'memory_profiler' gem 'memory_profiler'
gem 'rubocop', '~> 0.73', require: false gem 'rubocop', '~> 0.73', require: false
gem 'rubocop-rails', '~> 2.2', require: false gem 'rubocop-rails', '~> 2.2', require: false
gem 'brakeman', '~> 4.5', require: false gem 'brakeman', '~> 4.6', require: false
gem 'bundler-audit', '~> 0.6', require: false gem 'bundler-audit', '~> 0.6', require: false
gem 'capistrano', '~> 3.11' gem 'capistrano', '~> 3.11'

View file

@ -22,6 +22,7 @@ GIT
remote: https://github.com/tmm1/http_parser.rb remote: https://github.com/tmm1/http_parser.rb
revision: 54b17ba8c7d8d20a16dfc65d1775241833219cf2 revision: 54b17ba8c7d8d20a16dfc65d1775241833219cf2
ref: 54b17ba8c7d8d20a16dfc65d1775241833219cf2 ref: 54b17ba8c7d8d20a16dfc65d1775241833219cf2
submodules: true
specs: specs:
http_parser.rb (0.6.1) http_parser.rb (0.6.1)
@ -96,17 +97,17 @@ GEM
av (0.9.0) av (0.9.0)
cocaine (~> 0.5.3) cocaine (~> 0.5.3)
aws-eventstream (1.0.3) aws-eventstream (1.0.3)
aws-partitions (1.184.0) aws-partitions (1.193.0)
aws-sdk-core (3.59.0) aws-sdk-core (3.61.1)
aws-eventstream (~> 1.0, >= 1.0.2) aws-eventstream (~> 1.0, >= 1.0.2)
aws-partitions (~> 1.0) aws-partitions (~> 1.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
jmespath (~> 1.0) jmespath (~> 1.0)
aws-sdk-kms (1.23.0) aws-sdk-kms (1.24.0)
aws-sdk-core (~> 3, >= 3.58.0) aws-sdk-core (~> 3, >= 3.61.1)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.45.0) aws-sdk-s3 (1.46.0)
aws-sdk-core (~> 3, >= 3.58.0) aws-sdk-core (~> 3, >= 3.61.1)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sigv4 (1.1.0) aws-sigv4 (1.1.0)
@ -123,7 +124,7 @@ GEM
ffi (~> 1.10.0) ffi (~> 1.10.0)
bootsnap (1.4.4) bootsnap (1.4.4)
msgpack (~> 1.0) msgpack (~> 1.0)
brakeman (4.5.1) brakeman (4.6.1)
browser (2.6.1) browser (2.6.1)
builder (3.2.3) builder (3.2.3)
bullet (6.0.1) bullet (6.0.1)
@ -149,7 +150,7 @@ GEM
sshkit (~> 1.3) sshkit (~> 1.3)
capistrano-yarn (2.0.2) capistrano-yarn (2.0.2)
capistrano (~> 3.0) capistrano (~> 3.0)
capybara (3.26.0) capybara (3.27.0)
addressable addressable
mini_mime (>= 0.1.3) mini_mime (>= 0.1.3)
nokogiri (~> 1.8) nokogiri (~> 1.8)
@ -291,7 +292,7 @@ GEM
domain_name (~> 0.5) domain_name (~> 0.5)
http-form_data (2.1.1) http-form_data (2.1.1)
http_accept_language (2.1.1) http_accept_language (2.1.1)
httplog (1.3.1) httplog (1.3.2)
rack (>= 1.0) rack (>= 1.0)
rainbow (>= 2.0.0) rainbow (>= 2.0.0)
i18n (1.6.0) i18n (1.6.0)
@ -386,7 +387,7 @@ GEM
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
sidekiq (>= 3.5) sidekiq (>= 3.5)
statsd-ruby (~> 1.4, >= 1.4.0) statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.8.0) oj (3.8.1)
omniauth (1.9.0) omniauth (1.9.0)
hashie (>= 3.4.6, < 3.7.0) hashie (>= 3.4.6, < 3.7.0)
rack (>= 1.6.2, < 3) rack (>= 1.6.2, < 3)
@ -670,12 +671,12 @@ DEPENDENCIES
active_record_query_trace (~> 1.6) active_record_query_trace (~> 1.6)
addressable (~> 2.6) addressable (~> 2.6)
annotate (~> 2.7) annotate (~> 2.7)
aws-sdk-s3 (~> 1.45) aws-sdk-s3 (~> 1.46)
better_errors (~> 2.5) better_errors (~> 2.5)
binding_of_caller (~> 0.7) binding_of_caller (~> 0.7)
blurhash (~> 0.1) blurhash (~> 0.1)
bootsnap (~> 1.4) bootsnap (~> 1.4)
brakeman (~> 4.5) brakeman (~> 4.6)
browser browser
bullet (~> 6.0) bullet (~> 6.0)
bundler-audit (~> 0.6) bundler-audit (~> 0.6)
@ -683,7 +684,7 @@ DEPENDENCIES
capistrano-rails (~> 1.4) capistrano-rails (~> 1.4)
capistrano-rbenv (~> 2.1) capistrano-rbenv (~> 2.1)
capistrano-yarn (~> 2.0) capistrano-yarn (~> 2.0)
capybara (~> 3.26) capybara (~> 3.27)
charlock_holmes (~> 0.7.6) charlock_holmes (~> 0.7.6)
chewy (~> 5.0) chewy (~> 5.0)
cld3 (~> 3.2.4) cld3 (~> 3.2.4)

View file

@ -4,6 +4,7 @@ class AboutController < ApplicationController
before_action :set_pack before_action :set_pack
layout 'public' layout 'public'
before_action :require_open_federation!, only: [:show, :more]
before_action :set_body_classes, only: :show before_action :set_body_classes, only: :show
before_action :set_instance_presenter before_action :set_instance_presenter
before_action :set_expires_in before_action :set_expires_in
@ -20,6 +21,10 @@ class AboutController < ApplicationController
private private
def require_open_federation!
not_found if whitelist_mode?
end
def new_user def new_user
User.new.tap do |user| User.new.tap do |user|
user.build_account user.build_account

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::BaseController < Api::BaseController class ActivityPub::BaseController < Api::BaseController
skip_before_action :require_authenticated_user!
private private
def set_cache_headers def set_cache_headers

View file

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::InboxesController < Api::BaseController class ActivityPub::InboxesController < ActivityPub::BaseController
include SignatureVerification include SignatureVerification
include JsonLdHelper include JsonLdHelper
include AccountOwnedConcern include AccountOwnedConcern

View file

@ -0,0 +1,40 @@
# frozen_string_literal: true
class Admin::DomainAllowsController < Admin::BaseController
before_action :set_domain_allow, only: [:destroy]
def new
authorize :domain_allow, :create?
@domain_allow = DomainAllow.new(domain: params[:_domain])
end
def create
authorize :domain_allow, :create?
@domain_allow = DomainAllow.new(resource_params)
if @domain_allow.save
log_action :create, @domain_allow
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.created_msg')
else
render :new
end
end
def destroy
authorize @domain_allow, :destroy?
UnallowDomainService.new.call(@domain_allow)
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
end
private
def set_domain_allow
@domain_allow = DomainAllow.find(params[:id])
end
def resource_params
params.require(:domain_allow).permit(:domain)
end
end

View file

@ -2,6 +2,10 @@
module Admin module Admin
class InstancesController < BaseController class InstancesController < BaseController
before_action :set_domain_block, only: :show
before_action :set_domain_allow, only: :show
before_action :set_instance, only: :show
def index def index
authorize :instance, :index? authorize :instance, :index?
@ -11,20 +15,38 @@ module Admin
def show def show
authorize :instance, :show? authorize :instance, :show?
@instance = Instance.new(Account.by_domain_accounts.find_by(domain: params[:id]) || DomainBlock.find_by!(domain: params[:id]))
@following_count = Follow.where(account: Account.where(domain: params[:id])).count @following_count = Follow.where(account: Account.where(domain: params[:id])).count
@followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count @followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count
@reports_count = Report.where(target_account: Account.where(domain: params[:id])).count @reports_count = Report.where(target_account: Account.where(domain: params[:id])).count
@blocks_count = Block.where(target_account: Account.where(domain: params[:id])).count @blocks_count = Block.where(target_account: Account.where(domain: params[:id])).count
@available = DeliveryFailureTracker.available?(Account.select(:shared_inbox_url).where(domain: params[:id]).first&.shared_inbox_url) @available = DeliveryFailureTracker.available?(Account.select(:shared_inbox_url).where(domain: params[:id]).first&.shared_inbox_url)
@media_storage = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size) @media_storage = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size)
@domain_block = DomainBlock.rule_for(params[:id])
end end
private private
def set_domain_block
@domain_block = DomainBlock.rule_for(params[:id])
end
def set_domain_allow
@domain_allow = DomainAllow.rule_for(params[:id])
end
def set_instance
resource = Account.by_domain_accounts.find_by(domain: params[:id])
resource ||= @domain_block
resource ||= @domain_allow
if resource
@instance = Instance.new(resource)
else
not_found
end
end
def filtered_instances def filtered_instances
InstanceFilter.new(filter_params).results InstanceFilter.new(whitelist_mode? ? { allowed: true } : filter_params).results
end end
def paginated_instances def paginated_instances

View file

@ -9,6 +9,7 @@ class Api::BaseController < ApplicationController
skip_before_action :store_current_location skip_before_action :store_current_location
skip_before_action :require_functional! skip_before_action :require_functional!
before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access?
before_action :set_cache_headers before_action :set_cache_headers
protect_from_forgery with: :null_session protect_from_forgery with: :null_session
@ -69,6 +70,10 @@ class Api::BaseController < ApplicationController
nil nil
end end
def require_authenticated_user!
render json: { error: 'This API requires an authenticated user' }, status: 401 unless current_user
end
def require_user! def require_user!
if !current_user if !current_user
render json: { error: 'This method requires an authenticated user' }, status: 422 render json: { error: 'This method requires an authenticated user' }, status: 422
@ -94,4 +99,8 @@ class Api::BaseController < ApplicationController
def set_cache_headers def set_cache_headers
response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate' response.headers['Cache-Control'] = 'no-cache, no-store, max-age=0, must-revalidate'
end end
def disallow_unauthenticated_api_access?
authorized_fetch_mode?
end
end end

View file

@ -12,6 +12,8 @@ class Api::V1::AccountsController < Api::BaseController
before_action :check_account_suspension, only: [:show] before_action :check_account_suspension, only: [:show]
before_action :check_enabled_registrations, only: [:create] before_action :check_enabled_registrations, only: [:create]
skip_before_action :require_authenticated_user!, only: :create
respond_to :json respond_to :json
def show def show

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::AppsController < Api::BaseController class Api::V1::AppsController < Api::BaseController
skip_before_action :require_authenticated_user!
def create def create
@app = Doorkeeper::Application.create!(application_options) @app = Doorkeeper::Application.create!(application_options)
render json: @app, serializer: REST::ApplicationSerializer render json: @app, serializer: REST::ApplicationSerializer

View file

@ -2,6 +2,7 @@
class Api::V1::Instances::ActivityController < Api::BaseController class Api::V1::Instances::ActivityController < Api::BaseController
before_action :require_enabled_api! before_action :require_enabled_api!
skip_before_action :set_cache_headers skip_before_action :set_cache_headers
respond_to :json respond_to :json
@ -33,6 +34,6 @@ class Api::V1::Instances::ActivityController < Api::BaseController
end end
def require_enabled_api! def require_enabled_api!
head 404 unless Setting.activity_api_enabled head 404 unless Setting.activity_api_enabled && !whitelist_mode?
end end
end end

View file

@ -2,6 +2,7 @@
class Api::V1::Instances::PeersController < Api::BaseController class Api::V1::Instances::PeersController < Api::BaseController
before_action :require_enabled_api! before_action :require_enabled_api!
skip_before_action :set_cache_headers skip_before_action :set_cache_headers
respond_to :json respond_to :json
@ -14,6 +15,6 @@ class Api::V1::Instances::PeersController < Api::BaseController
private private
def require_enabled_api! def require_enabled_api!
head 404 unless Setting.peers_api_enabled head 404 unless Setting.peers_api_enabled && !whitelist_mode?
end end
end end

View file

@ -2,6 +2,7 @@
class Api::V1::InstancesController < Api::BaseController class Api::V1::InstancesController < Api::BaseController
respond_to :json respond_to :json
skip_before_action :set_cache_headers skip_before_action :set_cache_headers
def show def show

View file

@ -11,6 +11,7 @@ class ApplicationController < ActionController::Base
include UserTrackingConcern include UserTrackingConcern
include SessionTrackingConcern include SessionTrackingConcern
include CacheConcern include CacheConcern
include DomainControlHelper
helper_method :current_account helper_method :current_account
helper_method :current_session helper_method :current_session
@ -18,6 +19,7 @@ class ApplicationController < ActionController::Base
helper_method :current_skin helper_method :current_skin
helper_method :single_user_mode? helper_method :single_user_mode?
helper_method :use_seamless_external_login? helper_method :use_seamless_external_login?
helper_method :whitelist_mode?
rescue_from ActionController::RoutingError, with: :not_found rescue_from ActionController::RoutingError, with: :not_found
rescue_from ActiveRecord::RecordNotFound, with: :not_found rescue_from ActiveRecord::RecordNotFound, with: :not_found
@ -39,7 +41,7 @@ class ApplicationController < ActionController::Base
end end
def authorized_fetch_mode? def authorized_fetch_mode?
ENV['AUTHORIZED_FETCH'] == 'true' ENV['AUTHORIZED_FETCH'] == 'true' || Rails.configuration.x.whitelist_mode
end end
def public_fetch_mode? def public_fetch_mode?

View file

@ -4,6 +4,7 @@ module AccountOwnedConcern
extend ActiveSupport::Concern extend ActiveSupport::Concern
included do included do
before_action :authenticate_user!, if: -> { whitelist_mode? && request.format != :json }
before_action :set_account, if: :account_required? before_action :set_account, if: :account_required?
before_action :check_account_approval, if: :account_required? before_action :check_account_approval, if: :account_required?
before_action :check_account_suspension, if: :account_required? before_action :check_account_suspension, if: :account_required?

View file

@ -3,7 +3,8 @@
class DirectoriesController < ApplicationController class DirectoriesController < ApplicationController
layout 'public' layout 'public'
before_action :check_enabled before_action :authenticate_user!, if: :whitelist_mode?
before_action :require_enabled!
before_action :set_instance_presenter before_action :set_instance_presenter
before_action :set_tag, only: :show before_action :set_tag, only: :show
before_action :set_tags before_action :set_tags
@ -24,7 +25,7 @@ class DirectoriesController < ApplicationController
use_pack 'share' use_pack 'share'
end end
def check_enabled def require_enabled!
return not_found unless Setting.profile_directory return not_found unless Setting.profile_directory
end end

View file

@ -61,7 +61,7 @@ class HomeController < ApplicationController
end end
def default_redirect_path def default_redirect_path
if request.path.start_with?('/web') if request.path.start_with?('/web') || whitelist_mode?
new_user_session_path new_user_session_path
elsif single_user_mode? elsif single_user_mode?
short_account_path(Account.local.without_suspended.where('id > 0').first) short_account_path(Account.local.without_suspended.where('id > 0').first)

View file

@ -5,6 +5,7 @@ class MediaController < ApplicationController
skip_before_action :store_current_location skip_before_action :store_current_location
before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_media_attachment before_action :set_media_attachment
before_action :verify_permitted_status! before_action :verify_permitted_status!
before_action :check_playable, only: :player before_action :check_playable, only: :player

View file

@ -5,6 +5,8 @@ class MediaProxyController < ApplicationController
skip_before_action :store_current_location skip_before_action :store_current_location
before_action :authenticate_user!, if: :whitelist_mode?
def show def show
RedisLock.acquire(lock_options) do |lock| RedisLock.acquire(lock_options) do |lock|
if lock.acquired? if lock.acquired?

View file

@ -4,7 +4,8 @@ class PublicTimelinesController < ApplicationController
before_action :set_pack before_action :set_pack
layout 'public' layout 'public'
before_action :check_enabled before_action :authenticate_user!, if: :whitelist_mode?
before_action :require_enabled!
before_action :set_body_classes before_action :set_body_classes
before_action :set_instance_presenter before_action :set_instance_presenter
@ -17,7 +18,7 @@ class PublicTimelinesController < ApplicationController
private private
def check_enabled def require_enabled!
not_found unless Setting.timeline_preview not_found unless Setting.timeline_preview
end end

View file

@ -5,6 +5,7 @@ class RemoteInteractionController < ApplicationController
layout 'modal' layout 'modal'
before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_interaction_type before_action :set_interaction_type
before_action :set_status before_action :set_status
before_action :set_body_classes before_action :set_body_classes

View file

@ -8,6 +8,7 @@ class TagsController < ApplicationController
layout 'public' layout 'public'
before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? } before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_tag before_action :set_tag
before_action :set_body_classes before_action :set_body_classes
before_action :set_instance_presenter before_action :set_instance_presenter

View file

@ -12,6 +12,14 @@ module DomainControlHelper
end end
end end
if whitelist_mode?
!DomainAllow.allowed?(domain)
else
DomainBlock.blocked?(domain) DomainBlock.blocked?(domain)
end end
end end
def whitelist_mode?
Rails.configuration.x.whitelist_mode
end
end

View file

@ -44,7 +44,8 @@ export default function search(state = initialState, action) {
hashtags: fromJS(action.results.hashtags), hashtags: fromJS(action.results.hashtags),
})).set('submitted', true).set('searchTerm', action.searchTerm); })).set('submitted', true).set('searchTerm', action.searchTerm);
case SEARCH_EXPAND_SUCCESS: case SEARCH_EXPAND_SUCCESS:
return state.updateIn(['results', action.searchType], list => list.concat(action.results[action.searchType].map(item => item.id))); const results = action.searchType === 'hashtags' ? fromJS(action.results.hashtags) : action.results[action.searchType].map(item => item.id);
return state.updateIn(['results', action.searchType], list => list.concat(results));
default: default:
return state; return state;
} }

View file

@ -418,16 +418,16 @@ export function selectComposeSuggestion(position, token, suggestion, path) {
return (dispatch, getState) => { return (dispatch, getState) => {
let completion, startPosition; let completion, startPosition;
if (typeof suggestion === 'object' && suggestion.id) { if (suggestion.type === 'emoji') {
completion = suggestion.native || suggestion.colons; completion = suggestion.native || suggestion.colons;
startPosition = position - 1; startPosition = position - 1;
dispatch(useEmoji(suggestion)); dispatch(useEmoji(suggestion));
} else if (typeof suggestion === 'object' && suggestion.name) { } else if (suggestion.type === 'hashtag') {
completion = `#${suggestion.name}`; completion = `#${suggestion.name}`;
startPosition = position - 1; startPosition = position - 1;
} else { } else if (suggestion.type === 'account') {
completion = getState().getIn(['accounts', suggestion, 'acct']); completion = getState().getIn(['accounts', suggestion.id, 'acct']);
startPosition = position; startPosition = position;
} }

View file

@ -168,15 +168,15 @@ export default class AutosuggestInput extends ImmutablePureComponent {
const { selectedSuggestion } = this.state; const { selectedSuggestion } = this.state;
let inner, key; let inner, key;
if (typeof suggestion === 'object' && suggestion.shortcode) { if (suggestion.type === 'emoji') {
inner = <AutosuggestEmoji emoji={suggestion} />; inner = <AutosuggestEmoji emoji={suggestion} />;
key = suggestion.id; key = suggestion.id;
} else if (typeof suggestion === 'object' && suggestion.name) { } else if (suggestion.type ==='hashtag') {
inner = <AutosuggestHashtag tag={suggestion} />; inner = <AutosuggestHashtag tag={suggestion} />;
key = suggestion.name; key = suggestion.name;
} else { } else if (suggestion.type === 'account') {
inner = <AutosuggestAccountContainer id={suggestion} />; inner = <AutosuggestAccountContainer id={suggestion.id} />;
key = suggestion; key = suggestion.id;
} }
return ( return (

View file

@ -174,15 +174,15 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
const { selectedSuggestion } = this.state; const { selectedSuggestion } = this.state;
let inner, key; let inner, key;
if (typeof suggestion === 'object' && suggestion.shortcode) { if (suggestion.type === 'emoji') {
inner = <AutosuggestEmoji emoji={suggestion} />; inner = <AutosuggestEmoji emoji={suggestion} />;
key = suggestion.id; key = suggestion.id;
} else if (typeof suggestion === 'object' && suggestion.name) { } else if (suggestion.type === 'hashtag') {
inner = <AutosuggestHashtag tag={suggestion} />; inner = <AutosuggestHashtag tag={suggestion} />;
key = suggestion.name; key = suggestion.name;
} else { } else if (suggestion.type === 'account') {
inner = <AutosuggestAccountContainer id={suggestion} />; inner = <AutosuggestAccountContainer id={suggestion.id} />;
key = suggestion; key = suggestion.id;
} }
return ( return (

View file

@ -8,9 +8,71 @@ import classnames from 'classnames';
import PollContainer from 'mastodon/containers/poll_container'; import PollContainer from 'mastodon/containers/poll_container';
import Icon from 'mastodon/components/icon'; import Icon from 'mastodon/components/icon';
import { autoPlayGif } from 'mastodon/initial_state'; import { autoPlayGif } from 'mastodon/initial_state';
import { decode as decodeIDNA } from 'mastodon/utils/idna';
const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top) const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
// Regex matching what "looks like a link", that is, something that starts with
// an optional "http://" or "https://" scheme and then what could look like a
// domain main, that is, at least two sequences of characters not including spaces
// and separated by "." or an homoglyph. The idea is not to match valid URLs or
// domain names, but what could be confused for a valid URL or domain name,
// especially to the untrained eye.
const h_confusables = 'h\u13c2\u1d58d\u1d4f1\u1d691\u0068\uff48\u1d525\u210e\u1d489\u1d629\u0570\u1d4bd\u1d65d\u1d421\u1d5c1\u1d5f5\u04bb\u1d559';
const t_confusables = 't\u1d42d\u1d5cd\u1d531\u1d565\u1d4c9\u1d669\u1d4fd\u1d69d\u0074\u1d461\u1d601\u1d495\u1d635\u1d599';
const p_confusables = 'p\u0440\u03c1\u1d52d\u1d631\u1d665\u1d429\uff50\u1d6e0\u1d45d\u1d561\u1d595\u1d71a\u1d699\u1d78e\u2ca3\u1d754\u1d6d2\u1d491\u1d7c8\u1d746\u1d4c5\u1d70c\u1d5c9\u0070\u1d780\u03f1\u1d5fd\u2374\u1d7ba\u1d4f9';
const s_confusables = 's\u1d530\u118c1\u1d494\u1d634\u1d4c8\u1d668\uabaa\u1d42c\u1d5cc\u1d460\u1d600\ua731\u0073\uff53\u1d564\u0455\u1d598\u1d4fc\u1d69c\u10448\u01bd';
const column_confusables = ':\u0903\u0a83\u0703\u1803\u05c3\u0704\u0589\u1809\ua789\u16ec\ufe30\u02d0\u2236\u02f8\u003a\uff1a\u205a\ua4fd';
const slash_confusables = '/\u2041\u2f03\u2044\u2cc6\u27cb\u30ce\u002f\u2571\u31d3\u3033\u1735\u2215\u29f8\u1d23a\u4e3f';
const dot_confusables = '.\u002e\u0660\u06f0\u0701\u0702\u2024\ua4f8\ua60e\u10a50\u1d16d';
const linkRegex = new RegExp(`^\\s*(([${h_confusables}][${t_confusables}][${t_confusables}][${p_confusables}][${s_confusables}]?[${column_confusables}][${slash_confusables}][${slash_confusables}]))?[^:/\\n ]+([${dot_confusables}][^:/\\n ]+)+`);
const isLinkMisleading = (link) => {
let linkTextParts = [];
// Reconstruct visible text, as we do not have much control over how links
// from remote software look, and we can't rely on `innerText` because the
// `invisible` class does not set `display` to `none`.
const walk = (node) => {
switch (node.nodeType) {
case Node.TEXT_NODE:
linkTextParts.push(node.textContent);
break;
case Node.ELEMENT_NODE:
if (node.classList.contains('invisible')) return;
const children = node.childNodes;
for (let i = 0; i < children.length; i++) {
walk(children[i]);
}
break;
}
};
walk(link);
const linkText = linkTextParts.join('');
const targetURL = new URL(link.href);
// The following may not work with international domain names
if (linkText === targetURL.origin || linkText === targetURL.host || 'www.' + linkText === targetURL.host || linkText.startsWith(targetURL.origin + '/') || linkText.startsWith(targetURL.host + '/')) {
return false;
}
// The link hasn't been recognized, maybe it features an international domain name
const hostname = decodeIDNA(targetURL.hostname);
const host = targetURL.host.replace(targetURL.hostname, hostname);
const origin = targetURL.origin.replace(targetURL.host, host);
if (linkText === origin || linkText === host || linkText.startsWith(origin + '/') || linkText.startsWith(host + '/')) {
return false;
}
// If the link text looks like an URL or auto-generated link, it is misleading
return linkRegex.test(linkText);
};
export default class StatusContent extends React.PureComponent { export default class StatusContent extends React.PureComponent {
static contextTypes = { static contextTypes = {
@ -56,6 +118,34 @@ export default class StatusContent extends React.PureComponent {
} else { } else {
link.setAttribute('title', link.href); link.setAttribute('title', link.href);
link.classList.add('unhandled-link'); link.classList.add('unhandled-link');
if (isLinkMisleading(link)) {
while (link.firstChild) {
link.removeChild(link.firstChild);
}
const prefix = (link.href.match(/https?:\/\/(www\.)?/) || [''])[0];
const text = link.href.substr(prefix.length, 30);
const suffix = link.href.substr(prefix.length + 30);
const cutoff = !!suffix;
const prefixTag = document.createElement('span');
prefixTag.classList.add('invisible');
prefixTag.textContent = prefix;
link.appendChild(prefixTag);
const textTag = document.createElement('span');
if (cutoff) {
textTag.classList.add('ellipsis');
}
textTag.textContent = text;
link.appendChild(textTag);
const suffixTag = document.createElement('span');
suffixTag.classList.add('invisible');
suffixTag.textContent = suffix;
link.appendChild(suffixTag);
}
} }
link.setAttribute('target', '_blank'); link.setAttribute('target', '_blank');

View file

@ -2,18 +2,9 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Immutable from 'immutable'; import Immutable from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import punycode from 'punycode';
import classnames from 'classnames'; import classnames from 'classnames';
import Icon from 'mastodon/components/icon'; import Icon from 'mastodon/components/icon';
import { decode as decodeIDNA } from 'mastodon/utils/idna';
const IDNA_PREFIX = 'xn--';
const decodeIDNA = domain => {
return domain
.split('.')
.map(part => part.indexOf(IDNA_PREFIX) === 0 ? punycode.decode(part.slice(IDNA_PREFIX.length)) : part)
.join('.');
};
const getHostname = url => { const getHostname = url => {
const parser = document.createElement('a'); const parser = document.createElement('a');

View file

@ -207,11 +207,11 @@ const expiresInFromExpiresAt = expires_at => {
const normalizeSuggestions = (state, { accounts, emojis, tags }) => { const normalizeSuggestions = (state, { accounts, emojis, tags }) => {
if (accounts) { if (accounts) {
return accounts.map(item => item.id); return accounts.map(item => ({ id: item.id, type: 'account' }));
} else if (emojis) { } else if (emojis) {
return emojis; return emojis.map(item => ({ ...item, type: 'emoji' }));
} else { } else {
return sortHashtagsByUse(state, tags); return sortHashtagsByUse(state, tags.map(item => ({ ...item, type: 'hashtag' })));
} }
}; };

View file

@ -44,7 +44,8 @@ export default function search(state = initialState, action) {
hashtags: fromJS(action.results.hashtags), hashtags: fromJS(action.results.hashtags),
})).set('submitted', true).set('searchTerm', action.searchTerm); })).set('submitted', true).set('searchTerm', action.searchTerm);
case SEARCH_EXPAND_SUCCESS: case SEARCH_EXPAND_SUCCESS:
return state.updateIn(['results', action.searchType], list => list.concat(action.results[action.searchType].map(item => item.id))); const results = action.searchType === 'hashtags' ? fromJS(action.results.hashtags) : action.results[action.searchType].map(item => item.id);
return state.updateIn(['results', action.searchType], list => list.concat(results));
default: default:
return state; return state;
} }

View file

@ -0,0 +1,10 @@
import punycode from 'punycode';
const IDNA_PREFIX = 'xn--';
export const decode = domain => {
return domain
.split('.')
.map(part => part.indexOf(IDNA_PREFIX) === 0 ? punycode.decode(part.slice(IDNA_PREFIX.length)) : part)
.join('.');
};

View file

@ -0,0 +1,33 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: domain_allows
#
# id :bigint(8) not null, primary key
# domain :string default(""), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class DomainAllow < ApplicationRecord
include DomainNormalizable
validates :domain, presence: true, uniqueness: true
scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
class << self
def allowed?(domain)
!rule_for(domain).nil?
end
def rule_for(domain)
return if domain.blank?
uri = Addressable::URI.new.tap { |u| u.host = domain.gsub(/[\/]/, '') }
find_by(domain: uri.normalized_host)
end
end
end

View file

@ -7,8 +7,9 @@ class Instance
def initialize(resource) def initialize(resource)
@domain = resource.domain @domain = resource.domain
@accounts_count = resource.is_a?(DomainBlock) ? nil : resource.accounts_count @accounts_count = resource.respond_to?(:accounts_count) ? resource.accounts_count : nil
@domain_block = resource.is_a?(DomainBlock) ? resource : DomainBlock.rule_for(domain) @domain_block = resource.is_a?(DomainBlock) ? resource : DomainBlock.rule_for(domain)
@domain_allow = resource.is_a?(DomainAllow) ? resource : DomainAllow.rule_for(domain)
end end
def countable? def countable?

View file

@ -12,6 +12,10 @@ class InstanceFilter
scope = DomainBlock scope = DomainBlock
scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present? scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?
scope.order(id: :desc) scope.order(id: :desc)
elsif params[:allowed].present?
scope = DomainAllow
scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?
scope.order(id: :desc)
else else
scope = Account.remote scope = Account.remote
scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present? scope = scope.matches_domain(params[:by_domain]) if params[:by_domain].present?

View file

@ -65,7 +65,7 @@ class Tag < ApplicationRecord
class << self class << self
def find_or_create_by_names(name_or_names) def find_or_create_by_names(name_or_names)
Array(name_or_names).map(&method(:normalize)).uniq.map do |normalized_name| Array(name_or_names).map(&method(:normalize)).uniq { |str| str.mb_chars.downcase.to_s }.map do |normalized_name|
tag = matching_name(normalized_name).first || create(name: normalized_name) tag = matching_name(normalized_name).first || create(name: normalized_name)
yield tag if block_given? yield tag if block_given?
@ -77,7 +77,7 @@ class Tag < ApplicationRecord
def search_for(term, limit = 5, offset = 0) def search_for(term, limit = 5, offset = 0)
pattern = sanitize_sql_like(normalize(term.strip)) + '%' pattern = sanitize_sql_like(normalize(term.strip)) + '%'
Tag.where(arel_table[:name].lower.matches(pattern.downcase)) Tag.where(arel_table[:name].lower.matches(pattern.mb_chars.downcase.to_s))
.order(:name) .order(:name)
.limit(limit) .limit(limit)
.offset(offset) .offset(offset)
@ -92,7 +92,7 @@ class Tag < ApplicationRecord
end end
def matching_name(name_or_names) def matching_name(name_or_names)
names = Array(name_or_names).map { |name| normalize(name).downcase } names = Array(name_or_names).map { |name| normalize(name).mb_chars.downcase.to_s }
if names.size == 1 if names.size == 1
where(arel_table[:name].lower.eq(names.first)) where(arel_table[:name].lower.eq(names.first))
@ -104,7 +104,7 @@ class Tag < ApplicationRecord
private private
def normalize(str) def normalize(str)
str.gsub(/\A#/, '').mb_chars.to_s str.gsub(/\A#/, '')
end end
end end

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class DomainAllowPolicy < ApplicationPolicy
def create?
admin?
end
def destroy?
admin?
end
end

View file

@ -14,6 +14,6 @@ module Payloadable
end end
def signing_enabled? def signing_enabled?
ENV['AUTHORIZED_FETCH'] != 'true' ENV['AUTHORIZED_FETCH'] != 'true' && !Rails.configuration.x.whitelist_mode
end end
end end

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class UnallowDomainService < BaseService
def call(domain_allow)
Account.where(domain: domain_allow.domain).find_each do |account|
SuspendAccountService.new.call(account, destroy: true)
end
domain_allow.destroy
end
end

View file

@ -0,0 +1,14 @@
- content_for :header_tags do
= javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous'
- content_for :page_title do
= t('admin.domain_allows.add_new')
= simple_form_for @domain_allow, url: admin_domain_allows_path do |f|
= render 'shared/error_messages', object: @domain_allow
.fields-group
= f.input :domain, wrapper: :with_label, label: t('admin.domain_blocks.domain'), required: true
.actions
= f.button :button, t('admin.domain_allows.add_new'), type: :submit

View file

@ -6,11 +6,17 @@
%strong= t('admin.instances.moderation.title') %strong= t('admin.instances.moderation.title')
%ul %ul
%li= filter_link_to t('admin.instances.moderation.all'), limited: nil %li= filter_link_to t('admin.instances.moderation.all'), limited: nil
- unless whitelist_mode?
%li= filter_link_to t('admin.instances.moderation.limited'), limited: '1' %li= filter_link_to t('admin.instances.moderation.limited'), limited: '1'
%div{ style: 'flex: 1 1 auto; text-align: right' } %div{ style: 'flex: 1 1 auto; text-align: right' }
- if whitelist_mode?
= link_to t('admin.domain_allows.add_new'), new_admin_domain_allow_path, class: 'button'
- else
= link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path, class: 'button' = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path, class: 'button'
- unless whitelist_mode?
= form_tag admin_instances_url, method: 'GET', class: 'simple_form' do = form_tag admin_instances_url, method: 'GET', class: 'simple_form' do
.fields-group .fields-group
- Admin::FilterHelper::INSTANCES_FILTERS.each do |key| - Admin::FilterHelper::INSTANCES_FILTERS.each do |key|
@ -47,8 +53,11 @@
- unless first_item - unless first_item
&bull; &bull;
= t('admin.domain_blocks.rejecting_reports') = t('admin.domain_blocks.rejecting_reports')
- elsif whitelist_mode?
= t('admin.accounts.whitelisted')
- else - else
= t('admin.accounts.no_limits_imposed') = t('admin.accounts.no_limits_imposed')
- if instance.countable? - if instance.countable?
.trends__item__current{ title: t('admin.instances.known_accounts', count: instance.accounts_count) }= number_to_human instance.accounts_count, strip_insignificant_zeros: true .trends__item__current{ title: t('admin.instances.known_accounts', count: instance.accounts_count) }= number_to_human instance.accounts_count, strip_insignificant_zeros: true
= paginate paginated_instances = paginate paginated_instances

View file

@ -38,7 +38,9 @@
= link_to t('admin.accounts.title'), admin_accounts_path(remote: '1', by_domain: @instance.domain), class: 'button' = link_to t('admin.accounts.title'), admin_accounts_path(remote: '1', by_domain: @instance.domain), class: 'button'
%div{ style: 'float: right' } %div{ style: 'float: right' }
- if @domain_block - if @domain_allow
= link_to t('admin.domain_allows.undo'), admin_domain_allow_path(@domain_allow), class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure'), method: :delete }
- elsif @domain_block
= link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@domain_block), class: 'button' = link_to t('admin.domain_blocks.undo'), admin_domain_block_path(@domain_block), class: 'button'
- else - else
= link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button' = link_to t('admin.domain_blocks.add_new'), new_admin_domain_block_path(_domain: @instance.domain), class: 'button'

View file

@ -42,6 +42,7 @@
%hr.spacer/ %hr.spacer/
- unless whitelist_mode?
.fields-group .fields-group
= f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html') = f.input :timeline_preview, as: :boolean, wrapper: :with_label, label: t('admin.settings.timeline_preview.title'), hint: t('admin.settings.timeline_preview.desc_html')
@ -54,6 +55,7 @@
.fields-group .fields-group
= f.input :open_deletion, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.deletion.title'), hint: t('admin.settings.registrations.deletion.desc_html') = f.input :open_deletion, as: :boolean, wrapper: :with_label, label: t('admin.settings.registrations.deletion.title'), hint: t('admin.settings.registrations.deletion.desc_html')
- unless whitelist_mode?
.fields-group .fields-group
= f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html') = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.activity_api_enabled.title'), hint: t('admin.settings.activity_api_enabled.desc_html')
@ -88,7 +90,7 @@
.fields-group .fields-group
= f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 } = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, label: t('admin.settings.registrations.closed_message.title'), hint: t('admin.settings.registrations.closed_message.desc_html'), input_html: { rows: 8 }
= f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 } = f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 } unless whitelist_mode?
= f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 } = f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 }
= f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html') = f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 }, label: t('admin.settings.custom_css.title'), hint: t('admin.settings.custom_css.desc_html')

View file

@ -33,7 +33,7 @@
= f.input :invite_code, as: :hidden = f.input :invite_code, as: :hidden
.fields-group .fields-group
= f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path) = f.input :agreement, as: :boolean, wrapper: :with_label, label: whitelist_mode? ? t('auth.checkbox_agreement_without_rules_html', terms_path: terms_path) : t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path)
.actions .actions
= f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit = f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit

View file

@ -7,10 +7,13 @@
= link_to root_url, class: 'brand' do = link_to root_url, class: 'brand' do
= svg_logo_full = svg_logo_full
- unless whitelist_mode?
= link_to t('directories.directory'), explore_path, class: 'nav-link optional' if Setting.profile_directory = link_to t('directories.directory'), explore_path, class: 'nav-link optional' if Setting.profile_directory
= link_to t('about.about_this'), about_more_path, class: 'nav-link optional' = link_to t('about.about_this'), about_more_path, class: 'nav-link optional'
= link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link optional' = link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link optional'
.nav-center .nav-center
.nav-right .nav-right
- if user_signed_in? - if user_signed_in?
= link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn' = link_to t('settings.back'), root_url, class: 'nav-link nav-button webapp-btn'

View file

@ -0,0 +1,5 @@
# frozen_string_literal: true
Rails.application.configure do
config.x.whitelist_mode = ENV['WHITELIST_MODE'] == 'true'
end

View file

@ -186,6 +186,7 @@ en:
username: Username username: Username
warn: Warn warn: Warn
web: Web web: Web
whitelisted: Whitelisted
action_logs: action_logs:
actions: actions:
assigned_to_self_report: "%{name} assigned report %{target} to themselves" assigned_to_self_report: "%{name} assigned report %{target} to themselves"
@ -270,6 +271,11 @@ en:
week_interactions: interactions this week week_interactions: interactions this week
week_users_active: active this week week_users_active: active this week
week_users_new: users this week week_users_new: users this week
domain_allows:
add_new: Whitelist domain
created_msg: Domain has been successfully whitelisted
destroyed_msg: Domain has been removed from the whitelist
undo: Remove from whitelist
domain_blocks: domain_blocks:
add_new: Add new domain block add_new: Add new domain block
created_msg: Domain block is now being processed created_msg: Domain block is now being processed
@ -537,6 +543,7 @@ en:
apply_for_account: Request an invite apply_for_account: Request an invite
change_password: Password change_password: Password
checkbox_agreement_html: I agree to the <a href="%{rules_path}" target="_blank">server rules</a> and <a href="%{terms_path}" target="_blank">terms of service</a> checkbox_agreement_html: I agree to the <a href="%{rules_path}" target="_blank">server rules</a> and <a href="%{terms_path}" target="_blank">terms of service</a>
checkbox_agreement_without_rules_html: I agree to the <a href="%{terms_path}" target="_blank">terms of service</a>
delete_account: Delete account delete_account: Delete account
delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation. delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.
didnt_get_confirmation: Didn't receive confirmation instructions? didnt_get_confirmation: Didn't receive confirmation instructions?

View file

@ -43,6 +43,8 @@ en:
setting_use_pending_items: Hide timeline updates behind a click instead of automatically scrolling the feed setting_use_pending_items: Hide timeline updates behind a click instead of automatically scrolling the feed
username: Your username will be unique on %{domain} username: Your username will be unique on %{domain}
whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word 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
featured_tag: featured_tag:
name: 'You might want to use one of these:' name: 'You might want to use one of these:'
imports: imports:

View file

@ -45,7 +45,7 @@ SimpleNavigation::Configuration.run do |navigation|
s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_url, highlights_on: %r{/admin/accounts|/admin/pending_accounts} s.item :accounts, safe_join([fa_icon('users fw'), t('admin.accounts.title')]), admin_accounts_url, highlights_on: %r{/admin/accounts|/admin/pending_accounts}
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path
s.item :tags, safe_join([fa_icon('tag fw'), t('admin.tags.title')]), admin_tags_path s.item :tags, safe_join([fa_icon('tag fw'), t('admin.tags.title')]), admin_tags_path
s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url(limited: '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks}, if: -> { current_user.admin? } s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_url(limited: whitelist_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.admin? }
s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.admin? } s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_url, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.admin? }
end end

View file

@ -156,6 +156,7 @@ Rails.application.routes.draw do
namespace :admin do namespace :admin do
get '/dashboard', to: 'dashboard#index' get '/dashboard', to: 'dashboard#index'
resources :domain_allows, only: [:new, :create, :show, :destroy]
resources :domain_blocks, only: [:new, :create, :show, :destroy] resources :domain_blocks, only: [:new, :create, :show, :destroy]
resources :email_domain_blocks, only: [:index, :new, :create, :destroy] resources :email_domain_blocks, only: [:index, :new, :create, :destroy]
resources :action_logs, only: [:index] resources :action_logs, only: [:index]

View file

@ -0,0 +1,9 @@
class CreateDomainAllows < ActiveRecord::Migration[5.2]
def change
create_table :domain_allows do |t|
t.string :domain, default: '', null: false, index: { unique: true }
t.timestamps
end
end
end

View file

@ -2,6 +2,19 @@ class AddCaseInsensitiveIndexToTags < ActiveRecord::Migration[5.2]
disable_ddl_transaction! disable_ddl_transaction!
def up def up
Tag.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM tags GROUP BY lower(name) HAVING count(*) > 1').to_hash.each do |row|
canonical_tag_id = row['ids'].split(',').first
redundant_tag_ids = row['ids'].split(',')[1..-1]
safety_assured do
execute "UPDATE accounts_tags AS t0 SET tag_id = #{canonical_tag_id} WHERE tag_id IN (#{redundant_tag_ids.join(', ')}) AND NOT EXISTS (SELECT t1.tag_id FROM accounts_tags AS t1 WHERE t1.tag_id = #{canonical_tag_id} AND t1.account_id = t0.account_id)"
execute "UPDATE statuses_tags AS t0 SET tag_id = #{canonical_tag_id} WHERE tag_id IN (#{redundant_tag_ids.join(', ')}) AND NOT EXISTS (SELECT t1.tag_id FROM statuses_tags AS t1 WHERE t1.tag_id = #{canonical_tag_id} AND t1.status_id = t0.status_id)"
execute "UPDATE featured_tags AS t0 SET tag_id = #{canonical_tag_id} WHERE tag_id IN (#{redundant_tag_ids.join(', ')}) AND NOT EXISTS (SELECT t1.tag_id FROM featured_tags AS t1 WHERE t1.tag_id = #{canonical_tag_id} AND t1.account_id = t0.account_id)"
end
Tag.where(id: redundant_tag_ids).in_batches.delete_all
end
safety_assured { execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower ON tags (lower(name))' } safety_assured { execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower ON tags (lower(name))' }
remove_index :tags, name: 'index_tags_on_name' remove_index :tags, name: 'index_tags_on_name'
remove_index :tags, name: 'hashtag_search_index' remove_index :tags, name: 'hashtag_search_index'

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_07_26_175042) do ActiveRecord::Schema.define(version: 2019_07_28_084117) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -255,6 +255,13 @@ ActiveRecord::Schema.define(version: 2019_07_26_175042) do
t.index ["account_id"], name: "index_custom_filters_on_account_id" t.index ["account_id"], name: "index_custom_filters_on_account_id"
end end
create_table "domain_allows", force: :cascade do |t|
t.string "domain", default: "", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["domain"], name: "index_domain_allows_on_domain", unique: true
end
create_table "domain_blocks", force: :cascade do |t| create_table "domain_blocks", force: :cascade do |t|
t.string "domain", default: "", null: false t.string "domain", default: "", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false

View file

@ -12,17 +12,33 @@ module Mastodon
end end
option :dry_run, type: :boolean option :dry_run, type: :boolean
desc 'purge DOMAIN', 'Remove accounts from a DOMAIN without a trace' option :whitelist_mode, type: :boolean
desc 'purge [DOMAIN]', 'Remove accounts from a DOMAIN without a trace'
long_desc <<-LONG_DESC long_desc <<-LONG_DESC
Remove all accounts from a given DOMAIN without leaving behind any Remove all accounts from a given DOMAIN without leaving behind any
records. Unlike a suspension, if the DOMAIN still exists in the wild, records. Unlike a suspension, if the DOMAIN still exists in the wild,
it means the accounts could return if they are resolved again. it means the accounts could return if they are resolved again.
When the --whitelist-mode option is given, instead of purging accounts
from a single domain, all accounts from domains that are not whitelisted
are removed from the database.
LONG_DESC LONG_DESC
def purge(domain) def purge(domain = nil)
removed = 0 removed = 0
dry_run = options[:dry_run] ? ' (DRY RUN)' : '' dry_run = options[:dry_run] ? ' (DRY RUN)' : ''
Account.where(domain: domain).find_each do |account| scope = begin
if options[:whitelist_mode]
Account.remote.where.not(domain: DomainAllow.pluck(:domain))
elsif domain.present?
Account.remote.where(domain: domain)
else
say('No domain given', :red)
exit(1)
end
end
scope.find_each do |account|
SuspendAccountService.new.call(account, destroy: true) unless options[:dry_run] SuspendAccountService.new.call(account, destroy: true) unless options[:dry_run]
removed += 1 removed += 1
say('.', :green, false) say('.', :green, false)

View file

@ -69,13 +69,13 @@
"@babel/plugin-transform-react-jsx-self": "^7.2.0", "@babel/plugin-transform-react-jsx-self": "^7.2.0",
"@babel/plugin-transform-react-jsx-source": "^7.2.0", "@babel/plugin-transform-react-jsx-source": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.4.4", "@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "^7.4.5", "@babel/preset-env": "^7.5.5",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@babel/runtime": "^7.5.4", "@babel/runtime": "^7.5.4",
"@clusterws/cws": "^0.15.0", "@clusterws/cws": "^0.15.0",
"array-includes": "^3.0.3", "array-includes": "^3.0.3",
"atrament": "^0.2.3", "atrament": "^0.2.3",
"autoprefixer": "^9.6.0", "autoprefixer": "^9.6.1",
"axios": "^0.19.0", "axios": "^0.19.0",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"babel-plugin-lodash": "^3.3.4", "babel-plugin-lodash": "^3.3.4",
@ -97,7 +97,7 @@
"exif-js": "^2.3.0", "exif-js": "^2.3.0",
"express": "^4.17.1", "express": "^4.17.1",
"favico.js": "^0.3.10", "favico.js": "^0.3.10",
"file-loader": "^4.0.0", "file-loader": "^4.1.0",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"glob": "^7.1.1", "glob": "^7.1.1",
"http-link-header": "^1.0.2", "http-link-header": "^1.0.2",
@ -153,7 +153,7 @@
"requestidlecallback": "^0.3.0", "requestidlecallback": "^0.3.0",
"reselect": "^4.0.0", "reselect": "^4.0.0",
"rimraf": "^2.6.3", "rimraf": "^2.6.3",
"sass": "^1.20.3", "sass": "^1.22.7",
"sass-loader": "^7.0.3", "sass-loader": "^7.0.3",
"stringz": "^2.0.0", "stringz": "^2.0.0",
"substring-trie": "^1.0.2", "substring-trie": "^1.0.2",
@ -184,6 +184,6 @@
"react-test-renderer": "^16.8.6", "react-test-renderer": "^16.8.6",
"sass-lint": "^1.13.1", "sass-lint": "^1.13.1",
"webpack-dev-server": "^3.7.2", "webpack-dev-server": "^3.7.2",
"yargs": "^12.0.5" "yargs": "^13.3.0"
} }
} }

View file

@ -0,0 +1,3 @@
Fabricator(:domain_allow) do
domain "MyString"
end

View file

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe DomainAllow, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View file

@ -82,6 +82,40 @@ RSpec.describe Tag, type: :model do
end end
end end
describe '.find_normalized' do
it 'returns tag for a multibyte case-insensitive name' do
upcase_string = 'abcABCやゆよ'
downcase_string = 'abcabcやゆよ';
tag = Fabricate(:tag, name: downcase_string)
expect(Tag.find_normalized(upcase_string)).to eq tag
end
end
describe '.matching_name' do
it 'returns tags for multibyte case-insensitive names' do
upcase_string = 'abcABCやゆよ'
downcase_string = 'abcabcやゆよ';
tag = Fabricate(:tag, name: downcase_string)
expect(Tag.matching_name(upcase_string)).to eq [tag]
end
end
describe '.find_or_create_by_names' do
it 'runs a passed block once per tag regardless of duplicates' do
upcase_string = 'abcABCやゆよ'
downcase_string = 'abcabcやゆよ';
count = 0
Tag.find_or_create_by_names([upcase_string, downcase_string]) do |tag|
count += 1
end
expect(count).to eq 1
end
end
describe '.search_for' do describe '.search_for' do
it 'finds tag records with matching names' do it 'finds tag records with matching names' do
tag = Fabricate(:tag, name: "match") tag = Fabricate(:tag, name: "match")

View file

@ -12,6 +12,7 @@ const uuid = require('uuid');
const fs = require('fs'); const fs = require('fs');
const env = process.env.NODE_ENV || 'development'; const env = process.env.NODE_ENV || 'development';
const alwaysRequireAuth = process.env.WHITELIST_MODE === 'true' || process.env.AUTHORIZED_FETCH === 'true';
dotenv.config({ dotenv.config({
path: env === 'production' ? '.env.production' : '.env', path: env === 'production' ? '.env.production' : '.env',
@ -271,7 +272,7 @@ const startWorker = (workerId) => {
const wsVerifyClient = (info, cb) => { const wsVerifyClient = (info, cb) => {
const location = url.parse(info.req.url, true); const location = url.parse(info.req.url, true);
const authRequired = !PUBLIC_STREAMS.some(stream => stream === location.query.stream); const authRequired = alwaysRequireAuth || !PUBLIC_STREAMS.some(stream => stream === location.query.stream);
const allowedScopes = []; const allowedScopes = [];
if (authRequired) { if (authRequired) {
@ -306,7 +307,7 @@ const startWorker = (workerId) => {
return; return;
} }
const authRequired = !PUBLIC_ENDPOINTS.some(endpoint => endpoint === req.path); const authRequired = alwaysRequireAuth || !PUBLIC_ENDPOINTS.some(endpoint => endpoint === req.path);
const allowedScopes = []; const allowedScopes = [];
if (authRequired) { if (authRequired) {

397
yarn.lock
View file

@ -9,6 +9,13 @@
dependencies: dependencies:
"@babel/highlight" "^7.0.0" "@babel/highlight" "^7.0.0"
"@babel/code-frame@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/core@^7.1.0": "@babel/core@^7.1.0":
version "7.3.4" version "7.3.4"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b"
@ -71,6 +78,17 @@
source-map "^0.5.0" source-map "^0.5.0"
trim-right "^1.0.1" trim-right "^1.0.1"
"@babel/generator@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf"
integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==
dependencies:
"@babel/types" "^7.5.5"
jsesc "^2.5.1"
lodash "^4.17.13"
source-map "^0.5.0"
trim-right "^1.0.1"
"@babel/helper-annotate-as-pure@^7.0.0": "@babel/helper-annotate-as-pure@^7.0.0":
version "7.0.0" version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
@ -115,14 +133,14 @@
"@babel/helper-replace-supers" "^7.4.4" "@babel/helper-replace-supers" "^7.4.4"
"@babel/helper-split-export-declaration" "^7.4.4" "@babel/helper-split-export-declaration" "^7.4.4"
"@babel/helper-define-map@^7.4.4": "@babel/helper-define-map@^7.5.5":
version "7.4.4" version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz#6969d1f570b46bdc900d1eba8e5d59c48ba2c12a" resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369"
integrity sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg== integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==
dependencies: dependencies:
"@babel/helper-function-name" "^7.1.0" "@babel/helper-function-name" "^7.1.0"
"@babel/types" "^7.4.4" "@babel/types" "^7.5.5"
lodash "^4.17.11" lodash "^4.17.13"
"@babel/helper-explode-assignable-expression@^7.1.0": "@babel/helper-explode-assignable-expression@^7.1.0":
version "7.1.0" version "7.1.0"
@ -162,6 +180,13 @@
dependencies: dependencies:
"@babel/types" "^7.0.0" "@babel/types" "^7.0.0"
"@babel/helper-member-expression-to-functions@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590"
integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==
dependencies:
"@babel/types" "^7.5.5"
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49": "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49":
version "7.0.0" version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d"
@ -211,7 +236,7 @@
"@babel/traverse" "^7.1.0" "@babel/traverse" "^7.1.0"
"@babel/types" "^7.0.0" "@babel/types" "^7.0.0"
"@babel/helper-replace-supers@^7.1.0", "@babel/helper-replace-supers@^7.4.4": "@babel/helper-replace-supers@^7.4.4":
version "7.4.4" version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz#aee41783ebe4f2d3ab3ae775e1cc6f1a90cefa27"
integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg== integrity sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==
@ -221,6 +246,16 @@
"@babel/traverse" "^7.4.4" "@babel/traverse" "^7.4.4"
"@babel/types" "^7.4.4" "@babel/types" "^7.4.4"
"@babel/helper-replace-supers@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2"
integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.5.5"
"@babel/helper-optimise-call-expression" "^7.0.0"
"@babel/traverse" "^7.5.5"
"@babel/types" "^7.5.5"
"@babel/helper-simple-access@^7.1.0": "@babel/helper-simple-access@^7.1.0":
version "7.1.0" version "7.1.0"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c"
@ -278,6 +313,11 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872"
integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew== integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==
"@babel/parser@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b"
integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==
"@babel/plugin-proposal-async-generator-functions@^7.2.0": "@babel/plugin-proposal-async-generator-functions@^7.2.0":
version "7.2.0" version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e"
@ -304,6 +344,14 @@
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-decorators" "^7.2.0" "@babel/plugin-syntax-decorators" "^7.2.0"
"@babel/plugin-proposal-dynamic-import@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506"
integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
"@babel/plugin-proposal-json-strings@^7.2.0": "@babel/plugin-proposal-json-strings@^7.2.0":
version "7.2.0" version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317"
@ -312,10 +360,10 @@
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-json-strings" "^7.2.0" "@babel/plugin-syntax-json-strings" "^7.2.0"
"@babel/plugin-proposal-object-rest-spread@^7.4.4": "@babel/plugin-proposal-object-rest-spread@^7.4.4", "@babel/plugin-proposal-object-rest-spread@^7.5.5":
version "7.4.4" version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz#1ef173fcf24b3e2df92a678f027673b55e7e3005" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58"
integrity sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g== integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
@ -393,10 +441,10 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-async-to-generator@^7.4.4": "@babel/plugin-transform-async-to-generator@^7.5.0":
version "7.4.4" version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz#a3f1d01f2f21cadab20b33a82133116f14fb5894" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e"
integrity sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA== integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==
dependencies: dependencies:
"@babel/helper-module-imports" "^7.0.0" "@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
@ -409,25 +457,25 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-block-scoping@^7.4.4": "@babel/plugin-transform-block-scoping@^7.5.5":
version "7.4.4" version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz#c13279fabf6b916661531841a23c4b7dae29646d" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce"
integrity sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA== integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
lodash "^4.17.11" lodash "^4.17.13"
"@babel/plugin-transform-classes@^7.4.4": "@babel/plugin-transform-classes@^7.5.5":
version "7.4.4" version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz#0ce4094cdafd709721076d3b9c38ad31ca715eb6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9"
integrity sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw== integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==
dependencies: dependencies:
"@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-annotate-as-pure" "^7.0.0"
"@babel/helper-define-map" "^7.4.4" "@babel/helper-define-map" "^7.5.5"
"@babel/helper-function-name" "^7.1.0" "@babel/helper-function-name" "^7.1.0"
"@babel/helper-optimise-call-expression" "^7.0.0" "@babel/helper-optimise-call-expression" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/helper-replace-supers" "^7.4.4" "@babel/helper-replace-supers" "^7.5.5"
"@babel/helper-split-export-declaration" "^7.4.4" "@babel/helper-split-export-declaration" "^7.4.4"
globals "^11.1.0" globals "^11.1.0"
@ -438,10 +486,10 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-destructuring@^7.4.4": "@babel/plugin-transform-destructuring@^7.5.0":
version "7.4.4" version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz#9d964717829cc9e4b601fc82a26a71a4d8faf20f" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a"
integrity sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ== integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
@ -454,10 +502,10 @@
"@babel/helper-regex" "^7.4.4" "@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4" regexpu-core "^4.5.4"
"@babel/plugin-transform-duplicate-keys@^7.2.0": "@babel/plugin-transform-duplicate-keys@^7.5.0":
version "7.2.0" version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853"
integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
@ -498,30 +546,33 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-modules-amd@^7.2.0": "@babel/plugin-transform-modules-amd@^7.5.0":
version "7.2.0" version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91"
integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==
dependencies: dependencies:
"@babel/helper-module-transforms" "^7.1.0" "@babel/helper-module-transforms" "^7.1.0"
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-commonjs@^7.4.4": "@babel/plugin-transform-modules-commonjs@^7.5.0":
version "7.4.4" version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74"
integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw== integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==
dependencies: dependencies:
"@babel/helper-module-transforms" "^7.4.4" "@babel/helper-module-transforms" "^7.4.4"
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/helper-simple-access" "^7.1.0" "@babel/helper-simple-access" "^7.1.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-systemjs@^7.4.4": "@babel/plugin-transform-modules-systemjs@^7.5.0":
version "7.4.4" version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz#dc83c5665b07d6c2a7b224c00ac63659ea36a405" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249"
integrity sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ== integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==
dependencies: dependencies:
"@babel/helper-hoist-variables" "^7.4.4" "@babel/helper-hoist-variables" "^7.4.4"
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-umd@^7.2.0": "@babel/plugin-transform-modules-umd@^7.2.0":
version "7.2.0" version "7.2.0"
@ -545,13 +596,13 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-object-super@^7.2.0": "@babel/plugin-transform-object-super@^7.5.5":
version "7.2.0" version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9"
integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/helper-replace-supers" "^7.1.0" "@babel/helper-replace-supers" "^7.5.5"
"@babel/plugin-transform-parameters@^7.4.4": "@babel/plugin-transform-parameters@^7.4.4":
version "7.4.4" version "7.4.4"
@ -679,43 +730,45 @@
"@babel/helper-regex" "^7.4.4" "@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4" regexpu-core "^4.5.4"
"@babel/preset-env@^7.4.5": "@babel/preset-env@^7.5.5":
version "7.4.5" version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.5.tgz#2fad7f62983d5af563b5f3139242755884998a58" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a"
integrity sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w== integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==
dependencies: dependencies:
"@babel/helper-module-imports" "^7.0.0" "@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-proposal-async-generator-functions" "^7.2.0" "@babel/plugin-proposal-async-generator-functions" "^7.2.0"
"@babel/plugin-proposal-dynamic-import" "^7.5.0"
"@babel/plugin-proposal-json-strings" "^7.2.0" "@babel/plugin-proposal-json-strings" "^7.2.0"
"@babel/plugin-proposal-object-rest-spread" "^7.4.4" "@babel/plugin-proposal-object-rest-spread" "^7.5.5"
"@babel/plugin-proposal-optional-catch-binding" "^7.2.0" "@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
"@babel/plugin-proposal-unicode-property-regex" "^7.4.4" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
"@babel/plugin-syntax-async-generators" "^7.2.0" "@babel/plugin-syntax-async-generators" "^7.2.0"
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
"@babel/plugin-syntax-json-strings" "^7.2.0" "@babel/plugin-syntax-json-strings" "^7.2.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0" "@babel/plugin-syntax-object-rest-spread" "^7.2.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.2.0" "@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
"@babel/plugin-transform-arrow-functions" "^7.2.0" "@babel/plugin-transform-arrow-functions" "^7.2.0"
"@babel/plugin-transform-async-to-generator" "^7.4.4" "@babel/plugin-transform-async-to-generator" "^7.5.0"
"@babel/plugin-transform-block-scoped-functions" "^7.2.0" "@babel/plugin-transform-block-scoped-functions" "^7.2.0"
"@babel/plugin-transform-block-scoping" "^7.4.4" "@babel/plugin-transform-block-scoping" "^7.5.5"
"@babel/plugin-transform-classes" "^7.4.4" "@babel/plugin-transform-classes" "^7.5.5"
"@babel/plugin-transform-computed-properties" "^7.2.0" "@babel/plugin-transform-computed-properties" "^7.2.0"
"@babel/plugin-transform-destructuring" "^7.4.4" "@babel/plugin-transform-destructuring" "^7.5.0"
"@babel/plugin-transform-dotall-regex" "^7.4.4" "@babel/plugin-transform-dotall-regex" "^7.4.4"
"@babel/plugin-transform-duplicate-keys" "^7.2.0" "@babel/plugin-transform-duplicate-keys" "^7.5.0"
"@babel/plugin-transform-exponentiation-operator" "^7.2.0" "@babel/plugin-transform-exponentiation-operator" "^7.2.0"
"@babel/plugin-transform-for-of" "^7.4.4" "@babel/plugin-transform-for-of" "^7.4.4"
"@babel/plugin-transform-function-name" "^7.4.4" "@babel/plugin-transform-function-name" "^7.4.4"
"@babel/plugin-transform-literals" "^7.2.0" "@babel/plugin-transform-literals" "^7.2.0"
"@babel/plugin-transform-member-expression-literals" "^7.2.0" "@babel/plugin-transform-member-expression-literals" "^7.2.0"
"@babel/plugin-transform-modules-amd" "^7.2.0" "@babel/plugin-transform-modules-amd" "^7.5.0"
"@babel/plugin-transform-modules-commonjs" "^7.4.4" "@babel/plugin-transform-modules-commonjs" "^7.5.0"
"@babel/plugin-transform-modules-systemjs" "^7.4.4" "@babel/plugin-transform-modules-systemjs" "^7.5.0"
"@babel/plugin-transform-modules-umd" "^7.2.0" "@babel/plugin-transform-modules-umd" "^7.2.0"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5" "@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
"@babel/plugin-transform-new-target" "^7.4.4" "@babel/plugin-transform-new-target" "^7.4.4"
"@babel/plugin-transform-object-super" "^7.2.0" "@babel/plugin-transform-object-super" "^7.5.5"
"@babel/plugin-transform-parameters" "^7.4.4" "@babel/plugin-transform-parameters" "^7.4.4"
"@babel/plugin-transform-property-literals" "^7.2.0" "@babel/plugin-transform-property-literals" "^7.2.0"
"@babel/plugin-transform-regenerator" "^7.4.5" "@babel/plugin-transform-regenerator" "^7.4.5"
@ -726,7 +779,7 @@
"@babel/plugin-transform-template-literals" "^7.4.4" "@babel/plugin-transform-template-literals" "^7.4.4"
"@babel/plugin-transform-typeof-symbol" "^7.2.0" "@babel/plugin-transform-typeof-symbol" "^7.2.0"
"@babel/plugin-transform-unicode-regex" "^7.4.4" "@babel/plugin-transform-unicode-regex" "^7.4.4"
"@babel/types" "^7.4.4" "@babel/types" "^7.5.5"
browserslist "^4.6.0" browserslist "^4.6.0"
core-js-compat "^3.1.1" core-js-compat "^3.1.1"
invariant "^2.2.2" invariant "^2.2.2"
@ -798,13 +851,28 @@
globals "^11.1.0" globals "^11.1.0"
lodash "^4.17.11" lodash "^4.17.11"
"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.4", "@babel/types@^7.4.4": "@babel/traverse@^7.5.5":
version "7.4.4" version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb"
integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ== integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==
dependencies:
"@babel/code-frame" "^7.5.5"
"@babel/generator" "^7.5.5"
"@babel/helper-function-name" "^7.1.0"
"@babel/helper-split-export-declaration" "^7.4.4"
"@babel/parser" "^7.5.5"
"@babel/types" "^7.5.5"
debug "^4.1.0"
globals "^11.1.0"
lodash "^4.17.13"
"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.4", "@babel/types@^7.4.4", "@babel/types@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a"
integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==
dependencies: dependencies:
esutils "^2.0.2" esutils "^2.0.2"
lodash "^4.17.11" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@clusterws/cws@^0.15.0": "@clusterws/cws@^0.15.0":
@ -1445,6 +1513,14 @@ anymatch@^2.0.0:
micromatch "^3.1.4" micromatch "^3.1.4"
normalize-path "^2.1.1" normalize-path "^2.1.1"
anymatch@^3.0.1:
version "3.0.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.0.3.tgz#2fb624fe0e84bccab00afee3d0006ed310f22f09"
integrity sha512-c6IvoeBECQlMVuYUjSwimnhmztImpErfxJzWZhIQinIvQWoGOnB0dLIgifbPHQt5heS6mNlaZG16f06H3C8t1g==
dependencies:
normalize-path "^3.0.0"
picomatch "^2.0.4"
aproba@^1.0.3, aproba@^1.1.1: aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@ -1632,18 +1708,18 @@ atrament@^0.2.3:
version "0.2.3" version "0.2.3"
resolved "https://registry.yarnpkg.com/atrament/-/atrament-0.2.3.tgz#6ccbc0daa6d3f25e5aeaeb31befeb78e86980348" resolved "https://registry.yarnpkg.com/atrament/-/atrament-0.2.3.tgz#6ccbc0daa6d3f25e5aeaeb31befeb78e86980348"
autoprefixer@^9.6.0: autoprefixer@^9.6.1:
version "9.6.0" version "9.6.1"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.0.tgz#0111c6bde2ad20c6f17995a33fad7cf6854b4c87" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.1.tgz#51967a02d2d2300bb01866c1611ec8348d355a47"
integrity sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ== integrity sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==
dependencies: dependencies:
browserslist "^4.6.1" browserslist "^4.6.3"
caniuse-lite "^1.0.30000971" caniuse-lite "^1.0.30000980"
chalk "^2.4.2" chalk "^2.4.2"
normalize-range "^0.1.2" normalize-range "^0.1.2"
num2fraction "^1.2.2" num2fraction "^1.2.2"
postcss "^7.0.16" postcss "^7.0.17"
postcss-value-parser "^3.3.1" postcss-value-parser "^4.0.0"
aws-sign2@~0.7.0: aws-sign2@~0.7.0:
version "0.7.0" version "0.7.0"
@ -1705,6 +1781,13 @@ babel-loader@^8.0.6:
mkdirp "^0.5.1" mkdirp "^0.5.1"
pify "^4.0.1" pify "^4.0.1"
babel-plugin-dynamic-import-node@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f"
integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==
dependencies:
object.assign "^4.1.0"
babel-plugin-emotion@^9.2.11: babel-plugin-emotion@^9.2.11:
version "9.2.11" version "9.2.11"
resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-9.2.11.tgz#319c005a9ee1d15bb447f59fe504c35fd5807728" resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-9.2.11.tgz#319c005a9ee1d15bb447f59fe504c35fd5807728"
@ -1876,6 +1959,11 @@ binary-extensions@^1.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14"
integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==
binary-extensions@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
bluebird@^3.5.1, bluebird@^3.5.3: bluebird@^3.5.1, bluebird@^3.5.3:
version "3.5.3" version "3.5.3"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
@ -1948,6 +2036,13 @@ braces@^2.3.1, braces@^2.3.2:
split-string "^3.0.2" split-string "^3.0.2"
to-regex "^3.0.1" to-regex "^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==
dependencies:
fill-range "^7.0.1"
bricks.js@^1.7.0: bricks.js@^1.7.0:
version "1.8.0" version "1.8.0"
resolved "https://registry.yarnpkg.com/bricks.js/-/bricks.js-1.8.0.tgz#8fdeb3c0226af251f4d5727a7df7f9ac0092b4b2" resolved "https://registry.yarnpkg.com/bricks.js/-/bricks.js-1.8.0.tgz#8fdeb3c0226af251f4d5727a7df7f9ac0092b4b2"
@ -2031,14 +2126,14 @@ browserify-zlib@^0.2.0:
dependencies: dependencies:
pako "~1.0.5" pako "~1.0.5"
browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.6.1: browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.6.3:
version "4.6.2" version "4.6.6"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.2.tgz#574c665950915c2ac73a4594b8537a9eba26203f" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453"
integrity sha512-2neU/V0giQy9h3XMPwLhEY3+Ao0uHSwHvU8Q1Ea6AgLVL1sXbX3dzPrJ8NWe5Hi4PoTkCYXOtVR9rfRLI0J/8Q== integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==
dependencies: dependencies:
caniuse-lite "^1.0.30000974" caniuse-lite "^1.0.30000984"
electron-to-chromium "^1.3.150" electron-to-chromium "^1.3.191"
node-releases "^1.1.23" node-releases "^1.1.25"
bser@^2.0.0: bser@^2.0.0:
version "2.0.0" version "2.0.0"
@ -2182,10 +2277,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2" lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000971, caniuse-lite@^1.0.30000974: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000984:
version "1.0.30000974" version "1.0.30000986"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz#b7afe14ee004e97ce6dc73e3f878290a12928ad8" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000986.tgz#f34350e367cc900509511574817ac092112bf7ab"
integrity sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww== integrity sha512-pM+LnkoAX0+QnIH3tpW5EnkmfpEoqOD8FAcoBvsl3Xh6DXkgctiCxeCbXphP/k3XJtJzm+zOAJbi6U6IVkpWZQ==
capture-exit@^1.2.0: capture-exit@^1.2.0:
version "1.2.0" version "1.2.0"
@ -2241,7 +2336,22 @@ cheerio@^1.0.0-rc.2:
lodash "^4.15.0" lodash "^4.15.0"
parse5 "^3.0.1" parse5 "^3.0.1"
chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.1.6: "chokidar@>=2.0.0 <4.0.0":
version "3.0.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.2.tgz#0d1cd6d04eb2df0327446188cd13736a3367d681"
integrity sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==
dependencies:
anymatch "^3.0.1"
braces "^3.0.2"
glob-parent "^5.0.0"
is-binary-path "^2.1.0"
is-glob "^4.0.1"
normalize-path "^3.0.0"
readdirp "^3.1.1"
optionalDependencies:
fsevents "^2.0.6"
chokidar@^2.0.2, chokidar@^2.1.6:
version "2.1.6" version "2.1.6"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5"
integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==
@ -3299,10 +3409,10 @@ ejs@^2.3.4, ejs@^2.6.1:
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0"
integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==
electron-to-chromium@^1.3.150: electron-to-chromium@^1.3.191:
version "1.3.163" version "1.3.203"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.163.tgz#7fc3d637f5d8fa4ca4a052cad0de7675bd98b911" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.203.tgz#76de1b76eaaf7208e587a26b8e45407535a00abd"
integrity sha512-uCEoqQeKrjlhUSUudY0XvyNVDhWR5XmnCIV0WXr2Qo9PVzEVXI75LHGtzwro9Qh8NNetRjSitrm8AfQvPGaSqA== integrity sha512-Z1FjJKEBhYrCNmnususVk8khiBabVI/bSJB/295V4ghVt4MFmtbP+mXgRZLQZinEBI469U6FtiGgpXnlLs6qiQ==
elliptic@^6.0.0: elliptic@^6.0.0:
version "6.4.1" version "6.4.1"
@ -4086,13 +4196,13 @@ file-entry-cache@^5.0.1:
dependencies: dependencies:
flat-cache "^2.0.1" flat-cache "^2.0.1"
file-loader@^4.0.0: file-loader@^4.1.0:
version "4.0.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.0.0.tgz#c3570783fefb6e1bc0978a856f4bf5825b966c2a" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.1.0.tgz#3a763391bc9502da7c59612fe348e38fc1980336"
integrity sha512-roAbL6IdSGczwfXxhMi6Zq+jD4IfUpL0jWHD7fvmjdOVb7xBfdRUHe4LpBgO23VtVK5AW1OlWZo0p34Jvx3iWg== integrity sha512-ajDk1nlByoalZAGR4b0H6oD+EGlWnyW1qbSxzaUc7RFiqmn+RbXQQRbTc72jsiUIlVusJ4Et58ltds8ZwTfnAw==
dependencies: dependencies:
loader-utils "^1.2.2" loader-utils "^1.2.3"
schema-utils "^1.0.0" schema-utils "^2.0.0"
filesize@^3.6.1: filesize@^3.6.1:
version "3.6.1" version "3.6.1"
@ -4109,6 +4219,13 @@ fill-range@^4.0.0:
repeat-string "^1.6.1" repeat-string "^1.6.1"
to-regex-range "^2.1.0" to-regex-range "^2.1.0"
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
dependencies:
to-regex-range "^5.0.1"
finalhandler@~1.1.2: finalhandler@~1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
@ -4339,6 +4456,11 @@ fsevents@^1.2.7:
nan "^2.12.1" nan "^2.12.1"
node-pre-gyp "^0.12.0" node-pre-gyp "^0.12.0"
fsevents@^2.0.6:
version "2.0.7"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a"
integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==
function-bind@^1.0.2, function-bind@^1.1.1: function-bind@^1.0.2, function-bind@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@ -5115,6 +5237,13 @@ is-binary-path@^1.0.0:
dependencies: dependencies:
binary-extensions "^1.0.0" binary-extensions "^1.0.0"
is-binary-path@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
dependencies:
binary-extensions "^2.0.0"
is-boolean-object@^1.0.0: is-boolean-object@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
@ -5286,6 +5415,11 @@ is-number@^3.0.0:
dependencies: dependencies:
kind-of "^3.0.2" kind-of "^3.0.2"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-obj@^1.0.0: is-obj@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
@ -6107,7 +6241,7 @@ loader-utils@0.2.x:
json5 "^0.5.0" json5 "^0.5.0"
object-assign "^4.0.1" object-assign "^4.0.1"
loader-utils@1.2.3, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.2, loader-utils@^1.2.3: loader-utils@1.2.3, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"
integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==
@ -6209,7 +6343,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10: lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10:
version "4.17.15" version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@ -6718,10 +6852,10 @@ node-pre-gyp@^0.12.0:
semver "^5.3.0" semver "^5.3.0"
tar "^4" tar "^4"
node-releases@^1.1.23: node-releases@^1.1.25:
version "1.1.23" version "1.1.26"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.23.tgz#de7409f72de044a2fa59c097f436ba89c39997f0" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.26.tgz#f30563edc5c7dc20cf524cc8652ffa7be0762937"
integrity sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w== integrity sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ==
dependencies: dependencies:
semver "^5.3.0" semver "^5.3.0"
@ -7385,6 +7519,11 @@ pgpass@1.*:
dependencies: dependencies:
split "^1.0.0" split "^1.0.0"
picomatch@^2.0.4:
version "2.0.7"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6"
integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==
pify@^2.0.0: pify@^2.0.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@ -8463,6 +8602,13 @@ readdirp@^2.2.1:
micromatch "^3.1.10" micromatch "^3.1.10"
readable-stream "^2.0.2" readable-stream "^2.0.2"
readdirp@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.1.1.tgz#b158123ac343c8b0f31d65680269cc0fc1025db1"
integrity sha512-XXdSXZrQuvqoETj50+JAitxz1UPdt5dupjT6T5nVB+WvjMv2XKYj+s7hPeAVCXvmJrL36O4YYyWlIC3an2ePiQ==
dependencies:
picomatch "^2.0.4"
readline2@^1.0.1: readline2@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
@ -8920,12 +9066,12 @@ sass-loader@^7.0.3:
pify "^3.0.0" pify "^3.0.0"
semver "^5.5.0" semver "^5.5.0"
sass@^1.20.3: sass@^1.22.7:
version "1.20.3" version "1.22.7"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.20.3.tgz#18284a7bac6eab9cbb80453288473194f29efb84" resolved "https://registry.yarnpkg.com/sass/-/sass-1.22.7.tgz#5a1a77dc11aa659db4e782d238bf9f3d44a60546"
integrity sha512-kvf+w5XT7FrmFrCKz1gPHqegufG+gxifC8oQesX/s8gkShdeiTqiuvP0c8TvfBwMAuI1YGOgobZQ2KIJGn//jA== integrity sha512-ahREi0AdG7RTovSv14+yd1prQSfIvFcrDpOsth5EQf1+RM7SvOxsSttzNQaFmK1aa/k/3vyYwlYF5l0Xl+6c+g==
dependencies: dependencies:
chokidar "^2.0.0" chokidar ">=2.0.0 <4.0.0"
sax@^1.2.4, sax@~1.2.4: sax@^1.2.4, sax@~1.2.4:
version "1.2.4" version "1.2.4"
@ -9782,6 +9928,13 @@ to-regex-range@^2.1.0:
is-number "^3.0.0" is-number "^3.0.0"
repeat-string "^1.6.1" repeat-string "^1.6.1"
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
to-regex@^3.0.1, to-regex@^3.0.2: to-regex@^3.0.1, to-regex@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
@ -10478,7 +10631,7 @@ yargs-parser@^11.1.1:
camelcase "^5.0.0" camelcase "^5.0.0"
decamelize "^1.2.0" decamelize "^1.2.0"
yargs-parser@^13.1.0: yargs-parser@^13.1.0, yargs-parser@^13.1.1:
version "13.1.1" version "13.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"
integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
@ -10486,7 +10639,7 @@ yargs-parser@^13.1.0:
camelcase "^5.0.0" camelcase "^5.0.0"
decamelize "^1.2.0" decamelize "^1.2.0"
yargs@12.0.5, yargs@^12.0.2, yargs@^12.0.5: yargs@12.0.5, yargs@^12.0.2:
version "12.0.5" version "12.0.5"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
@ -10520,3 +10673,19 @@ yargs@13.2.4:
which-module "^2.0.0" which-module "^2.0.0"
y18n "^4.0.0" y18n "^4.0.0"
yargs-parser "^13.1.0" yargs-parser "^13.1.0"
yargs@^13.3.0:
version "13.3.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83"
integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==
dependencies:
cliui "^5.0.0"
find-up "^3.0.0"
get-caller-file "^2.0.1"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^3.0.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^13.1.1"