about summary refs log tree commit diff
path: root/app/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/about_controller.rb34
-rw-r--r--app/controllers/accounts_controller.rb17
-rw-r--r--app/controllers/activitypub/replies_controller.rb11
-rw-r--r--app/controllers/application_controller.rb7
-rw-r--r--app/controllers/concerns/signature_verification.rb15
-rw-r--r--app/controllers/follower_accounts_controller.rb2
-rw-r--r--app/controllers/following_accounts_controller.rb2
-rw-r--r--app/controllers/home_controller.rb16
-rw-r--r--app/controllers/instance_actors_controller.rb2
-rw-r--r--app/controllers/invites_controller.rb2
-rw-r--r--app/controllers/media_proxy_controller.rb2
-rw-r--r--app/controllers/public_timelines_controller.rb7
-rw-r--r--app/controllers/shares_controller.rb18
-rw-r--r--app/controllers/tags_controller.rb5
14 files changed, 84 insertions, 56 deletions
diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb
index f41e52aae..5003ae61c 100644
--- a/app/controllers/about_controller.rb
+++ b/app/controllers/about_controller.rb
@@ -4,10 +4,12 @@ class AboutController < ApplicationController
   before_action :set_pack
   layout 'public'
 
-  before_action :require_open_federation!, only: [:show, :more]
+  before_action :require_open_federation!, only: [:show, :more, :blocks]
+  before_action :check_blocklist_enabled, only: [:blocks]
+  before_action :authenticate_user!, only: [:blocks], if: :blocklist_account_required?
   before_action :set_body_classes, only: :show
   before_action :set_instance_presenter
-  before_action :set_expires_in
+  before_action :set_expires_in, only: [:show, :more, :terms]
 
   skip_before_action :require_functional!, only: [:more, :terms]
 
@@ -19,12 +21,40 @@ class AboutController < ApplicationController
 
   def terms; end
 
+  def blocks
+    @show_rationale = Setting.show_domain_blocks_rationale == 'all'
+    @show_rationale |= Setting.show_domain_blocks_rationale == 'users' && !current_user.nil? && current_user.functional?
+    @blocks = DomainBlock.with_user_facing_limitations.order('(CASE severity WHEN 0 THEN 1 WHEN 1 THEN 2 WHEN 2 THEN 0 END), reject_media, domain').to_a
+  end
+
   private
 
   def require_open_federation!
     not_found if whitelist_mode?
   end
 
+  def check_blocklist_enabled
+    not_found if Setting.show_domain_blocks == 'disabled'
+  end
+
+  def blocklist_account_required?
+    Setting.show_domain_blocks == 'users'
+  end
+
+  def block_severity_text(block)
+    if block.severity == 'suspend'
+      I18n.t('domain_blocks.suspension')
+    else
+      limitations = []
+      limitations << I18n.t('domain_blocks.media_block') if block.reject_media?
+      limitations << I18n.t('domain_blocks.silence') if block.severity == 'silence'
+      limitations.join(', ')
+    end
+  end
+
+  helper_method :block_severity_text
+  helper_method :public_fetch_mode?
+
   def new_user
     User.new.tap do |user|
       user.build_account
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index 1a876b831..817e5e832 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -19,6 +19,7 @@ class AccountsController < ApplicationController
 
         @pinned_statuses   = []
         @endorsed_accounts = @account.endorsed_accounts.to_a.sample(4)
+        @featured_hashtags = @account.featured_tags.order(statuses_count: :desc)
 
         if current_account && @account.blocking?(current_account)
           @statuses = []
@@ -28,6 +29,7 @@ class AccountsController < ApplicationController
         @pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
         @statuses        = filtered_status_page(params)
         @statuses        = cache_collection(@statuses, Status)
+        @rss_url         = rss_url
 
         unless @statuses.empty?
           @older_url = older_url if @statuses.last.id > filtered_statuses.last.id
@@ -38,8 +40,9 @@ class AccountsController < ApplicationController
       format.rss do
         expires_in 0, public: true
 
-        @statuses = cache_collection(default_statuses.without_reblogs.without_replies.limit(PAGE_SIZE), Status)
-        render xml: RSS::AccountSerializer.render(@account, @statuses)
+        @statuses = filtered_statuses.without_reblogs.without_replies.limit(PAGE_SIZE)
+        @statuses = cache_collection(@statuses, Status)
+        render xml: RSS::AccountSerializer.render(@account, @statuses, params[:tag])
       end
 
       format.json do
@@ -97,6 +100,14 @@ class AccountsController < ApplicationController
     params[:username]
   end
 
+  def rss_url
+    if tag_requested?
+      short_account_tag_url(@account, params[:tag], format: 'rss')
+    else
+      short_account_url(@account, format: 'rss')
+    end
+  end
+
   def older_url
     pagination_url(max_id: @statuses.last.id)
   end
@@ -126,7 +137,7 @@ class AccountsController < ApplicationController
   end
 
   def tag_requested?
-    request.path.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
+    request.path.split('.').first.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
   end
 
   def filtered_status_page(params)
diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb
index ab755ed4e..c62061555 100644
--- a/app/controllers/activitypub/replies_controller.rb
+++ b/app/controllers/activitypub/replies_controller.rb
@@ -27,7 +27,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
   end
 
   def set_replies
-    @replies = page_params[:other_accounts] ? Status.where.not(account_id: @account.id) : @account.statuses
+    @replies = page_params[:only_other_accounts] ? Status.where.not(account_id: @account.id) : @account.statuses
     @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
     @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
   end
@@ -38,7 +38,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
       type: :unordered,
       part_of: account_status_replies_url(@account, @status),
       next: next_page,
-      items: @replies.map { |status| status.local ? status : status.id }
+      items: @replies.map { |status| status.local ? status : status.uri }
     )
 
     return page if page_requested?
@@ -55,16 +55,17 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
   end
 
   def next_page
+    only_other_accounts = !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
     account_status_replies_url(
       @account,
       @status,
       page: true,
-      min_id: @replies&.last&.id,
-      other_accounts: !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
+      min_id: only_other_accounts && !page_params[:only_other_accounts] ? nil : @replies&.last&.id,
+      only_other_accounts: only_other_accounts
     )
   end
 
   def page_params
-    params_slice(:other_accounts, :min_id).merge(page: true)
+    params_slice(:only_other_accounts, :min_id).merge(page: true)
   end
 end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 19efc8838..5f88838e4 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -26,10 +26,13 @@ class ApplicationController < ActionController::Base
   rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
   rescue_from ActionController::UnknownFormat, with: :not_acceptable
   rescue_from Mastodon::NotPermittedError, with: :forbidden
+  rescue_from HTTP::Error, OpenSSL::SSL::SSLError, with: :internal_server_error
 
   before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
   before_action :require_functional!, if: :user_signed_in?
 
+  skip_before_action :verify_authenticity_token, only: :raise_not_found
+
   def raise_not_found
     raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}"
   end
@@ -163,6 +166,10 @@ class ApplicationController < ActionController::Base
     respond_with_error(406)
   end
 
+  def internal_server_error
+    respond_with_error(500)
+  end
+
   def single_user_mode?
     @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.where('id > 0').exists?
   end
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 7b251cf80..ce353f1de 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -23,6 +23,19 @@ module SignatureVerification
     @signature_verification_failure_code || 401
   end
 
+  def signature_key_id
+    raw_signature    = request.headers['Signature']
+    signature_params = {}
+
+    raw_signature.split(',').each do |part|
+      parsed_parts = part.match(/([a-z]+)="([^"]+)"/i)
+      next if parsed_parts.nil? || parsed_parts.size != 3
+      signature_params[parsed_parts[1]] = parsed_parts[2]
+    end
+
+    signature_params['keyId']
+  end
+
   def signed_request_account
     return @signed_request_account if defined?(@signed_request_account)
 
@@ -154,7 +167,7 @@ module SignatureVerification
       .with_fallback { nil }
       .with_threshold(1)
       .with_cool_off_time(5.minutes.seconds)
-      .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) }
+      .with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) }
       .run
   end
 
diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb
index e2ba9bf00..4641a8bb9 100644
--- a/app/controllers/follower_accounts_controller.rb
+++ b/app/controllers/follower_accounts_controller.rb
@@ -7,6 +7,8 @@ class FollowerAccountsController < ApplicationController
   before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
   before_action :set_cache_headers
 
+  skip_around_action :set_locale, if: -> { request.format == :json }
+
   def index
     respond_to do |format|
       format.html do
diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb
index 49f1f3218..6e80554fb 100644
--- a/app/controllers/following_accounts_controller.rb
+++ b/app/controllers/following_accounts_controller.rb
@@ -7,6 +7,8 @@ class FollowingAccountsController < ApplicationController
   before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
   before_action :set_cache_headers
 
+  skip_around_action :set_locale, if: -> { request.format == :json }
+
   def index
     respond_to do |format|
       format.html do
diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
index a09aed801..efdb1d226 100644
--- a/app/controllers/home_controller.rb
+++ b/app/controllers/home_controller.rb
@@ -5,7 +5,6 @@ class HomeController < ApplicationController
 
   before_action :set_pack
   before_action :set_referrer_policy_header
-  before_action :set_initial_state_json
 
   def index
     @body_classes = 'app-body'
@@ -45,21 +44,6 @@ class HomeController < ApplicationController
     use_pack 'home'
   end
 
-  def set_initial_state_json
-    serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
-    @initial_state_json   = serializable_resource.to_json
-  end
-
-  def initial_state_params
-    {
-      settings: Web::Setting.find_by(user: current_user)&.data || {},
-      push_subscription: current_account.user.web_push_subscription(current_session),
-      current_account: current_account,
-      token: current_session.token,
-      admin: Account.find_local(Setting.site_contact_username.strip.gsub(/\A@/, '')),
-    }
-  end
-
   def default_redirect_path
     if request.path.start_with?('/web') || whitelist_mode?
       new_user_session_path
diff --git a/app/controllers/instance_actors_controller.rb b/app/controllers/instance_actors_controller.rb
index 41f33602e..6f02d6a35 100644
--- a/app/controllers/instance_actors_controller.rb
+++ b/app/controllers/instance_actors_controller.rb
@@ -3,6 +3,8 @@
 class InstanceActorsController < ApplicationController
   include AccountControllerConcern
 
+  skip_around_action :set_locale
+
   def show
     expires_in 10.minutes, public: true
     render json: @account, content_type: 'application/activity+json', serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter, fields: restrict_fields_to
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 639002964..0b3c082dc 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -48,7 +48,7 @@ class InvitesController < ApplicationController
   end
 
   def resource_params
-    params.require(:invite).permit(:max_uses, :expires_in, :autofollow)
+    params.require(:invite).permit(:max_uses, :expires_in, :autofollow, :comment)
   end
 
   def set_body_classes
diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb
index 8da6c6fe0..558cd6e30 100644
--- a/app/controllers/media_proxy_controller.rb
+++ b/app/controllers/media_proxy_controller.rb
@@ -7,6 +7,8 @@ class MediaProxyController < ApplicationController
 
   before_action :authenticate_user!, if: :whitelist_mode?
 
+  rescue_from ActiveRecord::RecordInvalid, with: :not_found
+
   def show
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
diff --git a/app/controllers/public_timelines_controller.rb b/app/controllers/public_timelines_controller.rb
index 940b2f7cd..eb5bb191b 100644
--- a/app/controllers/public_timelines_controller.rb
+++ b/app/controllers/public_timelines_controller.rb
@@ -9,12 +9,7 @@ class PublicTimelinesController < ApplicationController
   before_action :set_body_classes
   before_action :set_instance_presenter
 
-  def show
-    @initial_state_json = ActiveModelSerializers::SerializableResource.new(
-      InitialStatePresenter.new(settings: { known_fediverse: Setting.show_known_fediverse_at_about_page }, token: current_session&.token),
-      serializer: InitialStateSerializer
-    ).to_json
-  end
+  def show; end
 
   private
 
diff --git a/app/controllers/shares_controller.rb b/app/controllers/shares_controller.rb
index ada4eec54..e13e7e8b6 100644
--- a/app/controllers/shares_controller.rb
+++ b/app/controllers/shares_controller.rb
@@ -7,26 +7,10 @@ class SharesController < ApplicationController
   before_action :set_pack
   before_action :set_body_classes
 
-  def show
-    serializable_resource = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(initial_state_params), serializer: InitialStateSerializer)
-    @initial_state_json   = serializable_resource.to_json
-  end
+  def show; end
 
   private
 
-  def initial_state_params
-    text = [params[:title], params[:text], params[:url]].compact.join(' ')
-
-    {
-      settings: Web::Setting.find_by(user: current_user)&.data || {},
-      push_subscription: current_account.user.web_push_subscription(current_session),
-      current_account: current_account,
-      token: current_session.token,
-      admin: Account.find_local(Setting.site_contact_username.strip.gsub(/\A@/, '')),
-      text: text,
-    }
-  end
-
   def set_pack
     use_pack 'share'
   end
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index d6bb28eb5..c447a3a2b 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -18,11 +18,6 @@ class TagsController < ApplicationController
       format.html do
         use_pack 'about'
         expires_in 0, public: true
-
-        @initial_state_json = ActiveModelSerializers::SerializableResource.new(
-          InitialStatePresenter.new(settings: {}, token: current_session&.token),
-          serializer: InitialStateSerializer
-        ).to_json
       end
 
       format.rss do