diff --git a/.codeclimate.yml b/.codeclimate.yml index 9817d7f1c..d8d5c0ac7 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -30,7 +30,7 @@ plugins: channel: eslint-6 rubocop: enabled: true - channel: rubocop-0-76 + channel: rubocop-0-82 sass-lint: enabled: true exclude_patterns: diff --git a/.env.production.sample b/.env.production.sample index a752298e8..1292b752e 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -33,7 +33,7 @@ LOCAL_DOMAIN=example.com # ALTERNATE_DOMAINS=example1.com,example2.com # Application secrets -# Generate each with the `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose) +# Generate each with the `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web bundle exec rake secret` if you use docker compose) SECRET_KEY_BASE= OTP_SECRET= @@ -42,7 +42,7 @@ OTP_SECRET= # You should only generate this once per instance. If you later decide to change it, all push subscription will # be invalidated, requiring the users to access the website again to resubscribe. # -# Generate with `RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web rake mastodon:webpush:generate_vapid_key` if you use docker compose) +# Generate with `RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web bundle exec rake mastodon:webpush:generate_vapid_key` if you use docker compose) # # For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html VAPID_PRIVATE_KEY= diff --git a/.rubocop.yml b/.rubocop.yml index 9a68becbb..3a11f7000 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,7 +2,7 @@ require: - rubocop-rails AllCops: - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.4 Exclude: - 'spec/**/*' - 'db/**/*' @@ -46,7 +46,7 @@ Metrics/ClassLength: Metrics/CyclomaticComplexity: Max: 25 -Metrics/LineLength: +Layout/LineLength: AllowURI: true Enabled: false diff --git a/Gemfile b/Gemfile index c5b957114..2cd2da270 100644 --- a/Gemfile +++ b/Gemfile @@ -20,7 +20,7 @@ gem 'makara', '~> 0.4' gem 'pghero', '~> 2.4' gem 'dotenv-rails', '~> 2.7' -gem 'aws-sdk-s3', '~> 1.63', require: false +gem 'aws-sdk-s3', '~> 1.64', require: false gem 'fog-core', '<= 2.1.0' gem 'fog-openstack', '~> 0.3', require: false gem 'paperclip', '~> 6.0' @@ -49,7 +49,7 @@ gem 'omniauth-saml', '~> 1.10' gem 'omniauth', '~> 1.9' gem 'discard', '~> 1.2' -gem 'doorkeeper', '~> 5.3' +gem 'doorkeeper', '~> 5.4' gem 'fast_blank', '~> 1.0' gem 'fastimage' gem 'goldfinger', '~> 2.1' @@ -57,12 +57,12 @@ gem 'hiredis', '~> 0.6' gem 'redis-namespace', '~> 1.7' gem 'health_check', git: 'https://github.com/ianheggie/health_check', ref: '0b799ead604f900ed50685e9b2d469cd2befba5b' gem 'htmlentities', '~> 4.3' -gem 'http', '~> 4.3' +gem 'http', '~> 4.4' gem 'http_accept_language', '~> 2.1' gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2', submodules: true gem 'httplog', '~> 1.4.2' gem 'idn-ruby', require: 'idn' -gem 'kaminari', '~> 1.1' +gem 'kaminari', '~> 1.2' gem 'link_header', '~> 0.0' gem 'mime-types', '~> 3.3.1', require: 'mime/types/columnar' gem 'nilsimsa', git: 'https://github.com/witgo/nilsimsa', ref: 'fd184883048b922b176939f851338d0a4971a532' @@ -75,7 +75,7 @@ gem 'parallel', '~> 1.19' gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c' gem 'pundit', '~> 2.1' gem 'premailer-rails' -gem 'rack-attack', '~> 6.2' +gem 'rack-attack', '~> 6.3' gem 'rack-cors', '~> 1.1', require: 'rack/cors' gem 'rails-i18n', '~> 5.1' gem 'rails-settings-cached', '~> 0.6' @@ -96,8 +96,8 @@ gem 'strong_migrations', '~> 0.6' gem 'tty-command', '~> 0.9', require: false gem 'tty-prompt', '~> 0.21', require: false gem 'twitter-text', '~> 1.14' -gem 'tzinfo-data', '~> 1.2019' -gem 'webpacker', '~> 4.2' +gem 'tzinfo-data', '~> 1.2020' +gem 'webpacker', '~> 5.1' gem 'webpush' gem 'json-ld' @@ -110,7 +110,7 @@ group :development, :test do gem 'fabrication', '~> 2.21' gem 'fuubar', '~> 2.5' gem 'i18n-tasks', '~> 0.9', require: false - gem 'pry-byebug', '~> 3.8' + gem 'pry-byebug', '~> 3.9' gem 'pry-rails', '~> 0.3' gem 'rspec-rails', '~> 4.0' end @@ -120,7 +120,7 @@ group :production, :test do end group :test do - gem 'capybara', '~> 3.31' + gem 'capybara', '~> 3.32' gem 'climate_control', '~> 0.2' gem 'faker', '~> 2.11' gem 'microformats', '~> 4.2' @@ -135,18 +135,18 @@ end group :development do gem 'active_record_query_trace', '~> 1.7' gem 'annotate', '~> 3.1' - gem 'better_errors', '~> 2.6' + gem 'better_errors', '~> 2.7' gem 'binding_of_caller', '~> 0.7' gem 'bullet', '~> 6.1' gem 'letter_opener', '~> 1.7' gem 'letter_opener_web', '~> 1.4' gem 'memory_profiler' - gem 'rubocop', '~> 0.79', require: false + gem 'rubocop', '~> 0.82', require: false gem 'rubocop-rails', '~> 2.5', require: false gem 'brakeman', '~> 4.8', require: false gem 'bundler-audit', '~> 0.6', require: false - gem 'capistrano', '~> 3.13' + gem 'capistrano', '~> 3.14' gem 'capistrano-rails', '~> 1.4' gem 'capistrano-rbenv', '~> 2.1' gem 'capistrano-yarn', '~> 2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 7525911ff..e4af7b195 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -92,23 +92,23 @@ GEM av (0.9.0) cocaine (~> 0.5.3) aws-eventstream (1.1.0) - aws-partitions (1.303.0) - aws-sdk-core (3.94.0) + aws-partitions (1.312.0) + aws-sdk-core (3.95.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.239.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.30.0) + aws-sdk-kms (1.31.0) aws-sdk-core (~> 3, >= 3.71.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.63.0) + aws-sdk-s3 (1.64.0) aws-sdk-core (~> 3, >= 3.83.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.2) + aws-sigv4 (1.1.3) aws-eventstream (~> 1.0, >= 1.0.2) bcrypt (3.1.13) - better_errors (2.6.0) + better_errors (2.7.0) coderay (>= 1.0.0) erubi (>= 1.0.0) rack (>= 0.9.0) @@ -118,8 +118,8 @@ GEM ffi (~> 1.10.0) bootsnap (1.4.6) msgpack (~> 1.0) - brakeman (4.8.0) - browser (4.0.0) + brakeman (4.8.1) + browser (4.1.0) builder (3.2.4) bullet (6.1.0) activesupport (>= 3.0.0) @@ -127,8 +127,8 @@ GEM bundler-audit (0.6.1) bundler (>= 1.2.0, < 3) thor (~> 0.18) - byebug (11.1.1) - capistrano (3.13.0) + byebug (11.1.3) + capistrano (3.14.0) airbrussh (>= 1.0.0) i18n rake (>= 10.0.0) @@ -143,7 +143,7 @@ GEM sshkit (~> 1.3) capistrano-yarn (2.0.2) capistrano (~> 3.0) - capybara (3.31.0) + capybara (3.32.1) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) @@ -194,7 +194,7 @@ GEM docile (1.3.2) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - doorkeeper (5.3.1) + doorkeeper (5.4.0) railties (>= 5) dotenv (2.7.5) dotenv-rails (2.7.5) @@ -213,7 +213,7 @@ GEM encryptor (3.0.0) equatable (0.6.1) erubi (1.9.0) - et-orbi (1.2.3) + et-orbi (1.2.4) tzinfo excon (0.73.0) fabrication (2.21.1) @@ -240,7 +240,7 @@ GEM fog-json (>= 1.0) ipaddress (>= 0.8) formatador (0.2.5) - fugit (1.3.3) + fugit (1.3.5) et-orbi (~> 1.1, >= 1.1.8) raabro (~> 1.1) fuubar (2.5.0) @@ -270,7 +270,7 @@ GEM hiredis (0.6.3) hkdf (0.3.0) htmlentities (4.3.4) - http (4.3.0) + http (4.4.1) addressable (~> 2.3) http-cookie (~> 1.0) http-form_data (~> 2.2) @@ -303,7 +303,7 @@ GEM jmespath (1.4.0) json (2.3.0) json-canonicalization (0.2.0) - json-ld (3.1.3) + json-ld (3.1.4) htmlentities (~> 4.3) json-canonicalization (~> 0.2) link_header (~> 0.0, >= 0.0.8) @@ -314,21 +314,21 @@ GEM json-ld (~> 3.1) rdf (~> 3.1) jsonapi-renderer (0.2.2) - jwt (2.1.0) - kaminari (1.1.1) + jwt (2.2.1) + kaminari (1.2.0) activesupport (>= 4.1.0) - kaminari-actionview (= 1.1.1) - kaminari-activerecord (= 1.1.1) - kaminari-core (= 1.1.1) - kaminari-actionview (1.1.1) + kaminari-actionview (= 1.2.0) + kaminari-activerecord (= 1.2.0) + kaminari-core (= 1.2.0) + kaminari-actionview (1.2.0) actionview - kaminari-core (= 1.1.1) - kaminari-activerecord (1.1.1) + kaminari-core (= 1.2.0) + kaminari-activerecord (1.2.0) activerecord - kaminari-core (= 1.1.1) - kaminari-core (1.1.1) - launchy (2.4.3) - addressable (~> 2.3) + kaminari-core (= 1.2.0) + kaminari-core (1.2.0) + launchy (2.5.0) + addressable (~> 2.7) letter_opener (1.7.0) launchy (~> 2.2) letter_opener_web (1.4.0) @@ -353,14 +353,14 @@ GEM mario-redis-lock (1.2.1) redis (>= 3.0.5) memory_profiler (0.9.14) - method_source (0.9.2) + method_source (1.0.0) microformats (4.2.0) json (~> 2.2) nokogiri (~> 1.10) mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2020.0425) - mimemagic (0.3.4) + mimemagic (0.3.5) mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.14.0) @@ -369,9 +369,9 @@ GEM multipart-post (2.1.1) necromancer (0.5.1) net-ldap (0.16.2) - net-scp (2.0.0) - net-ssh (>= 2.6.5, < 6.0.0) - net-ssh (5.2.0) + net-scp (3.0.0) + net-ssh (>= 2.6.5, < 7.0.0) + net-ssh (6.0.2) nio4r (2.5.2) nokogiri (1.10.9) mini_portile2 (~> 2.4.0) @@ -407,40 +407,40 @@ GEM parallel (1.19.1) parallel_tests (2.32.0) parallel - parser (2.7.1.1) + parser (2.7.1.2) ast (~> 2.4.0) parslet (2.0.0) - pastel (0.7.3) + pastel (0.7.4) equatable (~> 0.6) tty-color (~> 0.5) pg (1.2.3) - pghero (2.4.1) + pghero (2.4.2) activerecord (>= 5) pkg-config (1.4.1) premailer (1.11.1) addressable css_parser (>= 1.6.0) htmlentities (>= 4.0.0) - premailer-rails (1.10.3) + premailer-rails (1.11.1) actionmailer (>= 3) premailer (~> 1.7, >= 1.7.9) private_address_check (0.5.0) - pry (0.12.2) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - pry-byebug (3.8.0) + pry (0.13.1) + coderay (~> 1.1) + method_source (~> 1.0) + pry-byebug (3.9.0) byebug (~> 11.0) - pry (~> 0.10) + pry (~> 0.13.0) pry-rails (0.3.9) pry (>= 0.10.4) - public_suffix (4.0.4) + public_suffix (4.0.5) puma (4.3.3) nio4r (~> 2.0) pundit (2.1.0) activesupport (>= 3.0.0) - raabro (1.1.6) + raabro (1.3.1) rack (2.2.2) - rack-attack (6.2.2) + rack-attack (6.3.0) rack (>= 1.0, < 3) rack-cors (1.1.1) rack (>= 2.0.0) @@ -491,13 +491,13 @@ GEM rdf-normalize (0.4.0) rdf (~> 3.1) redcarpet (3.5.0) - redis (4.1.3) + redis (4.1.4) redis-actionpack (5.2.0) actionpack (>= 5, < 7) redis-rack (>= 2.1.0, < 3) redis-store (>= 1.1.0, < 2) - redis-activesupport (5.0.4) - activesupport (>= 3, < 6) + redis-activesupport (5.2.0) + activesupport (>= 3, < 7) redis-store (>= 1.3, < 2) redis-namespace (1.7.0) redis (>= 3.0.4) @@ -516,15 +516,16 @@ GEM responders (3.0.0) actionpack (>= 5.0) railties (>= 5.0) + rexml (3.2.4) rotp (2.1.2) rpam2 (4.0.2) rqrcode (1.1.2) chunky_png (~> 1.0) rqrcode_core (~> 0.1) rqrcode_core (0.1.2) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) - rspec-expectations (3.9.1) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) rspec-mocks (3.9.1) @@ -541,16 +542,17 @@ GEM rspec-sidekiq (3.0.3) rspec-core (~> 3.0, >= 3.0.0) sidekiq (>= 2.4.0) - rspec-support (3.9.2) + rspec-support (3.9.3) rspec_junit_formatter (0.4.1) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.79.0) + rubocop (0.82.0) jaro_winkler (~> 1.5.1) parallel (~> 1.10) parser (>= 2.7.0.1) rainbow (>= 2.2.2, < 4.0) + rexml ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) + unicode-display_width (>= 1.4.0, < 2.0) rubocop-rails (2.5.2) activesupport rack (>= 1.1) @@ -565,9 +567,10 @@ GEM crass (~> 1.0.2) nokogiri (>= 1.8.0) nokogumbo (~> 2.0) - sidekiq (6.0.4) + semantic_range (2.3.0) + sidekiq (6.0.7) connection_pool (>= 2.2.2) - rack (>= 2.0.0) + rack (~> 2.0) rack-protection (>= 2.0.0) redis (>= 4.1.0) sidekiq-bulk (0.2.0) @@ -607,7 +610,7 @@ GEM stoplight (2.2.0) streamio-ffmpeg (3.0.2) multi_json (~> 1.8) - strong_migrations (0.6.2) + strong_migrations (0.6.6) activerecord (>= 5) temple (0.8.2) terminal-table (1.8.0) @@ -635,12 +638,12 @@ GEM unf (~> 0.1.0) tzinfo (1.2.7) thread_safe (~> 0.1) - tzinfo-data (1.2019.3) + tzinfo-data (1.2020.1) tzinfo (>= 1.0.0) unf (0.1.4) unf_ext - unf_ext (0.0.7.6) - unicode-display_width (1.6.1) + unf_ext (0.0.7.7) + unicode-display_width (1.7.0) uniform_notifier (1.13.0) warden (1.2.8) rack (>= 2.0.6) @@ -648,10 +651,11 @@ GEM addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webpacker (4.2.2) - activesupport (>= 4.2) + webpacker (5.1.1) + activesupport (>= 5.2) rack-proxy (>= 0.6.1) - railties (>= 4.2) + railties (>= 5.2) + semantic_range (>= 2.3.0) webpush (0.3.8) hkdf (~> 0.2) jwt (~> 2.0) @@ -670,8 +674,8 @@ DEPENDENCIES active_record_query_trace (~> 1.7) addressable (~> 2.7) annotate (~> 3.1) - aws-sdk-s3 (~> 1.63) - better_errors (~> 2.6) + aws-sdk-s3 (~> 1.64) + better_errors (~> 2.7) binding_of_caller (~> 0.7) blurhash (~> 0.1) bootsnap (~> 1.4) @@ -679,11 +683,11 @@ DEPENDENCIES browser bullet (~> 6.1) bundler-audit (~> 0.6) - capistrano (~> 3.13) + capistrano (~> 3.14) capistrano-rails (~> 1.4) capistrano-rbenv (~> 2.1) capistrano-yarn (~> 2.0) - capybara (~> 3.31) + capybara (~> 3.32) charlock_holmes (~> 0.7.7) chewy (~> 5.1) cld3 (~> 3.3.0) @@ -694,7 +698,7 @@ DEPENDENCIES devise-two-factor (~> 3.1) devise_pam_authenticatable2 (~> 9.2) discard (~> 1.2) - doorkeeper (~> 5.3) + doorkeeper (~> 5.4) dotenv-rails (~> 2.7) e2mmap (~> 0.1.0) fabrication (~> 2.21) @@ -709,7 +713,7 @@ DEPENDENCIES health_check! hiredis (~> 0.6) htmlentities (~> 4.3) - http (~> 4.3) + http (~> 4.4) http_accept_language (~> 2.1) http_parser.rb (~> 0.6)! httplog (~> 1.4.2) @@ -718,7 +722,7 @@ DEPENDENCIES iso-639 json-ld json-ld-preloaded (~> 3.1) - kaminari (~> 1.1) + kaminari (~> 1.2) letter_opener (~> 1.7) letter_opener_web (~> 1.4) link_header (~> 0.0) @@ -748,12 +752,12 @@ DEPENDENCIES posix-spawn! premailer-rails private_address_check (~> 0.5) - pry-byebug (~> 3.8) + pry-byebug (~> 3.9) pry-rails (~> 0.3) puma (~> 4.3) pundit (~> 2.1) rack (~> 2.2.2) - rack-attack (~> 6.2) + rack-attack (~> 6.3) rack-cors (~> 1.1) rails (~> 5.2.4.2) rails-controller-testing (~> 1.0) @@ -768,7 +772,7 @@ DEPENDENCIES rspec-rails (~> 4.0) rspec-sidekiq (~> 3.0) rspec_junit_formatter (~> 0.4) - rubocop (~> 0.79) + rubocop (~> 0.82) rubocop-rails (~> 2.5) ruby-progressbar (~> 1.10) sanitize (~> 5.1) @@ -790,7 +794,7 @@ DEPENDENCIES tty-command (~> 0.9) tty-prompt (~> 0.21) twitter-text (~> 1.14) - tzinfo-data (~> 1.2019) + tzinfo-data (~> 1.2020) webmock (~> 3.8) - webpacker (~> 4.2) + webpacker (~> 5.1) webpush diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 52d09cff8..e3d8c1061 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -41,7 +41,7 @@ class AccountsController < ApplicationController format.rss do expires_in 1.minute, public: true - @statuses = filtered_statuses.without_reblogs.without_replies.limit(PAGE_SIZE) + @statuses = filtered_statuses.without_reblogs.limit(PAGE_SIZE) @statuses = cache_collection(@statuses, Status) render xml: RSS::AccountSerializer.render(@account, @statuses, params[:tag]) end @@ -130,11 +130,11 @@ class AccountsController < ApplicationController end def media_requested? - request.path.ends_with?('/media') && !tag_requested? + request.path.split('.').first.ends_with?('/media') && !tag_requested? end def replies_requested? - request.path.ends_with?('/with_replies') && !tag_requested? + request.path.split('.').first.ends_with?('/with_replies') && !tag_requested? end def tag_requested? diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb index 1daa1ed0d..2277067c9 100644 --- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb @@ -20,7 +20,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController return [] if hide_results? scope = default_accounts - scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil? + scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil? || current_account.id == @account.id scope.merge(paginated_follows).to_a end diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb index 6fc23cf75..93d4bd3a4 100644 --- a/app/controllers/api/v1/accounts/following_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb @@ -20,7 +20,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController return [] if hide_results? scope = default_accounts - scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil? + scope = scope.where.not(id: current_account.excluded_from_timeline_account_ids) unless current_account.nil? || current_account.id == @account.id scope.merge(paginated_follows).to_a end diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb index 581befef1..c6e7854d9 100644 --- a/app/controllers/api/v1/timelines/public_controller.rb +++ b/app/controllers/api/v1/timelines/public_controller.rb @@ -39,7 +39,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController end def public_timeline_statuses - Status.as_public_timeline(current_account, truthy_param?(:local)) + Status.as_public_timeline(current_account, truthy_param?(:remote) ? :remote : truthy_param?(:local)) end def insert_pagination_headers @@ -47,7 +47,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController end def pagination_params(core_params) - params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params) + params.slice(:local, :remote, :limit, :only_media).permit(:local, :remote, :limit, :only_media).merge(core_params) end def next_path diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index eac9dde6f..c36561b86 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -113,6 +113,13 @@ class Auth::SessionsController < Devise::SessionsController render :two_factor end + def require_no_authentication + super + # Delete flash message that isn't entirely useful and may be confusing in + # most cases because /web doesn't display/clear flash messages. + flash.delete(:alert) if flash[:alert] == I18n.t('devise.failure.already_authenticated') + end + private def set_pack diff --git a/app/controllers/concerns/localized.rb b/app/controllers/concerns/localized.rb index b43859d9d..d1384ed56 100644 --- a/app/controllers/concerns/localized.rb +++ b/app/controllers/concerns/localized.rb @@ -28,18 +28,6 @@ module Localized end def request_locale - preferred_locale || compatible_locale - end - - def preferred_locale - http_accept_language.preferred_language_from(available_locales) - end - - def compatible_locale - http_accept_language.compatible_language_from(available_locales) - end - - def available_locales - I18n.available_locales.reverse + http_accept_language.language_region_compatible_from(I18n.available_locales) end end diff --git a/app/controllers/settings/identity_proofs_controller.rb b/app/controllers/settings/identity_proofs_controller.rb index e84c1aca6..b217b3c3b 100644 --- a/app/controllers/settings/identity_proofs_controller.rb +++ b/app/controllers/settings/identity_proofs_controller.rb @@ -22,8 +22,7 @@ class Settings::IdentityProofsController < Settings::BaseController if current_account.username.casecmp(params[:username]).zero? render layout: 'auth' else - flash[:alert] = I18n.t('identity_proofs.errors.wrong_user', proving: params[:username], current: current_account.username) - redirect_to settings_identity_proofs_path + redirect_to settings_identity_proofs_path, alert: I18n.t('identity_proofs.errors.wrong_user', proving: params[:username], current: current_account.username) end end @@ -35,11 +34,16 @@ class Settings::IdentityProofsController < Settings::BaseController PostStatusService.new.call(current_user.account, text: post_params[:status_text]) if publish_proof? redirect_to @proof.on_success_path(params[:user_agent]) else - flash[:alert] = I18n.t('identity_proofs.errors.failed', provider: @proof.provider.capitalize) - redirect_to settings_identity_proofs_path + redirect_to settings_identity_proofs_path, alert: I18n.t('identity_proofs.errors.failed', provider: @proof.provider.capitalize) end end + def destroy + @proof = current_account.identity_proofs.find(params[:id]) + @proof.destroy! + redirect_to settings_identity_proofs_path, success: I18n.t('identity_proofs.removed') + end + private def check_enabled diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb index b66e827fe..4da68500a 100644 --- a/app/helpers/home_helper.rb +++ b/app/helpers/home_helper.rb @@ -7,13 +7,13 @@ module HomeHelper } end - def account_link_to(account, button = '', size: 36, path: nil) + def account_link_to(account, button = '', path: nil) content_tag(:div, class: 'account') do content_tag(:div, class: 'account__wrapper') do section = if account.nil? content_tag(:div, class: 'account__display-name') do content_tag(:div, class: 'account__avatar-wrapper') do - content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)})") + image_tag(full_asset_url('avatars/original/missing.png', skip_pipeline: true), class: 'account__avatar') end + content_tag(:span, class: 'display-name') do content_tag(:strong, t('about.contact_missing')) + @@ -23,7 +23,7 @@ module HomeHelper else link_to(path || ActivityPub::TagManager.instance.url_for(account), class: 'account__display-name') do content_tag(:div, class: 'account__avatar-wrapper') do - content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{full_asset_url(current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url)})") + image_tag(full_asset_url(current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url), class: 'account__avatar') end + content_tag(:span, class: 'display-name') do content_tag(:bdi) do diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 74544bad9..87718dc05 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -68,6 +68,7 @@ module SettingsHelper tr: 'Türkçe', uk: 'Українська', ur: 'اُردُو', + vi: 'Tiếng Việt', 'zh-CN': '简体中文', 'zh-HK': '繁體中文(香港)', 'zh-TW': '繁體中文(臺灣)', diff --git a/app/helpers/webfinger_helper.rb b/app/helpers/webfinger_helper.rb new file mode 100644 index 000000000..70c493210 --- /dev/null +++ b/app/helpers/webfinger_helper.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module WebfingerHelper + def webfinger!(uri) + hidden_service_uri = /\.(onion|i2p)(:\d+)?$/.match(uri) + + raise Mastodon::HostValidationError, 'Instance does not support hidden service connections' if !Rails.configuration.x.access_to_hidden_service && hidden_service_uri + + opts = { + ssl: !hidden_service_uri, + + headers: { + 'User-Agent': Mastodon::Version.user_agent, + }, + } + + Goldfinger::Client.new(uri, opts.merge(Rails.configuration.x.http_client_proxy)).finger + end +end diff --git a/app/javascript/flavours/glitch/actions/streaming.js b/app/javascript/flavours/glitch/actions/streaming.js index 2f82ea805..875013efc 100644 --- a/app/javascript/flavours/glitch/actions/streaming.js +++ b/app/javascript/flavours/glitch/actions/streaming.js @@ -73,7 +73,7 @@ const refreshHomeTimelineAndNotification = (dispatch, done) => { export const connectUserStream = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification); export const connectCommunityStream = ({ onlyMedia } = {}) => connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`); -export const connectPublicStream = ({ onlyMedia } = {}) => connectTimelineStream(`public${onlyMedia ? ':media' : ''}`, `public${onlyMedia ? ':media' : ''}`); +export const connectPublicStream = ({ onlyMedia, onlyRemote } = {}) => connectTimelineStream(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, `public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`); export const connectHashtagStream = (id, tag, accept) => connectTimelineStream(`hashtag:${id}`, `hashtag&tag=${tag}`, null, accept); export const connectDirectStream = () => connectTimelineStream('direct', 'direct'); export const connectListStream = id => connectTimelineStream(`list:${id}`, `list&list=${id}`); diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js index 50e36531e..b01109134 100644 --- a/app/javascript/flavours/glitch/actions/timelines.js +++ b/app/javascript/flavours/glitch/actions/timelines.js @@ -121,7 +121,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) { }; export const expandHomeTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('home', '/api/v1/timelines/home', { max_id: maxId }, done); -export const expandPublicTimeline = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`public${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { max_id: maxId, only_media: !!onlyMedia }, done); +export const expandPublicTimeline = ({ maxId, onlyMedia, onlyRemote } = {}, done = noOp) => expandTimeline(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { remote: !!onlyRemote, max_id: maxId, only_media: !!onlyMedia }, done); export const expandCommunityTimeline = ({ maxId, onlyMedia } = {}, done = noOp) => expandTimeline(`community${onlyMedia ? ':media' : ''}`, '/api/v1/timelines/public', { local: true, max_id: maxId, only_media: !!onlyMedia }, done); export const expandDirectTimeline = ({ maxId } = {}, done = noOp) => expandTimeline('direct', '/api/v1/timelines/direct', { max_id: maxId }, done); export const expandAccountTimeline = (accountId, { maxId, withReplies } = {}) => expandTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies, max_id: maxId }); diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index fb0f165ff..c7b54649c 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -186,10 +186,12 @@ class Header extends ImmutablePureComponent { menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' }); } else { if (account.getIn(['relationship', 'following'])) { - if (account.getIn(['relationship', 'showing_reblogs'])) { - menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); - } else { - menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); + if (!account.getIn(['relationship', 'muting'])) { + if (account.getIn(['relationship', 'showing_reblogs'])) { + menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); + } else { + menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); + } } menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle }); diff --git a/app/javascript/flavours/glitch/features/compose/components/poll_form.js b/app/javascript/flavours/glitch/features/compose/components/poll_form.js index 57fac10ac..e4b5104f3 100644 --- a/app/javascript/flavours/glitch/features/compose/components/poll_form.js +++ b/app/javascript/flavours/glitch/features/compose/components/poll_form.js @@ -28,6 +28,7 @@ class Option extends React.PureComponent { title: PropTypes.string.isRequired, index: PropTypes.number.isRequired, isPollMultiple: PropTypes.bool, + autoFocus: PropTypes.bool, onChange: PropTypes.func.isRequired, onRemove: PropTypes.func.isRequired, suggestions: ImmutablePropTypes.list, @@ -58,7 +59,7 @@ class Option extends React.PureComponent { } render () { - const { isPollMultiple, title, index, intl } = this.props; + const { isPollMultiple, title, index, autoFocus, intl } = this.props; return (
  • @@ -75,6 +76,7 @@ class Option extends React.PureComponent { onSuggestionsClearRequested={this.onSuggestionsClearRequested} onSuggestionSelected={this.onSuggestionSelected} searchTokens={[':']} + autoFocus={autoFocus} /> @@ -125,10 +127,12 @@ class PollForm extends ImmutablePureComponent { return null; } + const autoFocusIndex = options.indexOf(''); + return (