diff --git a/.gitignore b/.gitignore index 159d579c0..a4057eb6e 100644 --- a/.gitignore +++ b/.gitignore @@ -62,5 +62,3 @@ ubuntu-xenial-16.04-cloudimg-console.log # Ignore Docker option files docker-compose.override.yml - -public.tar.gz diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ae9fc82c..33663c2ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,32 @@ Changelog All notable changes to this project will be documented in this file. +## [v3.1.2] - 2020-02-27 +### Added + +- Add `--reset-password` option to `tootctl accounts modify` ([ThibG](https://github.com/tootsuite/mastodon/pull/13126)) +- Add source-mapped stacktrace to error message in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13082)) + +### Fixed + +- Fix dismissing an announcement twice raising an obscure error ([ThibG](https://github.com/tootsuite/mastodon/pull/13124)) +- Fix misleading error when attempting to re-send a pending follow request ([ThibG](https://github.com/tootsuite/mastodon/pull/13133)) +- Fix backups failing when files are missing from media attachments ([ThibG](https://github.com/tootsuite/mastodon/pull/13146)) +- Fix duplicate accounts being created when fetching an account for its key only ([ThibG](https://github.com/tootsuite/mastodon/pull/13147)) +- Fix `/web` redirecting to `/web/web` in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13128)) +- Fix previously OStatus-based accounts not being detected as ActivityPub ([ThibG](https://github.com/tootsuite/mastodon/pull/13129)) +- Fix account JSON/RSS not being cacheable due to wrong mime type comparison ([ThibG](https://github.com/tootsuite/mastodon/pull/13116)) +- Fix old browsers crashing because of missing `finally` polyfill in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13115)) +- Fix account's bio not being shown if there are no proofs/fields in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/13075)) +- Fix sign-ups without checked user agreement being accepted through the web form ([ThibG](https://github.com/tootsuite/mastodon/pull/13088)) +- Fix non-x64 architectures not being able to build Docker image because of hardcoded Node.js architecture ([SaraSmiseth](https://github.com/tootsuite/mastodon/pull/13081)) +- Fix invite request input not being shown on sign-up error if left empty ([ThibG](https://github.com/tootsuite/mastodon/pull/13089)) +- Fix some migration hints mentioning GitLab instead of Mastodon ([saper](https://github.com/tootsuite/mastodon/pull/13084)) + +### Security + +- Fix leak of arbitrary statuses through unfavourite action in REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/13161)) + ## [3.1.1] - 2020-02-10 ### Fixed diff --git a/Dockerfile b/Dockerfile index cc75bd6be..a22efe672 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,14 +5,25 @@ SHELL ["bash", "-c"] # Install Node v12 (LTS) ENV NODE_VER="12.14.0" -RUN echo "Etc/UTC" > /etc/localtime && \ +RUN ARCH= && \ + dpkgArch="$(dpkg --print-architecture)" && \ + case "${dpkgArch##*-}" in \ + amd64) ARCH='x64';; \ + ppc64el) ARCH='ppc64le';; \ + s390x) ARCH='s390x';; \ + arm64) ARCH='arm64';; \ + armhf) ARCH='armv7l';; \ + i386) ARCH='x86';; \ + *) echo "unsupported architecture"; exit 1 ;; \ + esac && \ + echo "Etc/UTC" > /etc/localtime && \ apt update && \ apt -y install wget python && \ cd ~ && \ - wget https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-linux-x64.tar.gz && \ - tar xf node-v$NODE_VER-linux-x64.tar.gz && \ - rm node-v$NODE_VER-linux-x64.tar.gz && \ - mv node-v$NODE_VER-linux-x64 /opt/node + wget https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-linux-$ARCH.tar.gz && \ + tar xf node-v$NODE_VER-linux-$ARCH.tar.gz && \ + rm node-v$NODE_VER-linux-$ARCH.tar.gz && \ + mv node-v$NODE_VER-linux-$ARCH /opt/node # Install jemalloc ENV JE_VER="5.2.1" @@ -58,7 +69,9 @@ RUN npm install -g yarn && \ COPY Gemfile* package.json yarn.lock /opt/mastodon/ RUN cd /opt/mastodon && \ - bundle install -j$(nproc) --deployment --without development test && \ + bundle config set deployment 'true' && \ + bundle config set without 'development test' && \ + bundle install -j$(nproc) && \ yarn install --pure-lockfile FROM ubuntu:18.04 diff --git a/Gemfile b/Gemfile index 9329f3ab0..07959fd3d 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ gem 'puma', '~> 4.3' gem 'rails', '~> 5.2.4' gem 'sprockets', '~> 3.7.2' gem 'thor', '~> 0.20' -gem 'rack', '~> 2.1.2' +gem 'rack', '~> 2.2.2' gem 'thwait', '~> 0.1.0' gem 'e2mmap', '~> 0.1.0' @@ -101,14 +101,14 @@ gem 'webpacker', '~> 4.2' gem 'webpush' gem 'json-ld' -gem 'json-ld-preloaded', '~> 3.0' +gem 'json-ld-preloaded', '~> 3.1' gem 'rdf-normalize', '~> 0.4' group :development, :test do gem 'fabrication', '~> 2.21' gem 'fuubar', '~> 2.5' gem 'i18n-tasks', '~> 0.9', require: false - gem 'pry-byebug', '~> 3.7' + gem 'pry-byebug', '~> 3.8' gem 'pry-rails', '~> 0.3' gem 'rspec-rails', '~> 3.9' end @@ -118,13 +118,13 @@ group :production, :test do end group :test do - gem 'capybara', '~> 3.30' + gem 'capybara', '~> 3.31' gem 'climate_control', '~> 0.2' gem 'faker', '~> 2.10' gem 'microformats', '~> 4.2' gem 'rails-controller-testing', '~> 1.0' gem 'rspec-sidekiq', '~> 3.0' - gem 'simplecov', '~> 0.17', require: false + gem 'simplecov', '~> 0.18', require: false gem 'webmock', '~> 3.8' gem 'parallel_tests', '~> 2.30' end @@ -136,7 +136,7 @@ group :development do gem 'binding_of_caller', '~> 0.7' gem 'bullet', '~> 6.1' gem 'letter_opener', '~> 1.7' - gem 'letter_opener_web', '~> 1.3' + gem 'letter_opener_web', '~> 1.4' gem 'memory_profiler' gem 'rubocop', '~> 0.79', require: false gem 'rubocop-rails', '~> 2.4', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 70e7238b2..095137e2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -127,7 +127,7 @@ GEM bundler-audit (0.6.1) bundler (>= 1.2.0, < 3) thor (~> 0.18) - byebug (11.0.0) + byebug (11.1.1) capistrano (3.11.2) airbrussh (>= 1.0.0) i18n @@ -144,7 +144,7 @@ GEM sshkit (~> 1.3) capistrano-yarn (2.0.2) capistrano (~> 3.0) - capybara (3.30.0) + capybara (3.31.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) @@ -311,10 +311,9 @@ GEM multi_json (~> 1.14) rack (~> 2.0) rdf (~> 3.1) - json-ld-preloaded (3.0.6) - json-ld (~> 3.0) - multi_json (~> 1.12) - rdf (~> 3.0) + json-ld-preloaded (3.1.0) + json-ld (~> 3.1) + rdf (~> 3.1) jsonapi-renderer (0.2.2) jwt (2.1.0) kaminari (1.1.1) @@ -333,7 +332,7 @@ GEM addressable (~> 2.3) letter_opener (1.7.0) launchy (~> 2.2) - letter_opener_web (1.3.4) + letter_opener_web (1.4.0) actionmailer (>= 3.2) letter_opener (~> 1.0) railties (>= 3.2) @@ -375,7 +374,7 @@ GEM net-ssh (>= 2.6.5, < 6.0.0) net-ssh (5.2.0) nio4r (2.5.2) - nokogiri (1.10.7) + nokogiri (1.10.8) mini_portile2 (~> 2.4.0) nokogumbo (2.0.1) nokogiri (~> 1.8, >= 1.8.4) @@ -418,7 +417,7 @@ GEM pg (1.2.2) pghero (2.4.1) activerecord (>= 5) - pkg-config (1.4.0) + pkg-config (1.4.1) premailer (1.11.1) addressable css_parser (>= 1.6.0) @@ -430,7 +429,7 @@ GEM pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) - pry-byebug (3.7.0) + pry-byebug (3.8.0) byebug (~> 11.0) pry (~> 0.10) pry-rails (0.3.9) @@ -441,7 +440,7 @@ GEM pundit (2.1.0) activesupport (>= 3.0.0) raabro (1.1.6) - rack (2.1.2) + rack (2.2.2) rack-attack (6.2.2) rack (>= 1.0, < 3) rack-cors (1.1.1) @@ -550,7 +549,7 @@ GEM rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 1.7) - rubocop-rails (2.4.1) + rubocop-rails (2.4.2) rack (>= 1.1) rubocop (>= 0.72.0) ruby-progressbar (1.10.1) @@ -584,11 +583,10 @@ GEM simple_form (5.0.1) actionpack (>= 5.0) activemodel (>= 5.0) - simplecov (0.17.1) + simplecov (0.18.2) docile (~> 1.1) - json (>= 1.8, < 3) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.2) + simplecov-html (~> 0.11) + simplecov-html (0.12.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -680,7 +678,7 @@ DEPENDENCIES capistrano-rails (~> 1.4) capistrano-rbenv (~> 2.1) capistrano-yarn (~> 2.0) - capybara (~> 3.30) + capybara (~> 3.31) charlock_holmes (~> 0.7.7) chewy (~> 5.1) cld3 (~> 3.2.6) @@ -714,10 +712,10 @@ DEPENDENCIES idn-ruby iso-639 json-ld - json-ld-preloaded (~> 3.0) + json-ld-preloaded (~> 3.1) kaminari (~> 1.1) letter_opener (~> 1.7) - letter_opener_web (~> 1.3) + letter_opener_web (~> 1.4) link_header (~> 0.0) lograge (~> 0.11) makara (~> 0.4) @@ -745,11 +743,11 @@ DEPENDENCIES posix-spawn! premailer-rails private_address_check (~> 0.5) - pry-byebug (~> 3.7) + pry-byebug (~> 3.8) pry-rails (~> 0.3) puma (~> 4.3) pundit (~> 2.1) - rack (~> 2.1.2) + rack (~> 2.2.2) rack-attack (~> 6.2) rack-cors (~> 1.1) rails (~> 5.2.4) @@ -773,7 +771,7 @@ DEPENDENCIES sidekiq-unique-jobs (~> 6.0) simple-navigation (~> 4.1) simple_form (~> 5.0) - simplecov (~> 0.17) + simplecov (~> 0.18) sprockets (~> 3.7.2) sprockets-rails (~> 3.2) stackprof diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 0a8015a56..124393d62 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -9,7 +9,7 @@ class AccountsController < ApplicationController before_action :set_cache_headers before_action :set_body_classes - skip_around_action :set_locale, if: -> { [:json, :rss].include?(request.format) } + skip_around_action :set_locale, if: -> { [:json, :rss].include?(request.format&.to_sym) } skip_before_action :require_functional! def show diff --git a/app/controllers/api/v1/announcements_controller.rb b/app/controllers/api/v1/announcements_controller.rb index 1e692ff75..ee79fc19f 100644 --- a/app/controllers/api/v1/announcements_controller.rb +++ b/app/controllers/api/v1/announcements_controller.rb @@ -11,7 +11,7 @@ class Api::V1::AnnouncementsController < Api::BaseController end def dismiss - AnnouncementMute.create!(account: current_account, announcement: @announcement) + AnnouncementMute.find_or_create_by!(account: current_account, announcement: @announcement) render_empty end diff --git a/app/controllers/api/v1/statuses/bookmarks_controller.rb b/app/controllers/api/v1/statuses/bookmarks_controller.rb index bb9729cf5..a7f1eed00 100644 --- a/app/controllers/api/v1/statuses/bookmarks_controller.rb +++ b/app/controllers/api/v1/statuses/bookmarks_controller.rb @@ -5,35 +5,28 @@ class Api::V1::Statuses::BookmarksController < Api::BaseController before_action -> { doorkeeper_authorize! :write, :'write:bookmarks' } before_action :require_user! + before_action :set_status respond_to :json def create - @status = bookmarked_status + current_account.bookmarks.find_or_create_by!(account: current_account, status: @status) render json: @status, serializer: REST::StatusSerializer end def destroy - @status = requested_status - @bookmarks_map = { @status.id => false } + bookmark = current_account.bookmarks.find_by(status: @status) + bookmark&.destroy! - bookmark = Bookmark.find_by!(account: current_user.account, status: @status) - bookmark.destroy! - - render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_user&.account_id, bookmarks_map: @bookmarks_map) + render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, bookmarks_map: { @status.id => false }) end private - def bookmarked_status - authorize_with current_user.account, requested_status, :show? - - bookmark = Bookmark.find_or_create_by!(account: current_user.account, status: requested_status) - - bookmark.status.reload - end - - def requested_status - Status.find(params[:status_id]) + def set_status + @status = Status.find(params[:status_id]) + authorize @status, :show? + rescue Mastodon::NotPermittedError + not_found end end diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb index 99eff360e..05f4acc33 100644 --- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb @@ -69,8 +69,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController @status = Status.find(params[:status_id]) authorize @status, :show? rescue Mastodon::NotPermittedError - # Reraise in order to get a 404 instead of a 403 error code - raise ActiveRecord::RecordNotFound + not_found end def pagination_params(core_params) diff --git a/app/controllers/api/v1/statuses/favourites_controller.rb b/app/controllers/api/v1/statuses/favourites_controller.rb index cceee9060..f18ace996 100644 --- a/app/controllers/api/v1/statuses/favourites_controller.rb +++ b/app/controllers/api/v1/statuses/favourites_controller.rb @@ -5,34 +5,26 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController before_action -> { doorkeeper_authorize! :write, :'write:favourites' } before_action :require_user! + before_action :set_status respond_to :json def create - @status = favourited_status + FavouriteService.new.call(current_account, @status) render json: @status, serializer: REST::StatusSerializer end def destroy - @status = requested_status - @favourites_map = { @status.id => false } - - UnfavouriteWorker.perform_async(current_user.account_id, @status.id) - - render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_user&.account_id, favourites_map: @favourites_map) + UnfavouriteWorker.perform_async(current_account.id, @status.id) + render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, favourites_map: { @status.id => false }) end private - def favourited_status - service_result.status.reload - end - - def service_result - FavouriteService.new.call(current_user.account, requested_status) - end - - def requested_status - Status.find(params[:status_id]) + def set_status + @status = Status.find(params[:status_id]) + authorize @status, :show? + rescue Mastodon::NotPermittedError + not_found end end diff --git a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb index cc285ad23..fa60e7d84 100644 --- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb @@ -66,8 +66,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController @status = Status.find(params[:status_id]) authorize @status, :show? rescue Mastodon::NotPermittedError - # Reraise in order to get a 404 instead of a 403 error code - raise ActiveRecord::RecordNotFound + not_found end def pagination_params(core_params) diff --git a/app/controllers/api/v1/statuses/reblogs_controller.rb b/app/controllers/api/v1/statuses/reblogs_controller.rb index 42381a37f..67106ccbe 100644 --- a/app/controllers/api/v1/statuses/reblogs_controller.rb +++ b/app/controllers/api/v1/statuses/reblogs_controller.rb @@ -5,33 +5,34 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController before_action -> { doorkeeper_authorize! :write, :'write:statuses' } before_action :require_user! + before_action :set_reblog respond_to :json def create - @status = ReblogService.new.call(current_user.account, status_for_reblog, reblog_params) + @status = ReblogService.new.call(current_account, @reblog, reblog_params) render json: @status, serializer: REST::StatusSerializer end def destroy - @status = status_for_destroy.reblog - @reblogs_map = { @status.id => false } + @status = current_account.statuses.find_by(reblog_of_id: @reblog.id) - authorize status_for_destroy, :unreblog? - status_for_destroy.discard - RemovalWorker.perform_async(status_for_destroy.id) + if @status + authorize @status, :unreblog? + @status.discard + RemovalWorker.perform_async(@status.id) + end - render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_user&.account_id, reblogs_map: @reblogs_map) + render json: @reblog, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, reblogs_map: { @reblog.id => false }) end private - def status_for_reblog - Status.find params[:status_id] - end - - def status_for_destroy - @status_for_destroy ||= current_user.account.statuses.where(reblog_of_id: params[:status_id]).first! + def set_reblog + @reblog = Status.find(params[:status_id]) + authorize @reblog, :show? + rescue Mastodon::NotPermittedError + not_found end def reblog_params diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 67495c221..2be864de8 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -41,7 +41,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController resource.locale = I18n.locale resource.invite_code = params[:invite_code] if resource.invite_code.blank? - resource.agreement = true resource.current_sign_in_ip = request.remote_ip resource.current_sign_in_ip = request.remote_ip if resource.current_sign_in_ip.nil? @@ -50,7 +49,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController def configure_sign_up_params devise_parameter_sanitizer.permit(:sign_up) do |u| - u.permit({ account_attributes: [:username], invite_request_attributes: [:text] }, :email, :password, :password_confirmation, :invite_code) + u.permit({ account_attributes: [:username], invite_request_attributes: [:text] }, :email, :password, :password_confirmation, :invite_code, :agreement) end end diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index ebf701107..55b7376b9 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -57,8 +57,8 @@ class Settings::PreferencesController < Settings::BaseController :setting_use_blurhash, :setting_use_pending_items, :setting_trends, - :setting_crop_images, :setting_strip_formatting, + :setting_crop_images, notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account trending_tag), interactions: %i(must_be_follower must_be_following must_be_following_dm) ) diff --git a/app/javascript/mastodon/base_polyfills.js b/app/javascript/mastodon/base_polyfills.js index 997813a04..12096d902 100644 --- a/app/javascript/mastodon/base_polyfills.js +++ b/app/javascript/mastodon/base_polyfills.js @@ -6,6 +6,7 @@ import assign from 'object-assign'; import values from 'object.values'; import isNaN from 'is-nan'; import { decode as decodeBase64 } from './utils/base64'; +import promiseFinally from 'promise.prototype.finally'; if (!Array.prototype.includes) { includes.shim(); @@ -23,6 +24,8 @@ if (!Number.isNaN) { Number.isNaN = isNaN; } +promiseFinally.shim(); + if (!HTMLCanvasElement.prototype.toBlob) { const BASE64_MARKER = ';base64,'; diff --git a/app/javascript/mastodon/components/error_boundary.js b/app/javascript/mastodon/components/error_boundary.js index 4e1c882e2..ca3012276 100644 --- a/app/javascript/mastodon/components/error_boundary.js +++ b/app/javascript/mastodon/components/error_boundary.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; import { version, source_url } from 'mastodon/initial_state'; +import StackTrace from 'stacktrace-js'; export default class ErrorBoundary extends React.PureComponent { @@ -11,24 +12,42 @@ export default class ErrorBoundary extends React.PureComponent { state = { hasError: false, + errorMessage: undefined, stackTrace: undefined, + mappedStackTrace: undefined, componentStack: undefined, }; componentDidCatch (error, info) { this.setState({ hasError: true, + errorMessage: error.toString(), stackTrace: error.stack, componentStack: info && info.componentStack, - copied: false, + mappedStackTrace: undefined, + }); + + StackTrace.fromError(error).then((stackframes) => { + this.setState({ + mappedStackTrace: stackframes.map((sf) => sf.toString()).join('\n'), + }); + }).catch(() => { + this.setState({ + mappedStackTrace: undefined, + }); }); } handleCopyStackTrace = () => { - const { stackTrace } = this.state; + const { errorMessage, stackTrace, mappedStackTrace } = this.state; const textarea = document.createElement('textarea'); - textarea.textContent = stackTrace; + let contents = [errorMessage, stackTrace]; + if (mappedStackTrace) { + contents.push(mappedStackTrace); + } + + textarea.textContent = contents.join('\n\n\n'); textarea.style.position = 'fixed'; document.body.appendChild(textarea); diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index 58f53e40c..dc86b9462 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -24,7 +24,7 @@ export const useBlurhash = getMeta('use_blurhash'); export const usePendingItems = getMeta('use_pending_items'); export const showTrends = getMeta('trends'); export const title = getMeta('title'); -export const cropImages = getMeta('crop_images'); export const stripFormatting = getMeta('strip_formatting'); +export const cropImages = getMeta('crop_images'); export default initialState; diff --git a/app/javascript/mastodon/load_polyfills.js b/app/javascript/mastodon/load_polyfills.js index 8cb81c1a6..73eedc9dc 100644 --- a/app/javascript/mastodon/load_polyfills.js +++ b/app/javascript/mastodon/load_polyfills.js @@ -18,7 +18,8 @@ function loadPolyfills() { Number.isNaN && Object.assign && Object.values && - window.Symbol + window.Symbol && + Promise.prototype.finally ); // Latest version of Firefox and Safari do not have IntersectionObserver. diff --git a/app/javascript/mastodon/locales/dog.json b/app/javascript/mastodon/locales/dog.json index 4fefc3076..19120d1a9 100644 --- a/app/javascript/mastodon/locales/dog.json +++ b/app/javascript/mastodon/locales/dog.json @@ -1,7 +1,6 @@ { "account.add_or_remove_from_list": "Add or Remove from lists", "account.badges.bot": "Bot", - "account.badges.group": "Group", "account.block": "Block @{name}", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", @@ -170,7 +169,7 @@ "getting_started.heading": "Getting started", "getting_started.invite": "Invite dogs", "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", - "getting_started.security": "Security", + "getting_started.security": "Account settings", "getting_started.terms": "Terms of service", "hashtag.column_header.tag_mode.all": "and {additional}", "hashtag.column_header.tag_mode.any": "or {additional}", @@ -184,6 +183,8 @@ "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Show awoos", "home.column_settings.show_replies": "Show barks", + "home.hide_announcements": "Hide announcements", + "home.show_announcements": "Show announcements", "intervals.full.days": "{number, plural, one {# day} other {# days}}", "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", @@ -290,12 +291,12 @@ "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", "notifications.column_settings.alert": "Desktop notifications", "notifications.column_settings.favourite": "Boops:", - "notifications.column_settings.follow": "New pack members:", - "notifications.column_settings.mention": "Barks:", + "notifications.column_settings.filter_bar.advanced": "Display all categories", + "notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.follow": "New pack members:", "notifications.column_settings.follow_request": "New pack requests:", - "notifications.column_settings.mention": "Barks:", + "notifications.column_settings.mention": "Mentions:", "notifications.column_settings.poll": "Poll results:", "notifications.column_settings.push": "Push notifications", "notifications.column_settings.reblog": "Awoos:", @@ -333,6 +334,7 @@ "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", + "relative_time.today": "today", "reply_indicator.cancel": "Cancel", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", diff --git a/app/javascript/mastodon/locales/lion.json b/app/javascript/mastodon/locales/lion.json index b708346cb..9ac559185 100644 --- a/app/javascript/mastodon/locales/lion.json +++ b/app/javascript/mastodon/locales/lion.json @@ -170,7 +170,7 @@ "getting_started.heading": "Getting started", "getting_started.invite": "Invite lions", "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", - "getting_started.security": "Security", + "getting_started.security": "Account settings", "getting_started.terms": "Terms of service", "hashtag.column_header.tag_mode.all": "and {additional}", "hashtag.column_header.tag_mode.any": "or {additional}", @@ -184,6 +184,8 @@ "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Show roars", "home.column_settings.show_replies": "Show meows", + "home.hide_announcements": "Hide announcements", + "home.show_announcements": "Show announcements", "intervals.full.days": "{number, plural, one {# day} other {# days}}", "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", @@ -205,7 +207,7 @@ "introduction.welcome.headline": "First steps", "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", "keyboard_shortcuts.back": "to navigate back", - "keyboard_shortcuts.blocked": "to open blocked dogs list", + "keyboard_shortcuts.blocked": "to open blocked lions list", "keyboard_shortcuts.boost": "to boost", "keyboard_shortcuts.column": "to focus a status in one of the columns", "keyboard_shortcuts.compose": "to focus the compose textarea", @@ -294,7 +296,7 @@ "notifications.column_settings.mention": "Meows:", "notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.follow": "New Pride Members:", - "notifications.column_settings.mention": "Meows:", + "notifications.column_settings.follow_request": "New pride requests:", "notifications.column_settings.mention": "Meows:", "notifications.column_settings.poll": "Poll results:", "notifications.column_settings.push": "Push notifications", @@ -333,6 +335,7 @@ "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", + "relative_time.today": "today", "reply_indicator.cancel": "Cancel", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", @@ -420,7 +423,7 @@ "upload_form.video_description": "Describe for people with hearing loss or visual impairment", "upload_modal.analyzing_picture": "Analyzing picture…", "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", + "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy lion", "upload_modal.detect_text": "Detect text from picture", "upload_modal.edit_media": "Edit media", "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", diff --git a/app/javascript/mastodon/locales/squeak.json b/app/javascript/mastodon/locales/squeak.json index 8f180999e..f9e3a0a86 100644 --- a/app/javascript/mastodon/locales/squeak.json +++ b/app/javascript/mastodon/locales/squeak.json @@ -170,7 +170,7 @@ "getting_started.heading": "Getting started", "getting_started.invite": "Invite people", "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", - "getting_started.security": "Security", + "getting_started.security": "Account settings", "getting_started.terms": "Terms of service", "hashtag.column_header.tag_mode.all": "and {additional}", "hashtag.column_header.tag_mode.any": "or {additional}", @@ -184,6 +184,8 @@ "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Show pumps", "home.column_settings.show_replies": "Show replies", + "home.hide_announcements": "Hide announcements", + "home.show_announcements": "Show announcements", "intervals.full.days": "{number, plural, one {# day} other {# days}}", "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", @@ -333,6 +335,7 @@ "relative_time.just_now": "now", "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", + "relative_time.today": "today", "reply_indicator.cancel": "Cancel", "report.forward": "Forward to {target}", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", diff --git a/app/javascript/mastodon/main.js b/app/javascript/mastodon/main.js index 5d73caa10..da4884fd3 100644 --- a/app/javascript/mastodon/main.js +++ b/app/javascript/mastodon/main.js @@ -12,7 +12,7 @@ function main() { if (window.history && history.replaceState) { const { pathname, search, hash } = window.location; const path = pathname + search + hash; - if (!(/^\/web[$/]/).test(path)) { + if (!(/^\/web($|\/)/).test(path)) { history.replaceState(null, document.title, `/web${path}`); } } diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 24518f7eb..9c2a6364a 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -37,8 +37,8 @@ class UserSettingsDecorator user.settings['use_blurhash'] = use_blurhash_preference if change?('setting_use_blurhash') user.settings['use_pending_items'] = use_pending_items_preference if change?('setting_use_pending_items') user.settings['trends'] = trends_preference if change?('setting_trends') - user.settings['crop_images'] = crop_images_preference if change?('setting_crop_images') user.settings['strip_formatting'] = strip_formatting_preference if change?('setting_strip_formatting') + user.settings['crop_images'] = crop_images_preference if change?('setting_crop_images') end def merged_notification_emails diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 9c649d35c..1c6ce6255 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -20,9 +20,10 @@ class ActivityPub::ProcessAccountService < BaseService RedisLock.acquire(lock_options) do |lock| if lock.acquired? - @account = Account.find_remote(@username, @domain) - @old_public_key = @account&.public_key - @old_protocol = @account&.protocol + @account = Account.remote.find_by(uri: @uri) if @options[:only_key] + @account ||= Account.find_remote(@username, @domain) + @old_public_key = @account&.public_key + @old_protocol = @account&.protocol create_account if @account.nil? update_account diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb index d1090dff1..896699324 100644 --- a/app/services/backup_service.rb +++ b/app/services/backup_service.rb @@ -66,6 +66,8 @@ class BackupService < BaseService def dump_media_attachments!(tar) MediaAttachment.attached.where(account: account).reorder(nil).find_in_batches do |media_attachments| media_attachments.each do |m| + next unless m.file&.path + download_to_tar(tar, m.file, m.file.path) end diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb index dc47804c0..4d19002c4 100644 --- a/app/services/follow_service.rb +++ b/app/services/follow_service.rb @@ -18,14 +18,13 @@ class FollowService < BaseService if source_account.following?(target_account) # We're already following this account, but we'll call follow! again to # make sure the reblogs status is set correctly. - source_account.follow!(target_account, reblogs: reblogs) - return + return source_account.follow!(target_account, reblogs: reblogs) elsif source_account.requested?(target_account) # This isn't managed by a method in AccountInteractions, so we modify it # ourselves if necessary. req = source_account.follow_requests.find_by(target_account: target_account) req.update!(show_reblogs: reblogs) - return + return req end ActivityTracker.increment('activity:interactions') diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb index 12e6544a0..1ad9ed407 100644 --- a/app/services/resolve_account_service.rb +++ b/app/services/resolve_account_service.rb @@ -99,7 +99,7 @@ class ResolveAccountService < BaseService if lock.acquired? @account = Account.find_remote(@username, @domain) - next if (@account.present? && !@account.activitypub?) || actor_json.nil? + next if actor_json.nil? @account = ActivityPub::ProcessAccountService.new.call(@username, @domain, actor_json) else diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index a83f77134..a30b78db2 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -27,9 +27,9 @@ = fa_icon 'check' = Formatter.instance.format_field(account, field.value, custom_emojify: true) - - if account.note.present? - %div - .account__header__content.emojify= Formatter.instance.simplified_format(account, custom_emojify: true) + - if account.note.present? + %div + .account__header__content.emojify= Formatter.instance.simplified_format(account, custom_emojify: true) .dashboard__counters{ style: 'margin-top: 10px' } %div diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index e807c8d86..bcd66fb8a 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -27,7 +27,7 @@ - if approved_registrations? && !@invite.present? .fields-group - = f.simple_fields_for :invite_request do |invite_request_fields| + = f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields| = invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: false = f.input :invite_code, as: :hidden diff --git a/app/views/authorize_interactions/show.html.haml b/app/views/authorize_interactions/show.html.haml index 7ca9b98c1..42c874134 100644 --- a/app/views/authorize_interactions/show.html.haml +++ b/app/views/authorize_interactions/show.html.haml @@ -10,6 +10,12 @@ %strong = t('authorize_follow.already_following') + = render 'post_follow_actions' + - elsif current_account.requested?(@resource) + .flash-message + %strong + = t('authorize_follow.already_requested') + = render 'post_follow_actions' - else = form_tag authorize_interaction_path, method: :post, class: 'simple_form' do diff --git a/config/application.rb b/config/application.rb index bd2eebadf..049f98a80 100644 --- a/config/application.rb +++ b/config/application.rb @@ -116,7 +116,7 @@ module Mastodon config.i18n.default_locale = ENV['DEFAULT_LOCALE']&.to_sym unless config.i18n.available_locales.include?(config.i18n.default_locale) - config.i18n.default_locale = :dog + config.i18n.default_locale = :en end # config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') diff --git a/config/locales/dog.yml b/config/locales/dog.yml index 4853d0764..4e883ee99 100644 --- a/config/locales/dog.yml +++ b/config/locales/dog.yml @@ -22,7 +22,7 @@ dog: get_apps: Try a mobile app hosted_on: Mastodon hosted on %{domain} instance_actor_flash: | - This dog is a virtual actor used to represent the server itself and not any individual dog. + This account is a virtual actor used to represent the server itself and not any individual dog. It is used for federation purposes and should not be blocked unless you want to block the whole instance, in which case you should use a domain block. learn_more: Learn more privacy_policy: Privacy policy @@ -78,6 +78,7 @@ dog: roles: admin: Admin bot: Bot + group: Group moderator: Mod unavailable: Profile unavailable unfollow: Leave pack @@ -469,7 +470,7 @@ dog: domain_blocks_rationale: title: Show rationale enable_bootstrap_timeline_accounts: - title: Enable default follows for new users + title: Enable default follows for new dogs hero: desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to server thumbnail title: Hero image @@ -527,8 +528,8 @@ dog: desc_html: Used for previews via OpenGraph and API. 1200x630px recommended title: Server thumbnail timeline_preview: - desc_html: Display link to public timeline on landing page and allow API access to the public timeline without authentication - title: Allow unauthenticated access to public timeline + desc_html: Display public timeline on landing page + title: Timeline preview title: Site settings trendable_by_default: desc_html: Affects hashtags that have not been previously disallowed @@ -660,6 +661,7 @@ dog: trouble_logging_in: Trouble logging in? authorize_follow: already_following: You already joined this pack + already_requested: You have already requested to join this pack error: Unfortunately, there was an error looking up the remote account follow: Join Pack follow_request: 'You have sent a pack request to:' @@ -743,6 +745,7 @@ dog: blocks: You block csv: CSV domain_blocks: Domain blocks + follows: You have joined lists: Lists mutes: You mute storage: Media storage @@ -1025,7 +1028,7 @@ dog: firefox_os: Firefox OS ios: iOS linux: Linux - mac: macOS + mac: Mac other: unknown platform windows: Windows windows_mobile: Windows Mobile @@ -1055,7 +1058,7 @@ dog: relationships: Packs and Pack Members two_factor_authentication: Two-factor Auth spam_check: - spam_detected: This is an automated report. Spam has been detected. + spam_detected_and_silenced: This is an automated report. Spam has been detected and the sender has been silenced automatically. If this is a mistake, please unsilence the account. statuses: attached: description: 'Attached: %{attached}' @@ -1087,6 +1090,7 @@ dog: other: "%{count} votes" vote: Vote show_more: Show more + show_thread: Show thread sign_in_to_participate: Sign in to participate in the conversation strip_formatting: all: All diff --git a/config/locales/en.yml b/config/locales/en.yml index 9d191a0fb..9cccae964 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -661,6 +661,7 @@ en: trouble_logging_in: Trouble logging in? authorize_follow: already_following: You are already following this account + already_requested: You have already sent a follow request to that account error: Unfortunately, there was an error looking up the remote account follow: Follow follow_request: 'You have sent a follow request to:' diff --git a/config/locales/lion.yml b/config/locales/lion.yml index 3f41197b7..c7a4100e8 100644 --- a/config/locales/lion.yml +++ b/config/locales/lion.yml @@ -78,6 +78,7 @@ lion: roles: admin: Admin bot: Bot + group: Group moderator: Mod unavailable: Profile unavailable unfollow: Leave Pride @@ -469,7 +470,7 @@ lion: domain_blocks_rationale: title: Show rationale enable_bootstrap_timeline_accounts: - title: Enable default follows for new users + title: Enable default follows for new lions hero: desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to server thumbnail title: Hero image @@ -660,6 +661,7 @@ lion: trouble_logging_in: Trouble logging in? authorize_follow: already_following: You already joined this pride + already_requested: You have already requested to join this pride error: Unfortunately, there was an error looking up the remote account follow: Join Pride follow_request: 'You have sent a pride request to:' @@ -743,6 +745,7 @@ lion: blocks: You block csv: CSV domain_blocks: Domain blocks + follows: You have joined lists: Lists mutes: You mute storage: Media storage @@ -943,7 +946,6 @@ lion: duration_too_long: is too far into the future duration_too_short: is too soon expired: The poll has already ended - invalid_choice: The chosen vote option does not exist over_character_limit: cannot be longer than %{max} characters each too_few_options: must have more than one item too_many_options: can't contain more than %{max} items @@ -1025,7 +1027,7 @@ lion: firefox_os: Firefox OS ios: iOS linux: Linux - mac: macOS + mac: Mac other: unknown platform windows: Windows windows_mobile: Windows Mobile @@ -1055,7 +1057,7 @@ lion: relationships: Prides and Pride Members two_factor_authentication: Two-factor Auth spam_check: - spam_detected: This is an automated report. Spam has been detected. + spam_detected_and_silenced: This is an automated report. Spam has been detected and the sender has been silenced automatically. If this is a mistake, please unsilence the account. statuses: attached: description: 'Attached: %{attached}' @@ -1087,6 +1089,7 @@ lion: other: "%{count} votes" vote: Vote show_more: Show more + show_thread: Show thread sign_in_to_participate: Sign in to participate in the conversation strip_formatting: all: All diff --git a/config/locales/simple_form.dog.yml b/config/locales/simple_form.dog.yml index 38e999c19..6d43dd033 100644 --- a/config/locales/simple_form.dog.yml +++ b/config/locales/simple_form.dog.yml @@ -93,7 +93,7 @@ dog: all_day: All-day event ends_at: End of event scheduled_at: Schedule publication - starts_at: Begin of event + starts_at: Start of event text: Announcement defaults: autofollow: Invite to follow your account @@ -125,7 +125,6 @@ dog: setting_aggregate_reblogs: Group awoos in timelines setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before awooing - setting_crop_images: Crop images in non-expanded toots to 16x9 setting_default_language: Posting language setting_default_privacy: Posting privacy setting_default_sensitive: Always mark media as sensitive @@ -168,7 +167,7 @@ dog: follow_request: Someone requested to join your pack mention: Someone barked at you pending_account: New account needs review - reblog: Someone awooed your toot + reblog: Someone boosted your status report: New report is submitted trending_tag: An unreviewed hashtag is trending tag: diff --git a/config/locales/simple_form.lion.yml b/config/locales/simple_form.lion.yml index 795b4af12..e33b0e120 100644 --- a/config/locales/simple_form.lion.yml +++ b/config/locales/simple_form.lion.yml @@ -93,7 +93,7 @@ lion: all_day: All-day event ends_at: End of event scheduled_at: Schedule publication - starts_at: Begin of event + starts_at: Start of event text: Announcement defaults: autofollow: Invite to follow your account @@ -125,7 +125,6 @@ lion: setting_aggregate_reblogs: Group roars in timelines setting_auto_play_gif: Auto-play animated GIFs setting_boost_modal: Show confirmation dialog before roaring - setting_crop_images: Crop images in non-expanded toots to 16x9 setting_default_language: Posting language setting_default_privacy: Posting privacy setting_default_sensitive: Always mark media as sensitive @@ -168,7 +167,7 @@ lion: follow_request: Someone requested to join your pride mention: Someone meowed at you pending_account: New account needs review - reblog: Someone roared your toot + reblog: Someone boosted your status report: New report is submitted trending_tag: An unreviewed hashtag is trending tag: diff --git a/config/locales/simple_form.squeak.yml b/config/locales/simple_form.squeak.yml index 378fe2759..5117839a7 100644 --- a/config/locales/simple_form.squeak.yml +++ b/config/locales/simple_form.squeak.yml @@ -84,7 +84,7 @@ squeak: text: Custom warning type: Action types: - disable: Disable + disable: Disable login none: Do nothing silence: Silence suspend: Suspend and irreversibly delete account data @@ -93,7 +93,7 @@ squeak: all_day: All-day event ends_at: End of event scheduled_at: Schedule publication - starts_at: Begin of event + starts_at: Start of event text: Announcement defaults: autofollow: Invite to follow your account diff --git a/config/locales/squeak.yml b/config/locales/squeak.yml index b2ac22e81..fe54ee8b2 100644 --- a/config/locales/squeak.yml +++ b/config/locales/squeak.yml @@ -661,6 +661,7 @@ squeak: trouble_logging_in: Trouble logging in? authorize_follow: already_following: You are already following this account + already_requested: You have already sent a follow request to that account error: Unfortunately, there was an error looking up the remote account follow: Follow follow_request: 'You have sent a follow request to:' @@ -1026,7 +1027,7 @@ squeak: firefox_os: Firefox OS ios: iOS linux: Linux - mac: macOS + mac: Mac other: unknown platform windows: Windows windows_mobile: Windows Mobile @@ -1056,7 +1057,7 @@ squeak: relationships: Follows and followers two_factor_authentication: Two-factor Auth spam_check: - spam_detected: This is an automated report. Spam has been detected. + spam_detected_and_silenced: This is an automated report. Spam has been detected and the sender has been silenced automatically. If this is a mistake, please unsilence the account. statuses: attached: description: 'Attached: %{attached}' @@ -1088,6 +1089,7 @@ squeak: other: "%{count} votes" vote: Vote show_more: Show more + show_thread: Show thread sign_in_to_participate: Sign in to participate in the conversation strip_formatting: all: All diff --git a/config/settings.yml b/config/settings.yml index 7a677870d..d06e5b992 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -29,7 +29,7 @@ defaults: &defaults show_application: true system_font_ui: false noindex: false - theme: 'pop-wider' + theme: 'mastodon' aggregate_reblogs: true advanced_layout: false use_blurhash: true diff --git a/lib/mastodon/accounts_cli.rb b/lib/mastodon/accounts_cli.rb index 6dbb75689..8c91c3013 100644 --- a/lib/mastodon/accounts_cli.rb +++ b/lib/mastodon/accounts_cli.rb @@ -120,6 +120,7 @@ module Mastodon option :disable, type: :boolean option :disable_2fa, type: :boolean option :approve, type: :boolean + option :reset_password, type: :boolean desc 'modify USERNAME', 'Modify a user' long_desc <<-LONG_DESC Modify a user account. @@ -138,6 +139,9 @@ module Mastodon With the --disable-2fa option, the two-factor authentication requirement for the user can be removed. + + With the --reset-password option, the user's password is replaced by + a randomly-generated one, printed in the output. LONG_DESC def modify(username) user = Account.find_local(username)&.user @@ -152,6 +156,8 @@ module Mastodon user.moderator = options[:role] == 'moderator' end + password = SecureRandom.hex if options[:reset_password] + user.password = password if options[:reset_password] user.email = options[:email] if options[:email] user.disabled = false if options[:enable] user.disabled = true if options[:disable] @@ -161,6 +167,7 @@ module Mastodon if user.save say('OK', :green) + say("New password: #{password}") if options[:reset_password] else user.errors.to_h.each do |key, error| say('Failure/Error: ', :red) diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb index 146eba8ec..bf2314ecb 100644 --- a/lib/mastodon/migration_helpers.rb +++ b/lib/mastodon/migration_helpers.rb @@ -886,16 +886,12 @@ module Mastodon Your database user is not allowed to create, drop, or execute triggers on the table #{table}. -If you are using PostgreSQL you can solve this by logging in to the GitLab +If you are using PostgreSQL you can solve this by logging in to the Mastodon database (#{dbname}) using a super user and running: ALTER USER #{user} WITH SUPERUSER -For MySQL you instead need to run: - - GRANT ALL PRIVILEGES ON *.* TO #{user}@'%' - -Both queries will grant the user super user permissions, ensuring you don't run +The query will grant the user super user permissions, ensuring you don't run into similar problems in the future (e.g. when new tables are created). EOF end diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 69353bde4..5aca0160c 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon end def patch - 1 + 2 end def flags diff --git a/package.json b/package.json index 6104ebce8..1a873615d 100644 --- a/package.json +++ b/package.json @@ -59,20 +59,20 @@ }, "private": true, "dependencies": { - "@babel/core": "^7.8.3", + "@babel/core": "^7.8.4", "@babel/plugin-proposal-class-properties": "^7.8.3", "@babel/plugin-proposal-decorators": "^7.8.3", - "@babel/plugin-transform-react-inline-elements": "^7.8.0", - "@babel/plugin-transform-runtime": "^7.7.6", + "@babel/plugin-transform-react-inline-elements": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.8.3", "@babel/preset-env": "^7.8.3", "@babel/preset-react": "^7.8.3", "@babel/runtime": "^7.8.3", - "@gamestdio/websocket": "^0.3.2", "@clusterws/cws": "^0.17.3", + "@gamestdio/websocket": "^0.3.2", "array-includes": "^3.1.1", "arrow-key-navigation": "^1.1.0", "autoprefixer": "^9.7.4", - "axios": "^0.19.1", + "axios": "^0.19.2", "babel-loader": "^8.0.6", "babel-plugin-lodash": "^3.3.4", "babel-plugin-preval": "^4.0.0", @@ -120,6 +120,7 @@ "pg": "^6.4.0", "postcss-loader": "^3.0.0", "postcss-object-fit-images": "^1.1.2", + "promise.prototype.finally": "^3.1.2", "prop-types": "^15.5.10", "punycode": "^2.1.0", "rails-ujs": "^5.2.4", @@ -133,37 +134,38 @@ "react-motion": "^0.5.2", "react-notification": "^6.8.5", "react-overlays": "^0.9.1", - "react-redux": "^7.1.3", + "react-redux": "^7.2.0", "react-redux-loading-bar": "^4.0.8", "react-router-dom": "^4.1.1", "react-router-scroll-4": "^1.0.0-beta.1", "react-select": "^3.0.8", "react-sparklines": "^1.7.0", - "react-swipeable-views": "^0.13.4", + "react-swipeable-views": "^0.13.9", "react-textarea-autosize": "^7.1.2", "react-toggle": "^4.1.1", "redis": "^2.7.1", "redux": "^4.0.5", "redux-immutable": "^4.0.0", "redux-thunk": "^2.2.0", - "rellax": "^1.10.0", + "rellax": "^1.12.1", "requestidlecallback": "^0.3.0", "reselect": "^4.0.0", - "rimraf": "^3.0.0", - "sass": "^1.24.2", + "rimraf": "^3.0.2", + "sass": "^1.25.0", "sass-loader": "^8.0.2", + "stacktrace-js": "^2.0.2", "stringz": "^2.0.0", "substring-trie": "^1.0.2", - "terser-webpack-plugin": "^2.3.2", + "terser-webpack-plugin": "^2.3.5", "tesseract.js": "^2.0.0-alpha.16", "throng": "^4.0.0", "tiny-queue": "^0.2.1", - "uuid": "^3.3.3", + "uuid": "^3.4.0", "wavesurfer.js": "^3.3.1", "webpack": "^4.41.5", "webpack-assets-manifest": "^3.1.1", "webpack-bundle-analyzer": "^3.6.0", - "webpack-cli": "^3.3.10", + "webpack-cli": "^3.3.11", "webpack-merge": "^4.2.1", "wicg-inert": "^3.0.0" }, @@ -173,7 +175,7 @@ "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", "eslint": "^6.8.0", - "eslint-plugin-import": "~2.20.0", + "eslint-plugin-import": "~2.20.1", "eslint-plugin-jsx-a11y": "~6.2.3", "eslint-plugin-promise": "~4.2.1", "eslint-plugin-react": "~7.17.0", diff --git a/spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb b/spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb index b79853718..aa5ca433f 100644 --- a/spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/bookmarks_controller_spec.rb @@ -21,36 +21,67 @@ describe Api::V1::Statuses::BookmarksController do post :create, params: { status_id: status.id } end - it 'returns http success' do - expect(response).to have_http_status(:success) + context 'with public status' do + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'updates the bookmarked attribute' do + expect(user.account.bookmarked?(status)).to be true + end + + it 'returns json with updated attributes' do + hash_body = body_as_json + + expect(hash_body[:id]).to eq status.id.to_s + expect(hash_body[:bookmarked]).to be true + end end - it 'updates the bookmarked attribute' do - expect(user.account.bookmarked?(status)).to be true - end + context 'with private status of not-followed account' do + let(:status) { Fabricate(:status, visibility: :private) } - it 'return json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:bookmarked]).to be true + it 'returns http not found' do + expect(response).to have_http_status(404) + end end end describe 'POST #destroy' do - let(:status) { Fabricate(:status, account: user.account) } + context 'with public status' do + let(:status) { Fabricate(:status, account: user.account) } - before do - Bookmark.find_or_create_by!(account: user.account, status: status) - post :destroy, params: { status_id: status.id } + before do + Bookmark.find_or_create_by!(account: user.account, status: status) + post :destroy, params: { status_id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(:success) + end + + it 'updates the bookmarked attribute' do + expect(user.account.bookmarked?(status)).to be false + end + + it 'returns json with updated attributes' do + hash_body = body_as_json + + expect(hash_body[:id]).to eq status.id.to_s + expect(hash_body[:bookmarked]).to be false + end end - it 'returns http success' do - expect(response).to have_http_status(:success) - end + context 'with private status that was not bookmarked' do + let(:status) { Fabricate(:status, visibility: :private) } - it 'updates the bookmarked attribute' do - expect(user.account.bookmarked?(status)).to be false + before do + post :destroy, params: { status_id: status.id } + end + + it 'returns http not found' do + expect(response).to have_http_status(404) + end end end end diff --git a/spec/controllers/api/v1/statuses/favourites_controller_spec.rb b/spec/controllers/api/v1/statuses/favourites_controller_spec.rb index 24a760e20..6e947f5d2 100644 --- a/spec/controllers/api/v1/statuses/favourites_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/favourites_controller_spec.rb @@ -21,45 +21,77 @@ describe Api::V1::Statuses::FavouritesController do post :create, params: { status_id: status.id } end - it 'returns http success' do - expect(response).to have_http_status(200) + context 'with public status' do + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'updates the favourites count' do + expect(status.favourites.count).to eq 1 + end + + it 'updates the favourited attribute' do + expect(user.account.favourited?(status)).to be true + end + + it 'returns json with updated attributes' do + hash_body = body_as_json + + expect(hash_body[:id]).to eq status.id.to_s + expect(hash_body[:favourites_count]).to eq 1 + expect(hash_body[:favourited]).to be true + end end - it 'updates the favourites count' do - expect(status.favourites.count).to eq 1 - end + context 'with private status of not-followed account' do + let(:status) { Fabricate(:status, visibility: :private) } - it 'updates the favourited attribute' do - expect(user.account.favourited?(status)).to be true - end - - it 'return json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:id]).to eq status.id.to_s - expect(hash_body[:favourites_count]).to eq 1 - expect(hash_body[:favourited]).to be true + it 'returns http not found' do + expect(response).to have_http_status(404) + end end end describe 'POST #destroy' do - let(:status) { Fabricate(:status, account: user.account) } + context 'with public status' do + let(:status) { Fabricate(:status, account: user.account) } - before do - FavouriteService.new.call(user.account, status) - post :destroy, params: { status_id: status.id } + before do + FavouriteService.new.call(user.account, status) + post :destroy, params: { status_id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'updates the favourites count' do + expect(status.favourites.count).to eq 0 + end + + it 'updates the favourited attribute' do + expect(user.account.favourited?(status)).to be false + end + + it 'returns json with updated attributes' do + hash_body = body_as_json + + expect(hash_body[:id]).to eq status.id.to_s + expect(hash_body[:favourites_count]).to eq 0 + expect(hash_body[:favourited]).to be false + end end - it 'returns http success' do - expect(response).to have_http_status(200) - end + context 'with private status that was not favourited' do + let(:status) { Fabricate(:status, visibility: :private) } - it 'updates the favourites count' do - expect(status.favourites.count).to eq 0 - end + before do + post :destroy, params: { status_id: status.id } + end - it 'updates the favourited attribute' do - expect(user.account.favourited?(status)).to be false + it 'returns http not found' do + expect(response).to have_http_status(404) + end end end end diff --git a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb index d14ca3e8b..93b244cc3 100644 --- a/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb +++ b/spec/controllers/api/v1/statuses/reblogs_controller_spec.rb @@ -21,45 +21,77 @@ describe Api::V1::Statuses::ReblogsController do post :create, params: { status_id: status.id } end - it 'returns http success' do - expect(response).to have_http_status(200) + context 'with public status' do + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'updates the reblogs count' do + expect(status.reblogs.count).to eq 1 + end + + it 'updates the reblogged attribute' do + expect(user.account.reblogged?(status)).to be true + end + + it 'returns json with updated attributes' do + hash_body = body_as_json + + expect(hash_body[:reblog][:id]).to eq status.id.to_s + expect(hash_body[:reblog][:reblogs_count]).to eq 1 + expect(hash_body[:reblog][:reblogged]).to be true + end end - it 'updates the reblogs count' do - expect(status.reblogs.count).to eq 1 - end + context 'with private status of not-followed account' do + let(:status) { Fabricate(:status, visibility: :private) } - it 'updates the reblogged attribute' do - expect(user.account.reblogged?(status)).to be true - end - - it 'return json with updated attributes' do - hash_body = body_as_json - - expect(hash_body[:reblog][:id]).to eq status.id.to_s - expect(hash_body[:reblog][:reblogs_count]).to eq 1 - expect(hash_body[:reblog][:reblogged]).to be true + it 'returns http not found' do + expect(response).to have_http_status(404) + end end end describe 'POST #destroy' do - let(:status) { Fabricate(:status, account: user.account) } + context 'with public status' do + let(:status) { Fabricate(:status, account: user.account) } - before do - ReblogService.new.call(user.account, status) - post :destroy, params: { status_id: status.id } + before do + ReblogService.new.call(user.account, status) + post :destroy, params: { status_id: status.id } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'updates the reblogs count' do + expect(status.reblogs.count).to eq 0 + end + + it 'updates the reblogged attribute' do + expect(user.account.reblogged?(status)).to be false + end + + it 'returns json with updated attributes' do + hash_body = body_as_json + + expect(hash_body[:id]).to eq status.id.to_s + expect(hash_body[:reblogs_count]).to eq 0 + expect(hash_body[:reblogged]).to be false + end end - it 'returns http success' do - expect(response).to have_http_status(200) - end + context 'with private status that was not reblogged' do + let(:status) { Fabricate(:status, visibility: :private) } - it 'updates the reblogs count' do - expect(status.reblogs.count).to eq 0 - end + before do + post :destroy, params: { status_id: status.id } + end - it 'updates the reblogged attribute' do - expect(user.account.reblogged?(status)).to be false + it 'returns http not found' do + expect(response).to have_http_status(404) + end end end end diff --git a/spec/controllers/auth/registrations_controller_spec.rb b/spec/controllers/auth/registrations_controller_spec.rb index 3e11b34b5..c2e9f33a8 100644 --- a/spec/controllers/auth/registrations_controller_spec.rb +++ b/spec/controllers/auth/registrations_controller_spec.rb @@ -100,7 +100,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do subject do Setting.registrations_mode = 'open' request.headers["Accept-Language"] = accept_language - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678' } } + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } } end it 'redirects to setup' do @@ -116,6 +116,26 @@ RSpec.describe Auth::RegistrationsController, type: :controller do end end + context 'when user has not agreed to terms of service' do + around do |example| + registrations_mode = Setting.registrations_mode + example.run + Setting.registrations_mode = registrations_mode + end + + subject do + Setting.registrations_mode = 'open' + request.headers["Accept-Language"] = accept_language + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'false' } } + end + + it 'does not create user' do + subject + user = User.find_by(email: 'test@example.com') + expect(user).to be_nil + end + end + context 'approval-based registrations without invite' do around do |example| registrations_mode = Setting.registrations_mode @@ -126,7 +146,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do subject do Setting.registrations_mode = 'approved' request.headers["Accept-Language"] = accept_language - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678' } } + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', agreement: 'true' } } end it 'redirects to setup' do @@ -154,7 +174,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do Setting.registrations_mode = 'approved' request.headers["Accept-Language"] = accept_language invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.ago) - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } } + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code, agreement: 'true' } } end it 'redirects to setup' do @@ -182,7 +202,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do Setting.registrations_mode = 'approved' request.headers["Accept-Language"] = accept_language invite = Fabricate(:invite, max_uses: nil, expires_at: 1.hour.from_now) - post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code } } + post :create, params: { user: { account_attributes: { username: 'test' }, email: 'test@example.com', password: '12345678', password_confirmation: '12345678', 'invite_code': invite.code, agreement: 'true' } } end it 'redirects to setup' do diff --git a/yarn.lock b/yarn.lock index bf83649ea..8814eb961 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,17 +18,17 @@ invariant "^2.2.4" semver "^5.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.3.tgz#30b0ebb4dd1585de6923a0b4d179e0b9f5d82941" - integrity sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA== +"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e" + integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.3" - "@babel/helpers" "^7.8.3" - "@babel/parser" "^7.8.3" + "@babel/generator" "^7.8.4" + "@babel/helpers" "^7.8.4" + "@babel/parser" "^7.8.4" "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.3" + "@babel/traverse" "^7.8.4" "@babel/types" "^7.8.3" convert-source-map "^1.7.0" debug "^4.1.0" @@ -39,10 +39,10 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.3.tgz#0e22c005b0a94c1c74eafe19ef78ce53a4d45c03" - integrity sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug== +"@babel/generator@^7.0.0", "@babel/generator@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e" + integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA== dependencies: "@babel/types" "^7.8.3" jsesc "^2.5.1" @@ -64,14 +64,6 @@ "@babel/helper-explode-assignable-expression" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-builder-react-jsx@^7.8.0": - version "7.8.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.0.tgz#4b9111eb862f5fd8840c37d200610fa95ab0aad8" - integrity sha512-Zg7VLtZzcAHoQ13S0pEIGKo8OAG3s5kjsk/4keGmUeNuc810T9fVp6izIaL8ZVeAErRFWJdvqFItY3QMTHMsSg== - dependencies: - "@babel/types" "^7.8.0" - esutils "^2.0.0" - "@babel/helper-builder-react-jsx@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz#dee98d7d79cc1f003d80b76fe01c7f8945665ff6" @@ -167,7 +159,7 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.7.4", "@babel/helper-module-imports@^7.8.3": +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== @@ -251,13 +243,13 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helpers@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.3.tgz#382fbb0382ce7c4ce905945ab9641d688336ce85" - integrity sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ== +"@babel/helpers@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" + integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== dependencies: "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.3" + "@babel/traverse" "^7.8.4" "@babel/types" "^7.8.3" "@babel/highlight@^7.8.3": @@ -269,10 +261,10 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.3.tgz#790874091d2001c9be6ec426c2eed47bc7679081" - integrity sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ== +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8" + integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw== "@babel/plugin-proposal-async-generator-functions@^7.8.3": version "7.8.3" @@ -619,13 +611,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-react-inline-elements@^7.8.0": - version "7.8.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-inline-elements/-/plugin-transform-react-inline-elements-7.8.0.tgz#851799e0f66708563b9ada01b175affa1085f0d5" - integrity sha512-LZCsQfeoF8qqc6IaxJfAe4iSgWlbsdKeEkdxDtb8uzvcDbtXxUYjgUcSsqWgbpC88PIEv65SNzlQZo9/mymgQw== +"@babel/plugin-transform-react-inline-elements@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-inline-elements/-/plugin-transform-react-inline-elements-7.8.3.tgz#fc234d02a35bb188ee3f933d068824e067e42b23" + integrity sha512-CGKUlW3vtgk6YYrIMyfpohmmpILnaeFwszqwTIcem2LQkK1qWJj5w2yTZ7LJr2IR8F0XQ60AZoM8jgAB4zpxCg== dependencies: - "@babel/helper-builder-react-jsx" "^7.8.0" - "@babel/helper-plugin-utils" "^7.8.0" + "@babel/helper-builder-react-jsx" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-react-jsx-self@^7.8.3": version "7.8.3" @@ -666,13 +658,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-runtime@^7.7.6": - version "7.7.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.6.tgz#4f2b548c88922fb98ec1c242afd4733ee3e12f61" - integrity sha512-tajQY+YmXR7JjTwRvwL4HePqoL3DYxpYXIHKVvrOIvJmeHe2y1w4tz5qz9ObUDC9m76rCzIMPyn4eERuwA4a4A== +"@babel/plugin-transform-runtime@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz#c0153bc0a5375ebc1f1591cb7eea223adea9f169" + integrity sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ== dependencies: - "@babel/helper-module-imports" "^7.7.4" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" resolve "^1.8.1" semver "^5.5.1" @@ -825,22 +817,22 @@ "@babel/parser" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.3.tgz#a826215b011c9b4f73f3a893afbc05151358bf9a" - integrity sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg== +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c" + integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.3" + "@babel/generator" "^7.8.4" "@babel/helper-function-name" "^7.8.3" "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.3" + "@babel/parser" "^7.8.4" "@babel/types" "^7.8.3" 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.3.0", "@babel/types@^7.8.0", "@babel/types@^7.8.3": +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.3.0", "@babel/types@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== @@ -1710,11 +1702,6 @@ arrow-key-navigation@^1.1.0: resolved "https://registry.yarnpkg.com/arrow-key-navigation/-/arrow-key-navigation-1.1.0.tgz#c0f7021d006593e2e34e79aa1f032714877d3a76" integrity sha512-u73yfJRmKye5eZiMNrAUKaBIRt47/1NM8WEtVAPjjMDab/PVn0sKIuapvCxl7C+tI9nH0QOl1Tc2YL2aO9n9Zw== -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -1817,10 +1804,10 @@ axios@^0.18.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -axios@^0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.1.tgz#8a6a04eed23dfe72747e1dd43c604b8f1677b5aa" - integrity sha512-Yl+7nfreYKaLRvAvjNPkvfjnQHJM1yLBY3zhqAwcJSwR/6ETkanUgylgtIvkvz0xJ+p/vZuNw8X7Hnb7Whsbpw== +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== dependencies: follow-redirects "1.5.10" @@ -2827,11 +2814,6 @@ core-js-compat@^3.6.2: browserslist "^4.8.3" semver "7.0.0" -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= - core-js@^2.4.0: version "2.6.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.1.tgz#87416ae817de957a3f249b3b5ca475d4aaed6042" @@ -3179,11 +3161,6 @@ csstype@^2.5.7: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41" integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg== -csstype@^2.6.7: - version "2.6.8" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.8.tgz#0fb6fc2417ffd2816a418c9336da74d7f07db431" - integrity sha512-msVS9qTuMT5zwAGCVm4mxfrZ18BNc6Csd0oJAtiFMZ1FAx1CCvy2+5MDmYoix63LM/6NDbNtodCiGYGmFgO0dA== - cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -3466,14 +3443,6 @@ dom-helpers@^3.2.1, dom-helpers@^3.3.1: dependencies: "@babel/runtime" "^7.1.2" -dom-helpers@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.3.tgz#7233248eb3a2d1f74aafca31e52c5299cc8ce821" - integrity sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw== - dependencies: - "@babel/runtime" "^7.6.3" - csstype "^2.6.7" - dom-serializer@0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -3627,13 +3596,6 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= - dependencies: - iconv-lite "~0.4.13" - end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -3732,6 +3694,13 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-stack-parser@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + dependencies: + stackframe "^1.1.1" + es-abstract@^1.13.0, es-abstract@^1.15.0, es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.5.1: version "1.17.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0.tgz#f42a517d0036a5591dbb2c463591dc8bb50309b1" @@ -3749,6 +3718,23 @@ es-abstract@^1.13.0, es-abstract@^1.15.0, es-abstract@^1.17.0, es-abstract@^1.17 string.prototype.trimleft "^2.1.1" string.prototype.trimright "^2.1.1" +es-abstract@^1.17.0-next.0: + version "1.17.4" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" + integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -3878,10 +3864,10 @@ eslint-plugin-eslint-plugin@^2.1.0: resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz#a7a00f15a886957d855feacaafee264f039e62d5" integrity sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg== -eslint-plugin-import@~2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.0.tgz#d749a7263fb6c29980def8e960d380a6aa6aecaa" - integrity sha512-NK42oA0mUc8Ngn4kONOPsPB1XhbUvNHqF+g307dPV28aknPoiNnKLFd9em4nkswwepdF5ouieqv5Th/63U7YJQ== +eslint-plugin-import@~2.20.1: + version "2.20.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3" + integrity sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw== dependencies: array-includes "^3.0.3" array.prototype.flat "^1.2.1" @@ -4328,19 +4314,6 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" -fbjs@^0.8.4: - version "0.8.17" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" - integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - figgy-pudding@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" @@ -4925,6 +4898,11 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.0, has-symbols@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" @@ -5191,7 +5169,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -5755,7 +5733,7 @@ is-resolvable@^1.0.0: resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== -is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -5836,14 +5814,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isomorphic-fetch@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -6245,6 +6215,14 @@ jest-worker@^24.6.0, jest-worker@^24.9.0: merge-stream "^2.0.0" supports-color "^6.1.0" +jest-worker@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.1.0.tgz#75d038bad6fdf58eba0d2ec1835856c497e3907a" + integrity sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg== + dependencies: + merge-stream "^2.0.0" + supports-color "^7.0.0" + jest@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" @@ -7106,14 +7084,6 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-fetch@^1.0.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -7562,10 +7532,10 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1, p-limit@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== dependencies: p-try "^2.0.0" @@ -8401,12 +8371,14 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== +promise.prototype.finally@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz#b8af89160c9c673cefe3b4c4435b53cfd0287067" + integrity sha512-A2HuJWl2opDH0EafgdjwEw7HysI8ff/n4lW4QEVBCUXFk9QeGecBWv0Deph0UmLe3tTNYegz8MOjsVuE6SMoJA== dependencies: - asap "~2.0.3" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.0" + function-bind "^1.1.1" prompts@^2.0.1: version "2.0.3" @@ -8752,14 +8724,13 @@ react-redux-loading-bar@^4.0.8: prop-types "^15.6.2" react-lifecycles-compat "^3.0.2" -react-redux@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.1.3.tgz#717a3d7bbe3a1b2d535c94885ce04cdc5a33fc79" - integrity sha512-uI1wca+ECG9RoVkWQFF4jDMqmaw0/qnvaSvOoL/GA4dNxf6LoV8sUAcNDvE5NWKs4hFpn0t6wswNQnY3f7HT3w== +react-redux@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d" + integrity sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA== dependencies: "@babel/runtime" "^7.5.5" hoist-non-react-statics "^3.3.0" - invariant "^2.2.4" loose-envify "^1.4.0" prop-types "^15.7.2" react-is "^16.9.0" @@ -8818,36 +8789,35 @@ react-sparklines@^1.7.0: dependencies: prop-types "^15.5.10" -react-swipeable-views-core@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/react-swipeable-views-core/-/react-swipeable-views-core-0.13.1.tgz#8829a922462a8bdd701709cd1b385393d38f1527" - integrity sha512-EP8sCvvD7VDiZLglPt9icMuMNu8qLRLk0ab/fB1HXv7lX8ClnwF3UMCM0ZrN3sguSY7CsX3LevducGGsT1VcDg== +react-swipeable-views-core@^0.13.7: + version "0.13.7" + resolved "https://registry.yarnpkg.com/react-swipeable-views-core/-/react-swipeable-views-core-0.13.7.tgz#c082b553f26e83fd20fc17f934200eb717023c8a" + integrity sha512-ekn9oDYfBt0oqJSGGwLEhKvn+QaqMGTy//9dURTLf+vp7W5j6GvmKryYdnwJCDITaPFI2hujXV4CH9krhvaE5w== dependencies: "@babel/runtime" "7.0.0" warning "^4.0.1" -react-swipeable-views-utils@^0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/react-swipeable-views-utils/-/react-swipeable-views-utils-0.13.4.tgz#809fe408e55ed80f84eea508074387c23febf0ab" - integrity sha512-C6Ppq7Z5JIn4l8gKuRzzoGcm5Yiu57HBribjZ0T8DIeLisvIvk8A+Wysb1JhP0hsnJ9hIozlEZ8oJi4eBUTRXg== +react-swipeable-views-utils@^0.13.9: + version "0.13.9" + resolved "https://registry.yarnpkg.com/react-swipeable-views-utils/-/react-swipeable-views-utils-0.13.9.tgz#a66e98f2f4502d8b00182901f80d13b2f903e10f" + integrity sha512-QLGxRKrbJCbWz94vkWLzb1Daaa2Y/TZKmsNKQ6WSNrS+chrlfZ3z9tqZ7YUJlW6pRWp3QZdLSY3UE3cN0TXXmw== dependencies: "@babel/runtime" "7.0.0" - fbjs "^0.8.4" keycode "^2.1.7" prop-types "^15.6.0" react-event-listener "^0.6.0" - react-swipeable-views-core "^0.13.1" + react-swipeable-views-core "^0.13.7" + shallow-equal "^1.2.1" -react-swipeable-views@^0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/react-swipeable-views/-/react-swipeable-views-0.13.4.tgz#ebbe50a8592b185dbedf9e0060eaee09cf6b2c67" - integrity sha512-Qwmaj8LASEgxp3i4FBEgs1LM/Yqk7mFRp0fRgXH515NIEePUcjrrkuwvvmvwNQLDbN6PNv4QAuosEaTRyjEOUA== +react-swipeable-views@^0.13.9: + version "0.13.9" + resolved "https://registry.yarnpkg.com/react-swipeable-views/-/react-swipeable-views-0.13.9.tgz#d6a6c508bf5288ad55509f9c65916db5df0f2cec" + integrity sha512-WXC2FKYvZ9QdJ31v9LjEJEl1bA7E4AcaloTkbW0uU0dYf5uvv4aOpiyxubvOkVl1a5L2UAHmKSif4TmJ9usrSg== dependencies: "@babel/runtime" "7.0.0" - dom-helpers "^5.1.3" prop-types "^15.5.4" - react-swipeable-views-core "^0.13.1" - react-swipeable-views-utils "^0.13.4" + react-swipeable-views-core "^0.13.7" + react-swipeable-views-utils "^0.13.9" warning "^4.0.1" react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0: @@ -9102,10 +9072,10 @@ regjsparser@^0.6.0: dependencies: jsesc "~0.5.0" -rellax@^1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/rellax/-/rellax-1.10.0.tgz#0308b813b458f9175d37ffb4272e1f616eab1341" - integrity sha512-BtxD9b8cAQcTs6iat1fqKvHMjIZ8CaxjsC5U/cIIVHC4LjkIsr0ZmeqxUm5ZvBvyjLwfPbU8Wcryp77sR5C8QA== +rellax@^1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/rellax/-/rellax-1.12.1.tgz#1b433ef7ac4aa3573449a33efab391c112f6b34d" + integrity sha512-XBIi0CDpW5FLTujYjYBn1CIbK2CJL6TsAg/w409KghP2LucjjzBjsujXDAjyBLWgsfupfUcL5WzdnIPcGfK7XA== remove-trailing-separator@^1.0.1: version "1.1.0" @@ -9305,24 +9275,24 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@2.6.3, rimraf@^2.6.2, rimraf@~2.6.2: +rimraf@2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" -rimraf@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b" - integrity sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg== +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" @@ -9448,10 +9418,10 @@ sass-loader@^8.0.2: schema-utils "^2.6.1" semver "^6.3.0" -sass@^1.24.2: - version "1.24.2" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.24.2.tgz#0a0e0f00368be6808b2e94470172266ac45498fe" - integrity sha512-0JxdMMRd0fOmGFQFRI91vh4n0Ed766ib9JwPUa+1C37zn3VaqlHxbknUn/6LqP/MSfvNPxRYoCrYf5g8vu4OHw== +sass@^1.25.0: + version "1.25.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.25.0.tgz#f8bd7dfbb39d6b0305e27704a8ebe637820693f3" + integrity sha512-uQMjye0Y70SEDGO56n0j91tauqS9E1BmpKHtiYNQScXDHeaE9uHwNEqQNFf4Bes/3DHMNinB6u79JsG10XWNyw== dependencies: chokidar ">=2.0.0 <4.0.0" @@ -9477,10 +9447,10 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.1.tgz#eb78f0b945c7bcfa2082b3565e8db3548011dc4f" - integrity sha512-0WXHDs1VDJyo+Zqs9TKLKyD/h7yDpHUhEFsM2CzkICFdoX1av+GBq/J2xRTFfsQO5kBfhZzANf2VcIm84jqDbg== +schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.4.tgz#a27efbf6e4e78689d91872ee3ccfa57d7bdd0f53" + integrity sha512-VNjcaUxVnEeun6B2fiiUDjXXBtD4ZSH7pdbfIu1pOFwgptDPLMo/z9jr4sUfsjFVPqDCEin/F7IYlq7/E6yDbQ== dependencies: ajv "^6.10.2" ajv-keywords "^3.4.1" @@ -9587,7 +9557,7 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4, setimmediate@^1.0.5: +setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= @@ -9617,6 +9587,11 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +shallow-equal@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" + integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA== + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -9786,6 +9761,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -9899,11 +9879,40 @@ stable@~0.1.6: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-generator@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" + integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== + dependencies: + stackframe "^1.1.1" + stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== +stackframe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.1.1.tgz#ffef0a3318b1b60c3b58564989aca5660729ec71" + integrity sha512-0PlYhdKh6AfFxRyK/v+6/k+/mMfyiEBbTM5L94D0ZytQnJ166wuwoTYLHFWGbs2dpA8Rgq763KGWmN1EQEYHRQ== + +stacktrace-gps@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" + integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== + dependencies: + source-map "0.5.6" + stackframe "^1.1.1" + +stacktrace-js@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b" + integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== + dependencies: + error-stack-parser "^2.0.6" + stack-generator "^2.0.5" + stacktrace-gps "^3.0.4" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -10141,6 +10150,13 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +supports-color@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + svgo@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.1.1.tgz#12384b03335bcecd85cfa5f4e3375fed671cb985" @@ -10231,15 +10247,16 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser-webpack-plugin@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.2.tgz#6d3d1b0590c8f729bfbaeb7fb2528b8b62db4c74" - integrity sha512-SmvB/6gtEPv+CJ88MH5zDOsZdKXPS/Uzv2//e90+wM1IHFUhsguPKEILgzqrM1nQ4acRXN/SV4Obr55SXC+0oA== +terser-webpack-plugin@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz#5ad971acce5c517440ba873ea4f09687de2f4a81" + integrity sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w== dependencies: cacache "^13.0.1" find-cache-dir "^3.2.0" - jest-worker "^24.9.0" - schema-utils "^2.6.1" + jest-worker "^25.1.0" + p-limit "^2.2.2" + schema-utils "^2.6.4" serialize-javascript "^2.1.2" source-map "^0.6.1" terser "^4.4.3" @@ -10500,11 +10517,6 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -ua-parser-js@^0.7.18: - version "0.7.19" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b" - integrity sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ== - uglify-js@^3.1.4: version "3.7.2" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.2.tgz#cb1a601e67536e9ed094a92dd1e333459643d3f9" @@ -10682,10 +10694,10 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.0.1, uuid@^3.3.2, uuid@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== +uuid@^3.0.1, uuid@^3.3.2, uuid@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-compile-cache@2.0.3, v8-compile-cache@^2.0.3: version "2.0.3" @@ -10820,10 +10832,10 @@ webpack-bundle-analyzer@^3.6.0: opener "^1.5.1" ws "^6.0.0" -webpack-cli@^3.3.10: - version "3.3.10" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.10.tgz#17b279267e9b4fb549023fae170da8e6e766da13" - integrity sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg== +webpack-cli@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" + integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== dependencies: chalk "2.4.2" cross-spawn "6.0.5" @@ -10960,11 +10972,6 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.24" -whatwg-fetch@>=0.10.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" - integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== - whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"