Compare commits

...

20 commits

Author SHA1 Message Date
Eugen Rochko
b9964bd932 Bump version to 2.5.3 2018-12-02 17:32:57 +01:00
Eugen Rochko
6cf5716ece Skip deliveries to inboxes that have already been marked as unavailable (#9358) 2018-12-02 17:26:09 +01:00
Eugen Rochko
4cc9ada971 Fix nil error when no DNS addresses are found for host (#9379) 2018-12-02 17:25:54 +01:00
Hugo Gameiro
8c8575db74 add loglevel to ffmpeg in gif upload (#9368) 2018-12-02 17:25:40 +01:00
ThibG
4ffdf33137 Preload common JSON-LD contexts (#9412)
Fixes #9411
2018-12-02 17:18:38 +01:00
Eugen Rochko
048b2479c8 Remove npm-run-all dependency (#9401)
Fix #9359
2018-12-02 17:18:12 +01:00
Eugen Rochko
f5e7a4cdfa Fix TLS handshake timeout not being enforced (#9381)
Follow-up to #9329
2018-12-02 17:16:07 +01:00
Eugen Rochko
4fba16cbb8 Fix connect timeout not being enforced (#9329)
* Fix connect timeout not being enforced

The loop was catching the timeout exception that should stop execution, so the next IP would no longer be within a timed block, which led to requests taking much longer than 10 seconds.

* Use timeout on each IP attempt, but limit to 2 attempts

* Fix code style issue

* Do not break Request#perform if no block given

* Update method stub in spec for Request

* Move timeout inside the begin/rescue block

* Use Resolv::DNS with timeout of 1 to get IP addresses

* Update Request spec to stub Resolv::DNS instead of Addrinfo

* Fix Resolve::DNS stubs in Request spec
2018-12-02 17:15:36 +01:00
Eugen Rochko
c35be6c7e1 Prevent multiple handlers for Delete of Actor from running (#9292) 2018-12-02 17:14:06 +01:00
Eugen Rochko
e8a4ba49cf Bump version to 2.5.2 2018-10-12 00:22:38 +02:00
Eugen Rochko
1787704e1c Improve signature verification safeguards (#8959)
* Downcase signed_headers string before building the signed string

The HTTP Signatures draft does not mandate the “headers” field to be downcased,
but mandates the header field names to be downcased in the signed string, which
means that prior to this patch, Mastodon could fail to process signatures from
some compliant clients. It also means that it would not actually check the
Digest of non-compliant clients that wouldn't use a lowercased Digest field
name.

Thankfully, I don't know of any such client.

* Revert "Remove dead code (#8919)"

This reverts commit a00ce8c92c.

* Restore time window checking, change it to 12 hours

By checking the Date header, we can prevent replaying old vulnerable
signatures. The focus is to prevent replaying old vulnerable requests
from software that has been fixed in the meantime, so a somewhat long
window should be fine and accounts for timezone misconfiguration.

* Escape users' URLs when formatting them

Fixes possible HTML injection

* Escape all string interpolations in Formatter class

Slightly improve performance by reducing class allocations
from repeated Formatter#encode calls

* Fix code style issues
2018-10-12 00:17:36 +02:00
Eugen Rochko
65662b3847 Bump version to 2.5.1 2018-10-07 20:13:54 +02:00
ThibG
6984396b11 Ensure only toots from the reported users are reported (#8916) 2018-10-07 19:46:15 +02:00
Eugen Rochko
485dc7d559 Add fallback for PostgreSQL without upsert in CopyStatusStats (#8903)
Fix #8590
2018-10-07 18:42:11 +02:00
dependabot[bot]
a1b904441e Bump puma from 3.11.4 to 3.12.0 (#8883)
Bumps [puma](https://github.com/puma/puma) from 3.11.4 to 3.12.0.
- [Release notes](https://github.com/puma/puma/releases)
- [Changelog](https://github.com/puma/puma/blob/master/History.md)
- [Commits](https://github.com/puma/puma/compare/v3.11.4...v3.12.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-10-07 18:42:04 +02:00
dependabot[bot]
0d844c0780 [Security] Bump nokogiri from 1.8.4 to 1.8.5 (#8881)
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.8.4 to 1.8.5. **This update includes security fixes.**
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.8.4...v1.8.5)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-10-07 18:40:49 +02:00
ThibG
c2f31d908e Fix handling of ActivityPub activities lacking some attributes (#8864) 2018-10-07 18:40:31 +02:00
Yamagishi Kazutoshi
38a48a627c Fix that Rails.cache information could not be sent via StatsD (#8831) 2018-10-07 18:40:10 +02:00
Eugen Rochko
10f7278e9a Fix class autoloading issue in ActivityPub::Activity::Create (#8820) 2018-10-07 18:39:52 +02:00
ThibG
39e84d174d Unconditionally re-encode locally-uploaded images to strip metadata (#8714)
This strips metadata on file upload by re-encoding the files, at the cost
of possible slight image quality decrease and processing resources.
2018-10-07 18:37:22 +02:00
25 changed files with 260 additions and 170 deletions

24
CHANGELOG.md Normal file
View file

@ -0,0 +1,24 @@
## 2.5.3
- Fix already queued deliveries still trying to reach inboxes marked as unavailable (#9358)
- Fix ffmpeg processing sometimes stalling due to overfilled stdout buffer (#9368)
- Fix failures caused by commonly-used JSON-LD contexts being unavailable (#9412)
- Fix yarn dependencies not installing due to yanked event-stream package (#9401)
- Fix TLS handshake timeout not being enforced (#9381)
- Fix HTTP connection timeout of 10s not being enforced (#9329)
- Fix multiple remote account deletions being able to deadlock the database (#9292)
## 2.5.2
- Fix XSS vulnerability (#8959)
## 2.5.1
- Fix some local images not having their EXIF metadata stripped on upload (#8714)
- Fix class autoloading issue in ActivityPub Create handler (#8820)
- Fix cache statistics not being sent via statsd when statsd enabled (#8831)
- Fix being able to enable a disabled relay via ActivityPub Accept handler (#8864)
- Bump nokogiri from 1.8.4 to 1.8.5 (#8881)
- Bump puma from 3.11.4 to 3.12.0 (#8883)
- Fix database migrations for PostgreSQL below 9.5 (#8903)
- Fix being able to report statuses not belonging to the reported account (#8916)

View file

@ -5,7 +5,7 @@ ruby '>= 2.3.0', '< 2.6.0'
gem 'pkg-config', '~> 1.3' gem 'pkg-config', '~> 1.3'
gem 'puma', '~> 3.11' gem 'puma', '~> 3.12'
gem 'rails', '~> 5.2.1' gem 'rails', '~> 5.2.1'
gem 'thor', '~> 0.20' gem 'thor', '~> 0.20'
@ -91,6 +91,7 @@ gem 'webpacker', '~> 3.4'
gem 'webpush' gem 'webpush'
gem 'json-ld', '~> 2.2' gem 'json-ld', '~> 2.2'
gem 'json-ld-preloaded', '~> 2.2'
gem 'rdf-normalize', '~> 0.3' gem 'rdf-normalize', '~> 0.3'
group :development, :test do group :development, :test do

View file

@ -287,6 +287,10 @@ GEM
json-ld (2.2.1) json-ld (2.2.1)
multi_json (~> 1.12) multi_json (~> 1.12)
rdf (>= 2.2.8, < 4.0) rdf (>= 2.2.8, < 4.0)
json-ld-preloaded (2.2.3)
json-ld (>= 2.2, < 4.0)
multi_json (~> 1.12)
rdf (>= 2.2, < 4.0)
jsonapi-renderer (0.2.0) jsonapi-renderer (0.2.0)
jwt (2.1.0) jwt (2.1.0)
kaminari (1.1.1) kaminari (1.1.1)
@ -347,7 +351,7 @@ GEM
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh (4.2.0) net-ssh (4.2.0)
nio4r (2.3.1) nio4r (2.3.1)
nokogiri (1.8.4) nokogiri (1.8.5)
mini_portile2 (~> 2.3.0) mini_portile2 (~> 2.3.0)
nokogumbo (1.5.0) nokogumbo (1.5.0)
nokogiri nokogiri
@ -412,7 +416,7 @@ GEM
pry-rails (0.3.6) pry-rails (0.3.6)
pry (>= 0.10.4) pry (>= 0.10.4)
public_suffix (3.0.2) public_suffix (3.0.2)
puma (3.11.4) puma (3.12.0)
pundit (1.1.0) pundit (1.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
rack (2.0.5) rack (2.0.5)
@ -691,6 +695,7 @@ DEPENDENCIES
idn-ruby idn-ruby
iso-639 iso-639
json-ld (~> 2.2) json-ld (~> 2.2)
json-ld-preloaded (~> 2.2)
kaminari (~> 1.1) kaminari (~> 1.1)
letter_opener (~> 1.4) letter_opener (~> 1.4)
letter_opener_web (~> 1.3) letter_opener_web (~> 1.3)
@ -721,7 +726,7 @@ DEPENDENCIES
private_address_check (~> 0.4.1) private_address_check (~> 0.4.1)
pry-byebug (~> 3.6) pry-byebug (~> 3.6)
pry-rails (~> 0.3) pry-rails (~> 0.3)
puma (~> 3.11) puma (~> 3.12)
pundit (~> 1.1) pundit (~> 1.1)
rack-attack (~> 5.2) rack-attack (~> 5.2)
rack-cors (~> 1.0) rack-cors (~> 1.0)
@ -765,4 +770,4 @@ RUBY VERSION
ruby 2.5.0p0 ruby 2.5.0p0
BUNDLED WITH BUNDLED WITH
1.16.3 1.16.5

View file

@ -27,7 +27,7 @@ class Api::V1::ReportsController < Api::BaseController
private private
def reported_status_ids def reported_status_ids
Status.find(status_ids).pluck(:id) reported_account.statuses.find(status_ids).pluck(:id)
end end
def status_ids def status_ids

View file

@ -22,6 +22,12 @@ module SignatureVerification
return return
end end
if request.headers['Date'].present? && !matches_time_window?
@signature_verification_failure_reason = 'Signed request date outside acceptable time window'
@signed_request_account = nil
return
end
raw_signature = request.headers['Signature'] raw_signature = request.headers['Signature']
signature_params = {} signature_params = {}
@ -76,7 +82,7 @@ module SignatureVerification
def build_signed_string(signed_headers) def build_signed_string(signed_headers)
signed_headers = 'date' if signed_headers.blank? signed_headers = 'date' if signed_headers.blank?
signed_headers.split(' ').map do |signed_header| signed_headers.downcase.split(' ').map do |signed_header|
if signed_header == Request::REQUEST_TARGET if signed_header == Request::REQUEST_TARGET
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}" "#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
elsif signed_header == 'digest' elsif signed_header == 'digest'
@ -89,12 +95,12 @@ module SignatureVerification
def matches_time_window? def matches_time_window?
begin begin
time_sent = DateTime.httpdate(request.headers['Date']) time_sent = Time.httpdate(request.headers['Date'])
rescue ArgumentError rescue ArgumentError
return false return false
end end
(Time.now.utc - time_sent).abs <= 30 (Time.now.utc - time_sent).abs <= 12.hours
end end
def body_digest def body_digest

View file

@ -129,4 +129,10 @@ class ActivityPub::Activity
::FetchRemoteStatusService.new.call(@object['url']) ::FetchRemoteStatusService.new.call(@object['url'])
end end
end end
def lock_or_return(key, expire_after = 7.days.seconds)
yield if redis.set(key, true, nx: true, ex: expire_after)
ensure
redis.del(key)
end
end end

View file

@ -26,7 +26,7 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
end end
def relay def relay
@relay ||= Relay.find_by(follow_activity_id: object_uri) @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
end end
def relay_follow? def relay_follow?

View file

@ -92,7 +92,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
return if tag['href'].blank? return if tag['href'].blank?
account = account_from_uri(tag['href']) account = account_from_uri(tag['href'])
account = FetchRemoteAccountService.new.call(tag['href'], id: false) if account.nil? account = ::FetchRemoteAccountService.new.call(tag['href'], id: false) if account.nil?
return if account.nil? return if account.nil?
account.mentions.create(status: status) account.mentions.create(status: status)
end end

View file

@ -12,11 +12,15 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
private private
def delete_person def delete_person
SuspendAccountService.new.call(@account) lock_or_return("delete_in_progress:#{@account.id}") do
@account.destroy! SuspendAccountService.new.call(@account)
@account.destroy!
end
end end
def delete_note def delete_note
return if object_uri.nil?
@status = Status.find_by(uri: object_uri, account: @account) @status = Status.find_by(uri: object_uri, account: @account)
@status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present? @status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?

View file

@ -28,7 +28,7 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
end end
def relay def relay
@relay ||= Relay.find_by(follow_activity_id: object_uri) @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
end end
def relay_follow? def relay_follow?

View file

@ -19,6 +19,8 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
private private
def undo_announce def undo_announce
return if object_uri.nil?
status = Status.find_by(uri: object_uri, account: @account) status = Status.find_by(uri: object_uri, account: @account)
status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present? status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?

View file

@ -90,8 +90,12 @@ class Formatter
private private
def html_entities
@html_entities ||= HTMLEntities.new
end
def encode(html) def encode(html)
HTMLEntities.new.encode(html) html_entities.encode(html)
end end
def encode_and_link_urls(html, accounts = nil, options = {}) def encode_and_link_urls(html, accounts = nil, options = {})
@ -143,7 +147,7 @@ class Formatter
emoji = emoji_map[shortcode] emoji = emoji_map[shortcode]
if emoji if emoji
replacement = "<img draggable=\"false\" class=\"emojione\" alt=\":#{shortcode}:\" title=\":#{shortcode}:\" src=\"#{emoji}\" />" replacement = "<img draggable=\"false\" class=\"emojione\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(emoji)}\" />"
before_html = shortname_start_index.positive? ? html[0..shortname_start_index - 1] : '' before_html = shortname_start_index.positive? ? html[0..shortname_start_index - 1] : ''
html = before_html + replacement + html[i + 1..-1] html = before_html + replacement + html[i + 1..-1]
i += replacement.size - (shortcode.size + 2) - 1 i += replacement.size - (shortcode.size + 2) - 1
@ -212,7 +216,7 @@ class Formatter
return link_to_account(acct) unless linkable_accounts return link_to_account(acct) unless linkable_accounts
account = linkable_accounts.find { |item| TagManager.instance.same_acct?(item.acct, acct) } account = linkable_accounts.find { |item| TagManager.instance.same_acct?(item.acct, acct) }
account ? mention_html(account) : "@#{acct}" account ? mention_html(account) : "@#{encode(acct)}"
end end
def link_to_account(acct) def link_to_account(acct)
@ -221,7 +225,7 @@ class Formatter
domain = nil if TagManager.instance.local_domain?(domain) domain = nil if TagManager.instance.local_domain?(domain)
account = EntityCache.instance.mention(username, domain) account = EntityCache.instance.mention(username, domain)
account ? mention_html(account) : "@#{acct}" account ? mention_html(account) : "@#{encode(acct)}"
end end
def link_to_hashtag(entity) def link_to_hashtag(entity)
@ -239,10 +243,10 @@ class Formatter
end end
def hashtag_html(tag) def hashtag_html(tag)
"<a href=\"#{tag_url(tag.downcase)}\" class=\"mention hashtag\" rel=\"tag\">#<span>#{tag}</span></a>" "<a href=\"#{encode(tag_url(tag.downcase))}\" class=\"mention hashtag\" rel=\"tag\">#<span>#{encode(tag)}</span></a>"
end end
def mention_html(account) def mention_html(account)
"<span class=\"h-card\"><a href=\"#{TagManager.instance.url_for(account)}\" class=\"u-url mention\">@<span>#{account.username}</span></a></span>" "<span class=\"h-card\"><a href=\"#{encode(TagManager.instance.url_for(account))}\" class=\"u-url mention\">@<span>#{encode(account.username)}</span></a></span>"
end end
end end

View file

@ -2,6 +2,17 @@
require 'ipaddr' require 'ipaddr'
require 'socket' require 'socket'
require 'resolv'
# Monkey-patch the HTTP.rb timeout class to avoid using a timeout block
# around the Socket#open method, since we use our own timeout blocks inside
# that method
class HTTP::Timeout::PerOperation
def connect(socket_class, host, port, nodelay = false)
@socket = socket_class.open(host, port)
@socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) if nodelay
end
end
class Request class Request
REQUEST_TARGET = '(request-target)' REQUEST_TARGET = '(request-target)'
@ -45,7 +56,7 @@ class Request
end end
begin begin
yield response.extend(ClientLimit) yield response.extend(ClientLimit) if block_given?
ensure ensure
http_client.close http_client.close
end end
@ -94,7 +105,11 @@ class Request
end end
def timeout def timeout
{ write: 10, connect: 10, read: 10 } # We enforce a 1s timeout on DNS resolving, 10s timeout on socket opening
# and 5s timeout on the TLS handshake, meaning the worst case should take
# about 16s in total
{ connect: 5, read: 10, write: 10 }
end end
def http_client def http_client
@ -139,17 +154,34 @@ class Request
class Socket < TCPSocket class Socket < TCPSocket
class << self class << self
def open(host, *args) def open(host, *args)
return super host, *args if thru_hidden_service? host return super(host, *args) if thru_hidden_service?(host)
outer_e = nil outer_e = nil
Addrinfo.foreach(host, nil, nil, :SOCK_STREAM) do |address|
begin Resolv::DNS.open do |dns|
raise Mastodon::HostValidationError if PrivateAddressCheck.private_address? IPAddr.new(address.ip_address) dns.timeouts = 1
return super address.ip_address, *args
rescue => e addresses = dns.getaddresses(host).take(2)
outer_e = e time_slot = 10.0 / addresses.size
addresses.each do |address|
begin
raise Mastodon::HostValidationError if PrivateAddressCheck.private_address?(IPAddr.new(address.to_s))
::Timeout.timeout(time_slot, HTTP::TimeoutError) do
return super(address.to_s, *args)
end
rescue => e
outer_e = e
end
end end
end end
raise outer_e if outer_e
if outer_e
raise outer_e
else
raise SocketError, "No address for #{host}"
end
end end
alias new open alias new open

View file

@ -59,6 +59,7 @@ class MediaAttachment < ApplicationRecord
format: 'mp4', format: 'mp4',
convert_options: { convert_options: {
output: { output: {
'loglevel' => 'fatal',
'movflags' => 'faststart', 'movflags' => 'faststart',
'pix_fmt' => 'yuv420p', 'pix_fmt' => 'yuv420p',
'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'', 'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',

View file

@ -11,6 +11,8 @@ class ActivityPub::DeliveryWorker
HEADERS = { 'Content-Type' => 'application/activity+json' }.freeze HEADERS = { 'Content-Type' => 'application/activity+json' }.freeze
def perform(json, source_account_id, inbox_url, options = {}) def perform(json, source_account_id, inbox_url, options = {})
return if DeliveryFailureTracker.unavailable?(inbox_url)
@options = options.with_indifferent_access @options = options.with_indifferent_access
@json = json @json = json
@source_account = Account.find(source_account_id) @source_account = Account.find(source_account_id)

View file

@ -0,0 +1,3 @@
# frozen_string_literal: true
require_relative '../../lib/json_ld/security'

View file

@ -9,7 +9,7 @@ if ENV['STATSD_ADDR'].present?
::NSA.inform_statsd(statsd) do |informant| ::NSA.inform_statsd(statsd) do |informant|
informant.collect(:action_controller, :web) informant.collect(:action_controller, :web)
informant.collect(:active_record, :db) informant.collect(:active_record, :db)
informant.collect(:cache, :cache) informant.collect(:active_support_cache, :cache)
informant.collect(:sidekiq, :sidekiq) informant.collect(:sidekiq, :sidekiq)
end end
end end

View file

@ -3,15 +3,10 @@ class CopyStatusStats < ActiveRecord::Migration[5.2]
def up def up
safety_assured do safety_assured do
Status.unscoped.select('id').find_in_batches(batch_size: 5_000) do |statuses| if supports_upsert?
execute <<-SQL.squish up_fast
INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) else
SELECT id, reblogs_count, favourites_count, created_at, updated_at up_slow
FROM statuses
WHERE id IN (#{statuses.map(&:id).join(', ')})
ON CONFLICT (status_id) DO UPDATE
SET reblogs_count = EXCLUDED.reblogs_count, favourites_count = EXCLUDED.favourites_count
SQL
end end
end end
end end
@ -19,4 +14,41 @@ class CopyStatusStats < ActiveRecord::Migration[5.2]
def down def down
# Nothing # Nothing
end end
private
def supports_upsert?
version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i
version >= 90500
end
def up_fast
say 'Upsert is available, importing counters using the fast method'
Status.unscoped.select('id').find_in_batches(batch_size: 5_000) do |statuses|
execute <<-SQL.squish
INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at)
SELECT id, reblogs_count, favourites_count, created_at, updated_at
FROM statuses
WHERE id IN (#{statuses.map(&:id).join(', ')})
ON CONFLICT (status_id) DO UPDATE
SET reblogs_count = EXCLUDED.reblogs_count, favourites_count = EXCLUDED.favourites_count
SQL
end
end
def up_slow
say 'Upsert is not available in PostgreSQL below 9.5, falling back to slow import of counters'
# We cannot use bulk INSERT or overarching transactions here because of possible
# uniqueness violations that we need to skip over
Status.unscoped.select('id, reblogs_count, favourites_count, created_at, updated_at').find_each do |status|
begin
params = [[nil, status.id], [nil, status.reblogs_count], [nil, status.favourites_count], [nil, status.created_at], [nil, status.updated_at]]
exec_insert('INSERT INTO status_stats (status_id, reblogs_count, favourites_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5)', nil, params)
rescue ActiveRecord::RecordNotUnique
next
end
end
end
end end

50
lib/json_ld/security.rb Normal file
View file

@ -0,0 +1,50 @@
# -*- encoding: utf-8 -*-
# frozen_string_literal: true
# This file generated automatically from https://w3id.org/security/v1
require 'json/ld'
class JSON::LD::Context
add_preloaded("https://w3id.org/security/v1") do
new(processingMode: "json-ld-1.0", term_definitions: {
"CryptographicKey" => TermDefinition.new("CryptographicKey", id: "https://w3id.org/security#Key", simple: true),
"EcdsaKoblitzSignature2016" => TermDefinition.new("EcdsaKoblitzSignature2016", id: "https://w3id.org/security#EcdsaKoblitzSignature2016", simple: true),
"EncryptedMessage" => TermDefinition.new("EncryptedMessage", id: "https://w3id.org/security#EncryptedMessage", simple: true),
"GraphSignature2012" => TermDefinition.new("GraphSignature2012", id: "https://w3id.org/security#GraphSignature2012", simple: true),
"LinkedDataSignature2015" => TermDefinition.new("LinkedDataSignature2015", id: "https://w3id.org/security#LinkedDataSignature2015", simple: true),
"LinkedDataSignature2016" => TermDefinition.new("LinkedDataSignature2016", id: "https://w3id.org/security#LinkedDataSignature2016", simple: true),
"authenticationTag" => TermDefinition.new("authenticationTag", id: "https://w3id.org/security#authenticationTag", simple: true),
"canonicalizationAlgorithm" => TermDefinition.new("canonicalizationAlgorithm", id: "https://w3id.org/security#canonicalizationAlgorithm", simple: true),
"cipherAlgorithm" => TermDefinition.new("cipherAlgorithm", id: "https://w3id.org/security#cipherAlgorithm", simple: true),
"cipherData" => TermDefinition.new("cipherData", id: "https://w3id.org/security#cipherData", simple: true),
"cipherKey" => TermDefinition.new("cipherKey", id: "https://w3id.org/security#cipherKey", simple: true),
"created" => TermDefinition.new("created", id: "http://purl.org/dc/terms/created", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
"creator" => TermDefinition.new("creator", id: "http://purl.org/dc/terms/creator", type_mapping: "@id"),
"dc" => TermDefinition.new("dc", id: "http://purl.org/dc/terms/", simple: true, prefix: true),
"digestAlgorithm" => TermDefinition.new("digestAlgorithm", id: "https://w3id.org/security#digestAlgorithm", simple: true),
"digestValue" => TermDefinition.new("digestValue", id: "https://w3id.org/security#digestValue", simple: true),
"domain" => TermDefinition.new("domain", id: "https://w3id.org/security#domain", simple: true),
"encryptionKey" => TermDefinition.new("encryptionKey", id: "https://w3id.org/security#encryptionKey", simple: true),
"expiration" => TermDefinition.new("expiration", id: "https://w3id.org/security#expiration", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
"expires" => TermDefinition.new("expires", id: "https://w3id.org/security#expiration", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
"id" => TermDefinition.new("id", id: "@id", simple: true),
"initializationVector" => TermDefinition.new("initializationVector", id: "https://w3id.org/security#initializationVector", simple: true),
"iterationCount" => TermDefinition.new("iterationCount", id: "https://w3id.org/security#iterationCount", simple: true),
"nonce" => TermDefinition.new("nonce", id: "https://w3id.org/security#nonce", simple: true),
"normalizationAlgorithm" => TermDefinition.new("normalizationAlgorithm", id: "https://w3id.org/security#normalizationAlgorithm", simple: true),
"owner" => TermDefinition.new("owner", id: "https://w3id.org/security#owner", type_mapping: "@id"),
"password" => TermDefinition.new("password", id: "https://w3id.org/security#password", simple: true),
"privateKey" => TermDefinition.new("privateKey", id: "https://w3id.org/security#privateKey", type_mapping: "@id"),
"privateKeyPem" => TermDefinition.new("privateKeyPem", id: "https://w3id.org/security#privateKeyPem", simple: true),
"publicKey" => TermDefinition.new("publicKey", id: "https://w3id.org/security#publicKey", type_mapping: "@id"),
"publicKeyPem" => TermDefinition.new("publicKeyPem", id: "https://w3id.org/security#publicKeyPem", simple: true),
"publicKeyService" => TermDefinition.new("publicKeyService", id: "https://w3id.org/security#publicKeyService", type_mapping: "@id"),
"revoked" => TermDefinition.new("revoked", id: "https://w3id.org/security#revoked", type_mapping: "http://www.w3.org/2001/XMLSchema#dateTime"),
"salt" => TermDefinition.new("salt", id: "https://w3id.org/security#salt", simple: true),
"sec" => TermDefinition.new("sec", id: "https://w3id.org/security#", simple: true, prefix: true),
"signature" => TermDefinition.new("signature", id: "https://w3id.org/security#signature", simple: true),
"signatureAlgorithm" => TermDefinition.new("signatureAlgorithm", id: "https://w3id.org/security#signingAlgorithm", simple: true),
"signatureValue" => TermDefinition.new("signatureValue", id: "https://w3id.org/security#signatureValue", simple: true),
"type" => TermDefinition.new("type", id: "@type", simple: true),
"xsd" => TermDefinition.new("xsd", id: "http://www.w3.org/2001/XMLSchema#", simple: true, prefix: true)
})
end
end

View file

@ -13,7 +13,7 @@ module Mastodon
end end
def patch def patch
0 3
end end
def pre def pre

View file

@ -20,7 +20,7 @@ module Paperclip
private private
def needs_convert? def needs_convert?
needs_different_geometry? || needs_different_format? needs_different_geometry? || needs_different_format? || needs_metadata_stripping?
end end
def needs_different_geometry? def needs_different_geometry?
@ -31,5 +31,9 @@ module Paperclip
def needs_different_format? def needs_different_format?
@format.present? && @current_format != @format @format.present? && @current_format != @format
end end
def needs_metadata_stripping?
@attachment.instance.respond_to?(:local?) && @attachment.instance.local?
end
end end
end end

View file

@ -10,7 +10,7 @@
"build:production": "cross-env RAILS_ENV=production ./bin/webpack", "build:production": "cross-env RAILS_ENV=production ./bin/webpack",
"manage:translations": "node ./config/webpack/translationRunner.js", "manage:translations": "node ./config/webpack/translationRunner.js",
"start": "node ./streaming/index.js", "start": "node ./streaming/index.js",
"test": "npm-run-all test:lint test:jest", "test": "npm run test:lint && npm run test:jest",
"test:lint": "eslint -c .eslintrc.yml --ext=js app/javascript/ config/webpack/ streaming/", "test:lint": "eslint -c .eslintrc.yml --ext=js app/javascript/ config/webpack/ streaming/",
"test:jest": "cross-env NODE_ENV=test jest --coverage" "test:jest": "cross-env NODE_ENV=test jest --coverage"
}, },
@ -69,7 +69,6 @@
"mini-css-extract-plugin": "^0.4.1", "mini-css-extract-plugin": "^0.4.1",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"node-sass": "^4.9.2", "node-sass": "^4.9.2",
"npm-run-all": "^4.1.2",
"npmlog": "^4.1.2", "npmlog": "^4.1.2",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
"object-fit-images": "^3.2.3", "object-fit-images": "^3.2.3",

View file

@ -73,6 +73,30 @@ describe ApplicationController, type: :controller do
end end
end end
context 'with request older than a day' do
before do
get :success
fake_request = Request.new(:get, request.url)
fake_request.add_headers({ 'Date' => 2.days.ago.utc.httpdate })
fake_request.on_behalf_of(author)
request.headers.merge!(fake_request.headers)
end
describe '#signed_request?' do
it 'returns true' do
expect(controller.signed_request?).to be true
end
end
describe '#signed_request_account' do
it 'returns nil' do
expect(controller.signed_request_account).to be_nil
end
end
end
context 'with body' do context 'with body' do
before do before do
post :success, body: 'Hello world' post :success, body: 'Hello world'

View file

@ -48,9 +48,11 @@ describe Request do
end end
it 'executes a HTTP request when the first address is private' do it 'executes a HTTP request when the first address is private' do
allow(Addrinfo).to receive(:foreach).with('example.com', nil, nil, :SOCK_STREAM) resolver = double
.and_yield(Addrinfo.new(["AF_INET", 0, "example.com", "0.0.0.0"], :PF_INET, :SOCK_STREAM))
.and_yield(Addrinfo.new(["AF_INET6", 0, "example.com", "2001:4860:4860::8844"], :PF_INET6, :SOCK_STREAM)) allow(resolver).to receive(:getaddresses).with('example.com').and_return(%w(0.0.0.0 2001:4860:4860::8844))
allow(resolver).to receive(:timeouts=).and_return(nil)
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
expect { |block| subject.perform &block }.to yield_control expect { |block| subject.perform &block }.to yield_control
expect(a_request(:get, 'http://example.com')).to have_been_made.once expect(a_request(:get, 'http://example.com')).to have_been_made.once
@ -81,10 +83,13 @@ describe Request do
end end
it 'raises Mastodon::ValidationError' do it 'raises Mastodon::ValidationError' do
allow(Addrinfo).to receive(:foreach).with('example.com', nil, nil, :SOCK_STREAM) resolver = double
.and_yield(Addrinfo.new(["AF_INET", 0, "example.com", "0.0.0.0"], :PF_INET, :SOCK_STREAM))
.and_yield(Addrinfo.new(["AF_INET6", 0, "example.com", "2001:db8::face"], :PF_INET6, :SOCK_STREAM)) allow(resolver).to receive(:getaddresses).with('example.com').and_return(%w(0.0.0.0 2001:db8::face))
expect{ subject.perform }.to raise_error Mastodon::ValidationError allow(resolver).to receive(:timeouts=).and_return(nil)
allow(Resolv::DNS).to receive(:open).and_yield(resolver)
expect { subject.perform }.to raise_error Mastodon::ValidationError
end end
end end
end end

124
yarn.lock
View file

@ -449,10 +449,6 @@ array-equal@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
array-filter@~0.0.0:
version "0.0.1"
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
array-find-index@^1.0.1: array-find-index@^1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
@ -472,14 +468,6 @@ array-includes@^3.0.3:
define-properties "^1.1.2" define-properties "^1.1.2"
es-abstract "^1.7.0" es-abstract "^1.7.0"
array-map@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
array-reduce@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
array-union@^1.0.1: array-union@^1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
@ -2081,7 +2069,7 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0:
shebang-command "^1.2.0" shebang-command "^1.2.0"
which "^1.2.9" which "^1.2.9"
cross-spawn@^6.0.4, cross-spawn@^6.0.5: cross-spawn@^6.0.5:
version "6.0.5" version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
dependencies: dependencies:
@ -2528,7 +2516,7 @@ double-ended-queue@^2.1.0-0:
version "2.1.0-0" version "2.1.0-0"
resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
duplexer@^0.1.1, duplexer@~0.1.1: duplexer@^0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
@ -2663,7 +2651,7 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies: dependencies:
is-arrayish "^0.2.1" is-arrayish "^0.2.1"
es-abstract@^1.4.3, es-abstract@^1.6.1, es-abstract@^1.7.0: es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.12.0" version "1.12.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
dependencies: dependencies:
@ -2882,18 +2870,6 @@ etag@~1.8.1:
version "1.8.1" version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
event-stream@~3.3.0:
version "3.3.4"
resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
dependencies:
duplexer "~0.1.1"
from "~0"
map-stream "~0.1.0"
pause-stream "0.0.11"
split "0.3"
stream-combiner "~0.0.4"
through "~2.3.1"
eventemitter3@^3.0.0: eventemitter3@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163"
@ -3299,10 +3275,6 @@ from2@^2.1.0:
inherits "^2.0.1" inherits "^2.0.1"
readable-stream "^2.0.0" readable-stream "^2.0.0"
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
fs-extra@^0.30.0: fs-extra@^0.30.0:
version "0.30.0" version "0.30.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
@ -3356,7 +3328,7 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2:
mkdirp ">=0.5 0" mkdirp ">=0.5 0"
rimraf "2" rimraf "2"
function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: function-bind@^1.1.0, 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"
@ -4781,15 +4753,6 @@ load-json-file@^2.0.0:
pify "^2.0.0" pify "^2.0.0"
strip-bom "^3.0.0" strip-bom "^3.0.0"
load-json-file@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
dependencies:
graceful-fs "^4.1.2"
parse-json "^4.0.0"
pify "^3.0.0"
strip-bom "^3.0.0"
loader-runner@^2.3.0: loader-runner@^2.3.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
@ -4956,10 +4919,6 @@ map-obj@^1.0.0, map-obj@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
map-stream@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
map-visit@^1.0.0: map-visit@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
@ -5006,10 +4965,6 @@ memory-fs@^0.4.0, memory-fs@~0.4.1:
errno "^0.1.3" errno "^0.1.3"
readable-stream "^2.0.1" readable-stream "^2.0.1"
memorystream@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2"
meow@^3.3.0, meow@^3.7.0: meow@^3.3.0, meow@^3.7.0:
version "3.7.0" version "3.7.0"
resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
@ -5475,20 +5430,6 @@ npm-packlist@^1.1.6:
ignore-walk "^3.0.1" ignore-walk "^3.0.1"
npm-bundled "^1.0.1" npm-bundled "^1.0.1"
npm-run-all@^4.1.2:
version "4.1.3"
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.3.tgz#49f15b55a66bb4101664ce270cb18e7103f8f185"
dependencies:
ansi-styles "^3.2.0"
chalk "^2.1.0"
cross-spawn "^6.0.4"
memorystream "^0.3.1"
minimatch "^3.0.4"
ps-tree "^1.1.0"
read-pkg "^3.0.0"
shell-quote "^1.6.1"
string.prototype.padend "^3.0.0"
npm-run-path@^2.0.0: npm-run-path@^2.0.0:
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@ -5877,18 +5818,6 @@ path-type@^2.0.0:
dependencies: dependencies:
pify "^2.0.0" pify "^2.0.0"
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
dependencies:
pify "^3.0.0"
pause-stream@0.0.11:
version "0.0.11"
resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
dependencies:
through "~2.3"
pbkdf2@^3.0.3: pbkdf2@^3.0.3:
version "3.0.16" version "3.0.16"
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c"
@ -6636,12 +6565,6 @@ prr@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
ps-tree@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014"
dependencies:
event-stream "~3.3.0"
pseudomap@^1.0.2: pseudomap@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
@ -7042,14 +6965,6 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2" normalize-package-data "^2.3.2"
path-type "^2.0.0" path-type "^2.0.0"
read-pkg@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
dependencies:
load-json-file "^4.0.0"
normalize-package-data "^2.3.2"
path-type "^3.0.0"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.6: "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.6:
version "2.3.6" version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
@ -7603,15 +7518,6 @@ shebang-regex@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
shell-quote@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
dependencies:
array-filter "~0.0.0"
array-map "~0.0.0"
array-reduce "~0.0.0"
jsonify "~0.0.0"
shellwords@^0.1.1: shellwords@^0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
@ -7782,12 +7688,6 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies: dependencies:
extend-shallow "^3.0.0" extend-shallow "^3.0.0"
split@0.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
dependencies:
through "2"
split@^1.0.0: split@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
@ -7847,12 +7747,6 @@ stream-browserify@^2.0.1:
inherits "~2.0.1" inherits "~2.0.1"
readable-stream "^2.0.2" readable-stream "^2.0.2"
stream-combiner@~0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
dependencies:
duplexer "~0.1.1"
stream-each@^1.1.0: stream-each@^1.1.0:
version "1.2.2" version "1.2.2"
resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd"
@ -7900,14 +7794,6 @@ string-width@^1.0.1, string-width@^1.0.2:
is-fullwidth-code-point "^2.0.0" is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0" strip-ansi "^4.0.0"
string.prototype.padend@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0"
dependencies:
define-properties "^1.1.2"
es-abstract "^1.4.3"
function-bind "^1.0.2"
string_decoder@^1.0.0, string_decoder@~1.1.1: string_decoder@^1.0.0, string_decoder@~1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
@ -8098,7 +7984,7 @@ through2@^2.0.0:
readable-stream "^2.1.5" readable-stream "^2.1.5"
xtend "~4.0.1" xtend "~4.0.1"
through@2, through@^2.3.6, through@~2.3, through@~2.3.1: through@2, through@^2.3.6:
version "2.3.8" version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"