Commit 2ea5b315 authored by Nathan Ladd's avatar Nathan Ladd
Browse files

Merge branch 'mastodon-v3.1.2'

parents 7ca65e1e 3f72e0fd
...@@ -3,6 +3,32 @@ Changelog ...@@ -3,6 +3,32 @@ Changelog
All notable changes to this project will be documented in this file. 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 ## [3.1.1] - 2020-02-10
### Fixed ### Fixed
......
...@@ -5,14 +5,25 @@ SHELL ["bash", "-c"] ...@@ -5,14 +5,25 @@ SHELL ["bash", "-c"]
# Install Node v12 (LTS) # Install Node v12 (LTS)
ENV NODE_VER="12.14.0" 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 update && \
apt -y install wget python && \ apt -y install wget python && \
cd ~ && \ cd ~ && \
wget https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-linux-x64.tar.gz && \ wget https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-linux-$ARCH.tar.gz && \
tar xf node-v$NODE_VER-linux-x64.tar.gz && \ tar xf node-v$NODE_VER-linux-$ARCH.tar.gz && \
rm node-v$NODE_VER-linux-x64.tar.gz && \ rm node-v$NODE_VER-linux-$ARCH.tar.gz && \
mv node-v$NODE_VER-linux-x64 /opt/node mv node-v$NODE_VER-linux-$ARCH /opt/node
# Install jemalloc # Install jemalloc
ENV JE_VER="5.2.1" ENV JE_VER="5.2.1"
......
...@@ -9,7 +9,7 @@ gem 'puma', '~> 4.3' ...@@ -9,7 +9,7 @@ gem 'puma', '~> 4.3'
gem 'rails', '~> 5.2.4' gem 'rails', '~> 5.2.4'
gem 'sprockets', '~> 3.7.2' gem 'sprockets', '~> 3.7.2'
gem 'thor', '~> 0.20' gem 'thor', '~> 0.20'
gem 'rack', '~> 2.1.2' gem 'rack', '~> 2.2.2'
gem 'thwait', '~> 0.1.0' gem 'thwait', '~> 0.1.0'
gem 'e2mmap', '~> 0.1.0' gem 'e2mmap', '~> 0.1.0'
...@@ -101,14 +101,14 @@ gem 'webpacker', '~> 4.2' ...@@ -101,14 +101,14 @@ gem 'webpacker', '~> 4.2'
gem 'webpush' gem 'webpush'
gem 'json-ld' gem 'json-ld'
gem 'json-ld-preloaded', '~> 3.0' gem 'json-ld-preloaded', '~> 3.1'
gem 'rdf-normalize', '~> 0.4' gem 'rdf-normalize', '~> 0.4'
group :development, :test do group :development, :test do
gem 'fabrication', '~> 2.21' gem 'fabrication', '~> 2.21'
gem 'fuubar', '~> 2.5' gem 'fuubar', '~> 2.5'
gem 'i18n-tasks', '~> 0.9', require: false gem 'i18n-tasks', '~> 0.9', require: false
gem 'pry-byebug', '~> 3.7' gem 'pry-byebug', '~> 3.8'
gem 'pry-rails', '~> 0.3' gem 'pry-rails', '~> 0.3'
gem 'rspec-rails', '~> 3.9' gem 'rspec-rails', '~> 3.9'
end end
...@@ -118,13 +118,13 @@ group :production, :test do ...@@ -118,13 +118,13 @@ group :production, :test do
end end
group :test do group :test do
gem 'capybara', '~> 3.30' gem 'capybara', '~> 3.31'
gem 'climate_control', '~> 0.2' gem 'climate_control', '~> 0.2'
gem 'faker', '~> 2.10' gem 'faker', '~> 2.10'
gem 'microformats', '~> 4.2' gem 'microformats', '~> 4.2'
gem 'rails-controller-testing', '~> 1.0' gem 'rails-controller-testing', '~> 1.0'
gem 'rspec-sidekiq', '~> 3.0' gem 'rspec-sidekiq', '~> 3.0'
gem 'simplecov', '~> 0.17', require: false gem 'simplecov', '~> 0.18', require: false
gem 'webmock', '~> 3.8' gem 'webmock', '~> 3.8'
gem 'parallel_tests', '~> 2.30' gem 'parallel_tests', '~> 2.30'
end end
...@@ -136,7 +136,7 @@ group :development do ...@@ -136,7 +136,7 @@ group :development do
gem 'binding_of_caller', '~> 0.7' gem 'binding_of_caller', '~> 0.7'
gem 'bullet', '~> 6.1' gem 'bullet', '~> 6.1'
gem 'letter_opener', '~> 1.7' gem 'letter_opener', '~> 1.7'
gem 'letter_opener_web', '~> 1.3' gem 'letter_opener_web', '~> 1.4'
gem 'memory_profiler' gem 'memory_profiler'
gem 'rubocop', '~> 0.79', require: false gem 'rubocop', '~> 0.79', require: false
gem 'rubocop-rails', '~> 2.4', require: false gem 'rubocop-rails', '~> 2.4', require: false
......
...@@ -127,7 +127,7 @@ GEM ...@@ -127,7 +127,7 @@ GEM
bundler-audit (0.6.1) bundler-audit (0.6.1)
bundler (>= 1.2.0, < 3) bundler (>= 1.2.0, < 3)
thor (~> 0.18) thor (~> 0.18)
byebug (11.0.0) byebug (11.1.1)
capistrano (3.11.2) capistrano (3.11.2)
airbrussh (>= 1.0.0) airbrussh (>= 1.0.0)
i18n i18n
...@@ -144,7 +144,7 @@ GEM ...@@ -144,7 +144,7 @@ GEM
sshkit (~> 1.3) sshkit (~> 1.3)
capistrano-yarn (2.0.2) capistrano-yarn (2.0.2)
capistrano (~> 3.0) capistrano (~> 3.0)
capybara (3.30.0) capybara (3.31.0)
addressable addressable
mini_mime (>= 0.1.3) mini_mime (>= 0.1.3)
nokogiri (~> 1.8) nokogiri (~> 1.8)
...@@ -311,10 +311,9 @@ GEM ...@@ -311,10 +311,9 @@ GEM
multi_json (~> 1.14) multi_json (~> 1.14)
rack (~> 2.0) rack (~> 2.0)
rdf (~> 3.1) rdf (~> 3.1)
json-ld-preloaded (3.0.6) json-ld-preloaded (3.1.0)
json-ld (~> 3.0) json-ld (~> 3.1)
multi_json (~> 1.12) rdf (~> 3.1)
rdf (~> 3.0)
jsonapi-renderer (0.2.2) jsonapi-renderer (0.2.2)
jwt (2.1.0) jwt (2.1.0)
kaminari (1.1.1) kaminari (1.1.1)
...@@ -333,7 +332,7 @@ GEM ...@@ -333,7 +332,7 @@ GEM
addressable (~> 2.3) addressable (~> 2.3)
letter_opener (1.7.0) letter_opener (1.7.0)
launchy (~> 2.2) launchy (~> 2.2)
letter_opener_web (1.3.4) letter_opener_web (1.4.0)
actionmailer (>= 3.2) actionmailer (>= 3.2)
letter_opener (~> 1.0) letter_opener (~> 1.0)
railties (>= 3.2) railties (>= 3.2)
...@@ -375,7 +374,7 @@ GEM ...@@ -375,7 +374,7 @@ GEM
net-ssh (>= 2.6.5, < 6.0.0) net-ssh (>= 2.6.5, < 6.0.0)
net-ssh (5.2.0) net-ssh (5.2.0)
nio4r (2.5.2) nio4r (2.5.2)
nokogiri (1.10.7) nokogiri (1.10.8)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
nokogumbo (2.0.1) nokogumbo (2.0.1)
nokogiri (~> 1.8, >= 1.8.4) nokogiri (~> 1.8, >= 1.8.4)
...@@ -418,7 +417,7 @@ GEM ...@@ -418,7 +417,7 @@ GEM
pg (1.2.2) pg (1.2.2)
pghero (2.4.1) pghero (2.4.1)
activerecord (>= 5) activerecord (>= 5)
pkg-config (1.4.0) pkg-config (1.4.1)
premailer (1.11.1) premailer (1.11.1)
addressable addressable
css_parser (>= 1.6.0) css_parser (>= 1.6.0)
...@@ -430,7 +429,7 @@ GEM ...@@ -430,7 +429,7 @@ GEM
pry (0.12.2) pry (0.12.2)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.9.0) method_source (~> 0.9.0)
pry-byebug (3.7.0) pry-byebug (3.8.0)
byebug (~> 11.0) byebug (~> 11.0)
pry (~> 0.10) pry (~> 0.10)
pry-rails (0.3.9) pry-rails (0.3.9)
...@@ -441,7 +440,7 @@ GEM ...@@ -441,7 +440,7 @@ GEM
pundit (2.1.0) pundit (2.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.1.6) raabro (1.1.6)
rack (2.1.2) rack (2.2.2)
rack-attack (6.2.2) rack-attack (6.2.2)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rack-cors (1.1.1) rack-cors (1.1.1)
...@@ -550,7 +549,7 @@ GEM ...@@ -550,7 +549,7 @@ GEM
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.7) unicode-display_width (>= 1.4.0, < 1.7)
rubocop-rails (2.4.1) rubocop-rails (2.4.2)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 0.72.0) rubocop (>= 0.72.0)
ruby-progressbar (1.10.1) ruby-progressbar (1.10.1)
...@@ -584,11 +583,10 @@ GEM ...@@ -584,11 +583,10 @@ GEM
simple_form (5.0.1) simple_form (5.0.1)
actionpack (>= 5.0) actionpack (>= 5.0)
activemodel (>= 5.0) activemodel (>= 5.0)
simplecov (0.17.1) simplecov (0.18.2)
docile (~> 1.1) docile (~> 1.1)
json (>= 1.8, < 3) simplecov-html (~> 0.11)
simplecov-html (~> 0.10.0) simplecov-html (0.12.0)
simplecov-html (0.10.2)
sprockets (3.7.2) sprockets (3.7.2)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
...@@ -680,7 +678,7 @@ DEPENDENCIES ...@@ -680,7 +678,7 @@ DEPENDENCIES
capistrano-rails (~> 1.4) capistrano-rails (~> 1.4)
capistrano-rbenv (~> 2.1) capistrano-rbenv (~> 2.1)
capistrano-yarn (~> 2.0) capistrano-yarn (~> 2.0)
capybara (~> 3.30) capybara (~> 3.31)
charlock_holmes (~> 0.7.7) charlock_holmes (~> 0.7.7)
chewy (~> 5.1) chewy (~> 5.1)
cld3 (~> 3.2.6) cld3 (~> 3.2.6)
...@@ -714,10 +712,10 @@ DEPENDENCIES ...@@ -714,10 +712,10 @@ DEPENDENCIES
idn-ruby idn-ruby
iso-639 iso-639
json-ld json-ld
json-ld-preloaded (~> 3.0) json-ld-preloaded (~> 3.1)
kaminari (~> 1.1) kaminari (~> 1.1)
letter_opener (~> 1.7) letter_opener (~> 1.7)
letter_opener_web (~> 1.3) letter_opener_web (~> 1.4)
link_header (~> 0.0) link_header (~> 0.0)
lograge (~> 0.11) lograge (~> 0.11)
makara (~> 0.4) makara (~> 0.4)
...@@ -745,11 +743,11 @@ DEPENDENCIES ...@@ -745,11 +743,11 @@ DEPENDENCIES
posix-spawn! posix-spawn!
premailer-rails premailer-rails
private_address_check (~> 0.5) private_address_check (~> 0.5)
pry-byebug (~> 3.7) pry-byebug (~> 3.8)
pry-rails (~> 0.3) pry-rails (~> 0.3)
puma (~> 4.3) puma (~> 4.3)
pundit (~> 2.1) pundit (~> 2.1)
rack (~> 2.1.2) rack (~> 2.2.2)
rack-attack (~> 6.2) rack-attack (~> 6.2)
rack-cors (~> 1.1) rack-cors (~> 1.1)
rails (~> 5.2.4) rails (~> 5.2.4)
...@@ -773,7 +771,7 @@ DEPENDENCIES ...@@ -773,7 +771,7 @@ DEPENDENCIES
sidekiq-unique-jobs (~> 6.0) sidekiq-unique-jobs (~> 6.0)
simple-navigation (~> 4.1) simple-navigation (~> 4.1)
simple_form (~> 5.0) simple_form (~> 5.0)
simplecov (~> 0.17) simplecov (~> 0.18)
sprockets (~> 3.7.2) sprockets (~> 3.7.2)
sprockets-rails (~> 3.2) sprockets-rails (~> 3.2)
stackprof stackprof
......
...@@ -9,7 +9,7 @@ class AccountsController < ApplicationController ...@@ -9,7 +9,7 @@ class AccountsController < ApplicationController
before_action :set_cache_headers before_action :set_cache_headers
before_action :set_body_classes 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! skip_before_action :require_functional!
def show def show
......
...@@ -11,7 +11,7 @@ class Api::V1::AnnouncementsController < Api::BaseController ...@@ -11,7 +11,7 @@ class Api::V1::AnnouncementsController < Api::BaseController
end end
def dismiss def dismiss
AnnouncementMute.create!(account: current_account, announcement: @announcement) AnnouncementMute.find_or_create_by!(account: current_account, announcement: @announcement)
render_empty render_empty
end end
......
...@@ -5,35 +5,28 @@ class Api::V1::Statuses::BookmarksController < Api::BaseController ...@@ -5,35 +5,28 @@ class Api::V1::Statuses::BookmarksController < Api::BaseController
before_action -> { doorkeeper_authorize! :write, :'write:bookmarks' } before_action -> { doorkeeper_authorize! :write, :'write:bookmarks' }
before_action :require_user! before_action :require_user!
before_action :set_status
respond_to :json respond_to :json
def create def create
@status = bookmarked_status current_account.bookmarks.find_or_create_by!(account: current_account, status: @status)
render json: @status, serializer: REST::StatusSerializer render json: @status, serializer: REST::StatusSerializer
end end
def destroy def destroy
@status = requested_status bookmark = current_account.bookmarks.find_by(status: @status)
@bookmarks_map = { @status.id => false } bookmark&.destroy!
bookmark = Bookmark.find_by!(account: current_user.account, status: @status) render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, bookmarks_map: { @status.id => false })
bookmark.destroy!
render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_user&.account_id, bookmarks_map: @bookmarks_map)
end end
private private
def bookmarked_status def set_status
authorize_with current_user.account, requested_status, :show? @status = Status.find(params[:status_id])
authorize @status, :show?
bookmark = Bookmark.find_or_create_by!(account: current_user.account, status: requested_status) rescue Mastodon::NotPermittedError
not_found
bookmark.status.reload
end
def requested_status
Status.find(params[:status_id])
end end
end end
...@@ -69,8 +69,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController ...@@ -69,8 +69,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
@status = Status.find(params[:status_id]) @status = Status.find(params[:status_id])
authorize @status, :show? authorize @status, :show?
rescue Mastodon::NotPermittedError rescue Mastodon::NotPermittedError
# Reraise in order to get a 404 instead of a 403 error code not_found
raise ActiveRecord::RecordNotFound
end end
def pagination_params(core_params) def pagination_params(core_params)
......
...@@ -5,34 +5,26 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController ...@@ -5,34 +5,26 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController
before_action -> { doorkeeper_authorize! :write, :'write:favourites' } before_action -> { doorkeeper_authorize! :write, :'write:favourites' }
before_action :require_user! before_action :require_user!
before_action :set_status
respond_to :json respond_to :json
def create def create
@status = favourited_status FavouriteService.new.call(current_account, @status)
render json: @status, serializer: REST::StatusSerializer render json: @status, serializer: REST::StatusSerializer
end end
def destroy def destroy
@status = requested_status UnfavouriteWorker.perform_async(current_account.id, @status.id)
@favourites_map = { @status.id => false } render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, 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)
end end
private private
def favourited_status def set_status
service_result.status.reload @status = Status.find(params[:status_id])
end authorize @status, :show?
rescue Mastodon::NotPermittedError
def service_result not_found
FavouriteService.new.call(current_user.account, requested_status)
end
def requested_status
Status.find(params[:status_id])
end end
end end
...@@ -66,8 +66,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController ...@@ -66,8 +66,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
@status = Status.find(params[:status_id]) @status = Status.find(params[:status_id])
authorize @status, :show? authorize @status, :show?
rescue Mastodon::NotPermittedError rescue Mastodon::NotPermittedError
# Reraise in order to get a 404 instead of a 403 error code not_found
raise ActiveRecord::RecordNotFound
end end
def pagination_params(core_params) def pagination_params(core_params)
......
...@@ -5,33 +5,34 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController ...@@ -5,33 +5,34 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
before_action -> { doorkeeper_authorize! :write, :'write:statuses' } before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
before_action :require_user! before_action :require_user!
before_action :set_reblog
respond_to :json respond_to :json
def create 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 render json: @status, serializer: REST::StatusSerializer
end end
def destroy def destroy
@status = status_for_destroy.reblog @status = current_account.statuses.find_by(reblog_of_id: @reblog.id)
@reblogs_map = { @status.id => false }
authorize status_for_destroy, :unreblog? if @status
status_for_destroy.discard authorize @status, :unreblog?
RemovalWorker.perform_async(status_for_destroy.id) @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 end
private private
def status_for_reblog def set_reblog
Status.find params[:status_id] @reblog = Status.find(params[:status_id])
end authorize @reblog, :show?
rescue Mastodon::NotPermittedError
def status_for_destroy not_found
@status_for_destroy ||= current_user.account.statuses.where(reblog_of_id: params[:status_id]).first!
end end
def reblog_params def reblog_params
......
...@@ -41,7 +41,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController ...@@ -41,7 +41,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
resource.locale = I18n.locale resource.locale = I18n.locale
resource.invite_code = params[:invite_code] if resource.invite_code.blank? 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