Merge tag 'v3.4.0' into hometown-dev
This commit is contained in:
@ -20,6 +20,7 @@ class AboutController < ApplicationController
|
||||
|
||||
toc_generator = TOCGenerator.new(@instance_presenter.site_extended_description)
|
||||
|
||||
@rules = Rule.ordered
|
||||
@contents = toc_generator.html
|
||||
@table_of_contents = toc_generator.toc
|
||||
@blocks = DomainBlock.with_user_facing_limitations.by_severity if display_blocks?
|
||||
|
||||
@ -85,11 +85,7 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
def only_media_scope
|
||||
Status.where(id: account_media_status_ids)
|
||||
end
|
||||
|
||||
def account_media_status_ids
|
||||
@account.media_attachments.attached.reorder(nil).select(:status_id).group(:status_id)
|
||||
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
|
||||
end
|
||||
|
||||
def no_replies_scope
|
||||
@ -143,15 +139,15 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
def media_requested?
|
||||
request.path.split('.').first.ends_with?('/media') && !tag_requested?
|
||||
request.path.split('.').first.end_with?('/media') && !tag_requested?
|
||||
end
|
||||
|
||||
def replies_requested?
|
||||
request.path.split('.').first.ends_with?('/with_replies') && !tag_requested?
|
||||
request.path.split('.').first.end_with?('/with_replies') && !tag_requested?
|
||||
end
|
||||
|
||||
def tag_requested?
|
||||
request.path.split('.').first.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
|
||||
request.path.split('.').first.end_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
|
||||
end
|
||||
|
||||
def cached_filtered_status_page
|
||||
|
||||
@ -5,7 +5,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
|
||||
include JsonLdHelper
|
||||
include AccountOwnedConcern
|
||||
|
||||
before_action :skip_unknown_actor_delete
|
||||
before_action :skip_unknown_actor_activity
|
||||
before_action :require_signature!
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
@ -18,13 +18,13 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
|
||||
|
||||
private
|
||||
|
||||
def skip_unknown_actor_delete
|
||||
head 202 if unknown_deleted_account?
|
||||
def skip_unknown_actor_activity
|
||||
head 202 if unknown_affected_account?
|
||||
end
|
||||
|
||||
def unknown_deleted_account?
|
||||
def unknown_affected_account?
|
||||
json = Oj.load(body, mode: :strict)
|
||||
json.is_a?(Hash) && json['type'] == 'Delete' && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
|
||||
json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists?
|
||||
rescue Oj::ParseError
|
||||
false
|
||||
end
|
||||
|
||||
@ -20,7 +20,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
||||
def outbox_presenter
|
||||
if page_requested?
|
||||
ActivityPub::CollectionPresenter.new(
|
||||
id: outbox_url(page_params),
|
||||
id: outbox_url(**page_params),
|
||||
type: :ordered,
|
||||
part_of: outbox_url,
|
||||
prev: prev_page,
|
||||
|
||||
@ -4,6 +4,7 @@ require 'sidekiq/api'
|
||||
module Admin
|
||||
class DashboardController < BaseController
|
||||
def index
|
||||
@system_checks = Admin::SystemCheck.perform
|
||||
@users_count = User.count
|
||||
@pending_users_count = User.pending.count
|
||||
@registrations_week = Redis.current.get("activity:accounts:local:#{current_week}") || 0
|
||||
@ -34,7 +35,6 @@ module Admin
|
||||
@whitelist_enabled = whitelist_mode?
|
||||
@profile_directory = Setting.profile_directory
|
||||
@timeline_preview = Setting.timeline_preview
|
||||
@spam_check_enabled = Setting.spam_check_enabled
|
||||
@trends_enabled = Setting.trends
|
||||
end
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ module Admin
|
||||
if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block)
|
||||
@domain_block.save
|
||||
flash.now[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe # rubocop:disable Rails/OutputSafety
|
||||
@domain_block.errors[:domain].clear
|
||||
@domain_block.errors.delete(:domain)
|
||||
render :new
|
||||
else
|
||||
if existing_domain_block.present?
|
||||
|
||||
53
app/controllers/admin/follow_recommendations_controller.rb
Normal file
53
app/controllers/admin/follow_recommendations_controller.rb
Normal file
@ -0,0 +1,53 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class FollowRecommendationsController < BaseController
|
||||
before_action :set_language
|
||||
|
||||
def show
|
||||
authorize :follow_recommendation, :show?
|
||||
|
||||
@form = Form::AccountBatch.new
|
||||
@accounts = filtered_follow_recommendations
|
||||
end
|
||||
|
||||
def update
|
||||
@form = Form::AccountBatch.new(form_account_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||
@form.save
|
||||
rescue ActionController::ParameterMissing
|
||||
# Do nothing
|
||||
ensure
|
||||
redirect_to admin_follow_recommendations_path(filter_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_language
|
||||
@language = follow_recommendation_filter.language
|
||||
end
|
||||
|
||||
def filtered_follow_recommendations
|
||||
follow_recommendation_filter.results
|
||||
end
|
||||
|
||||
def follow_recommendation_filter
|
||||
@follow_recommendation_filter ||= FollowRecommendationFilter.new(filter_params)
|
||||
end
|
||||
|
||||
def form_account_batch_params
|
||||
params.require(:form_account_batch).permit(:action, account_ids: [])
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.slice(*FollowRecommendationFilter::KEYS).permit(*FollowRecommendationFilter::KEYS)
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
if params[:suppress]
|
||||
'suppress_follow_recommendation'
|
||||
elsif params[:unsuppress]
|
||||
'unsuppress_follow_recommendation'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -3,7 +3,8 @@
|
||||
module Admin
|
||||
class InstancesController < BaseController
|
||||
before_action :set_instances, only: :index
|
||||
before_action :set_instance, only: :show
|
||||
before_action :set_instance, except: :index
|
||||
before_action :set_exhausted_deliveries_days, only: :show
|
||||
|
||||
def index
|
||||
authorize :instance, :index?
|
||||
@ -13,14 +14,55 @@ module Admin
|
||||
authorize :instance, :show?
|
||||
end
|
||||
|
||||
def clear_delivery_errors
|
||||
authorize :delivery, :clear_delivery_errors?
|
||||
|
||||
@instance.delivery_failure_tracker.clear_failures!
|
||||
redirect_to admin_instance_path(@instance.domain)
|
||||
end
|
||||
|
||||
def restart_delivery
|
||||
authorize :delivery, :restart_delivery?
|
||||
|
||||
last_unavailable_domain = unavailable_domain
|
||||
|
||||
if last_unavailable_domain.present?
|
||||
@instance.delivery_failure_tracker.track_success!
|
||||
log_action :destroy, last_unavailable_domain
|
||||
end
|
||||
|
||||
redirect_to admin_instance_path(@instance.domain)
|
||||
end
|
||||
|
||||
def stop_delivery
|
||||
authorize :delivery, :stop_delivery?
|
||||
|
||||
UnavailableDomain.create(domain: @instance.domain)
|
||||
log_action :create, unavailable_domain
|
||||
redirect_to admin_instance_path(@instance.domain)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_instance
|
||||
@instance = Instance.find(params[:id])
|
||||
end
|
||||
|
||||
def set_exhausted_deliveries_days
|
||||
@exhausted_deliveries_days = @instance.delivery_failure_tracker.exhausted_deliveries_days
|
||||
end
|
||||
|
||||
def set_instances
|
||||
@instances = filtered_instances.page(params[:page])
|
||||
warning_domains_map = DeliveryFailureTracker.warning_domains_map
|
||||
|
||||
@instances.each do |instance|
|
||||
instance.failure_days = warning_domains_map[instance.domain]
|
||||
end
|
||||
end
|
||||
|
||||
def unavailable_domain
|
||||
UnavailableDomain.find_by(domain: @instance.domain)
|
||||
end
|
||||
|
||||
def filtered_instances
|
||||
|
||||
59
app/controllers/admin/rules_controller.rb
Normal file
59
app/controllers/admin/rules_controller.rb
Normal file
@ -0,0 +1,59 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class RulesController < BaseController
|
||||
before_action :set_rule, except: [:index, :create]
|
||||
|
||||
def index
|
||||
authorize :rule, :index?
|
||||
|
||||
@rules = Rule.ordered
|
||||
@rule = Rule.new
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :rule, :create?
|
||||
|
||||
@rule = Rule.new(resource_params)
|
||||
|
||||
if @rule.save
|
||||
redirect_to admin_rules_path
|
||||
else
|
||||
@rules = Rule.ordered
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @rule, :update?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @rule, :update?
|
||||
|
||||
if @rule.update(resource_params)
|
||||
redirect_to admin_rules_path
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @rule, :destroy?
|
||||
|
||||
@rule.discard
|
||||
|
||||
redirect_to admin_rules_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_rule
|
||||
@rule = Rule.find(params[:id])
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:rule).permit(:text, :priority)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -14,8 +14,7 @@ module Admin
|
||||
@statuses = @account.statuses.where(visibility: [:public, :unlisted])
|
||||
|
||||
if params[:media]
|
||||
account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).group(:status_id)
|
||||
@statuses.merge!(Status.where(id: account_media_status_ids))
|
||||
@statuses.merge!(Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id))
|
||||
end
|
||||
|
||||
@statuses = @statuses.preload(:media_attachments, :mentions).page(params[:page]).per(PER_PAGE)
|
||||
|
||||
@ -59,8 +59,8 @@ module Admin
|
||||
.where(Status.arel_table[:id].gteq(Mastodon::Snowflake.id_at(Time.now.utc.beginning_of_day)))
|
||||
.joins(:account)
|
||||
.group('accounts.domain')
|
||||
.reorder('statuses_count desc')
|
||||
.pluck('accounts.domain, count(*) AS statuses_count')
|
||||
.reorder(statuses_count: :desc)
|
||||
.pluck(Arel.sql('accounts.domain, count(*) AS statuses_count'))
|
||||
end
|
||||
|
||||
def set_counters
|
||||
|
||||
16
app/controllers/api/v1/accounts/lookup_controller.rb
Normal file
16
app/controllers/api/v1/accounts/lookup_controller.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::LookupController < Api::BaseController
|
||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }
|
||||
before_action :set_account
|
||||
|
||||
def show
|
||||
render json: @account, serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
@account = ResolveAccountService.new.call(params[:acct], skip_webfinger: true) || raise(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
@ -27,13 +27,15 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
|
||||
self.response_body = Oj.dump(response.body)
|
||||
self.status = response.status
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
render json: ValidationErrorFormatter.new(e, :'account.username' => :username, :'invite_request.text' => :reason).as_json, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def follow
|
||||
follow = FollowService.new.call(current_user.account, @account, reblogs: params.key?(:reblogs) ? truthy_param?(:reblogs) : nil, notify: params.key?(:notify) ? truthy_param?(:notify) : nil, with_rate_limit: true)
|
||||
options = @account.locked? || current_user.account.silenced? ? {} : { following_map: { @account.id => { reblogs: follow.show_reblogs?, notify: follow.notify? } }, requested_map: { @account.id => false } }
|
||||
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options)
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(**options)
|
||||
end
|
||||
|
||||
def block
|
||||
@ -42,7 +44,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
end
|
||||
|
||||
def mute
|
||||
MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: (params[:duration] || 0))
|
||||
MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: (params[:duration]&.to_i || 0))
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
|
||||
end
|
||||
|
||||
@ -68,7 +70,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
end
|
||||
|
||||
def relationships(**options)
|
||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
|
||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, **options)
|
||||
end
|
||||
|
||||
def account_params
|
||||
|
||||
@ -12,7 +12,7 @@ class Api::V1::Crypto::Keys::ClaimsController < Api::BaseController
|
||||
private
|
||||
|
||||
def set_claim_results
|
||||
@claim_results = devices.map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }.compact
|
||||
@claim_results = devices.filter_map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }
|
||||
end
|
||||
|
||||
def resource_params
|
||||
|
||||
@ -17,7 +17,7 @@ class Api::V1::Crypto::Keys::QueriesController < Api::BaseController
|
||||
end
|
||||
|
||||
def set_query_results
|
||||
@query_results = @accounts.map { |account| ::Keys::QueryService.new.call(account) }.compact
|
||||
@query_results = @accounts.filter_map { |account| ::Keys::QueryService.new.call(account) }
|
||||
end
|
||||
|
||||
def account_ids
|
||||
|
||||
21
app/controllers/api/v1/emails/confirmations_controller.rb
Normal file
21
app/controllers/api/v1/emails/confirmations_controller.rb
Normal file
@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Emails::ConfirmationsController < Api::BaseController
|
||||
before_action :doorkeeper_authorize!
|
||||
before_action :require_user_owned_by_application!
|
||||
|
||||
def create
|
||||
if !current_user.confirmed? && current_user.unconfirmed_email.present?
|
||||
current_user.update!(email: params[:email]) if params.key?(:email)
|
||||
current_user.resend_confirmation_instructions
|
||||
end
|
||||
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_user_owned_by_application!
|
||||
render json: { error: 'This method is only available to the application the user originally signed-up with' }, status: :forbidden unless current_user && current_user.created_by_application_id == doorkeeper_token.application_id
|
||||
end
|
||||
end
|
||||
@ -29,7 +29,7 @@ class Api::V1::FollowRequestsController < Api::BaseController
|
||||
end
|
||||
|
||||
def relationships(**options)
|
||||
AccountRelationshipsPresenter.new([params[:id]], current_user.account_id, options)
|
||||
AccountRelationshipsPresenter.new([params[:id]], current_user.account_id, **options)
|
||||
end
|
||||
|
||||
def load_accounts
|
||||
|
||||
17
app/controllers/api/v1/instances/rules_controller.rb
Normal file
17
app/controllers/api/v1/instances/rules_controller.rb
Normal file
@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Instances::RulesController < Api::BaseController
|
||||
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
|
||||
|
||||
before_action :set_rules
|
||||
|
||||
def index
|
||||
render json: @rules, each_serializer: REST::RuleSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_rules
|
||||
@rules = Rule.ordered
|
||||
end
|
||||
end
|
||||
@ -7,7 +7,7 @@ class Api::V1::MarkersController < Api::BaseController
|
||||
before_action :require_user!
|
||||
|
||||
def index
|
||||
@markers = current_user.markers.where(timeline: Array(params[:timeline])).each_with_object({}) { |marker, h| h[marker.timeline] = marker }
|
||||
@markers = current_user.markers.where(timeline: Array(params[:timeline])).index_by(&:timeline)
|
||||
render json: serialize_map(@markers)
|
||||
end
|
||||
|
||||
|
||||
@ -31,12 +31,13 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||
private
|
||||
|
||||
def load_notifications
|
||||
cache_collection_paginated_by_id(
|
||||
browserable_account_notifications,
|
||||
Notification,
|
||||
notifications = browserable_account_notifications.includes(from_account: :account_stat).to_a_paginated_by_id(
|
||||
limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
Notification.preload_cache_collection_target_statuses(notifications) do |target_statuses|
|
||||
cache_collection(target_statuses, Status)
|
||||
end
|
||||
end
|
||||
|
||||
def browserable_account_notifications
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
class Api::V1::Push::SubscriptionsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :push }
|
||||
before_action :require_user!
|
||||
before_action :set_web_push_subscription
|
||||
before_action :check_web_push_subscription, only: [:show, :update]
|
||||
before_action :set_push_subscription
|
||||
before_action :check_push_subscription, only: [:show, :update]
|
||||
|
||||
def create
|
||||
@web_subscription&.destroy!
|
||||
@push_subscription&.destroy!
|
||||
|
||||
@web_subscription = ::Web::PushSubscription.create!(
|
||||
@push_subscription = Web::PushSubscription.create!(
|
||||
endpoint: subscription_params[:endpoint],
|
||||
key_p256dh: subscription_params[:keys][:p256dh],
|
||||
key_auth: subscription_params[:keys][:auth],
|
||||
@ -18,31 +18,31 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
|
||||
access_token_id: doorkeeper_token.id
|
||||
)
|
||||
|
||||
render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@web_subscription.update!(data: data_params)
|
||||
render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
@push_subscription.update!(data: data_params)
|
||||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
@web_subscription&.destroy!
|
||||
@push_subscription&.destroy!
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_web_push_subscription
|
||||
@web_subscription = ::Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id)
|
||||
def set_push_subscription
|
||||
@push_subscription = Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id)
|
||||
end
|
||||
|
||||
def check_web_push_subscription
|
||||
not_found if @web_subscription.nil?
|
||||
def check_push_subscription
|
||||
not_found if @push_subscription.nil?
|
||||
end
|
||||
|
||||
def subscription_params
|
||||
@ -52,6 +52,6 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
|
||||
def data_params
|
||||
return {} if params[:data].blank?
|
||||
|
||||
params.require(:data).permit(alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll, :status])
|
||||
params.require(:data).permit(:policy, alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll, :status])
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,20 +5,20 @@ class Api::V1::SuggestionsController < Api::BaseController
|
||||
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!
|
||||
before_action :set_accounts
|
||||
|
||||
def index
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
suggestions = suggestions_source.get(current_account, limit: limit_param(DEFAULT_ACCOUNTS_LIMIT))
|
||||
render json: suggestions.map(&:account), each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
PotentialFriendshipTracker.remove(current_account.id, params[:id])
|
||||
suggestions_source.remove(current_account, params[:id])
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_accounts
|
||||
@accounts = PotentialFriendshipTracker.get(current_account.id, limit: limit_param(DEFAULT_ACCOUNTS_LIMIT))
|
||||
def suggestions_source
|
||||
AccountSuggestions::PastInteractionsSource.new
|
||||
end
|
||||
end
|
||||
|
||||
19
app/controllers/api/v2/suggestions_controller.rb
Normal file
19
app/controllers/api/v2/suggestions_controller.rb
Normal file
@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V2::SuggestionsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!
|
||||
before_action :set_suggestions
|
||||
|
||||
def index
|
||||
render json: @suggestions, each_serializer: REST::SuggestionSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_suggestions
|
||||
@suggestions = AccountSuggestions.get(current_account, limit_param(DEFAULT_ACCOUNTS_LIMIT))
|
||||
end
|
||||
end
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
||||
before_action :require_user!
|
||||
before_action :set_push_subscription, only: :update
|
||||
|
||||
def create
|
||||
active_session = current_session
|
||||
@ -15,9 +16,11 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
||||
alerts_enabled = active_session.detection.device.mobile? || active_session.detection.device.tablet?
|
||||
|
||||
data = {
|
||||
policy: 'all',
|
||||
|
||||
alerts: {
|
||||
follow: alerts_enabled,
|
||||
follow_request: false,
|
||||
follow_request: alerts_enabled,
|
||||
favourite: alerts_enabled,
|
||||
reblog: alerts_enabled,
|
||||
mention: alerts_enabled,
|
||||
@ -28,7 +31,7 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
||||
|
||||
data.deep_merge!(data_params) if params[:data]
|
||||
|
||||
web_subscription = ::Web::PushSubscription.create!(
|
||||
push_subscription = ::Web::PushSubscription.create!(
|
||||
endpoint: subscription_params[:endpoint],
|
||||
key_p256dh: subscription_params[:keys][:p256dh],
|
||||
key_auth: subscription_params[:keys][:auth],
|
||||
@ -37,27 +40,27 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
||||
access_token_id: active_session.access_token_id
|
||||
)
|
||||
|
||||
active_session.update!(web_push_subscription: web_subscription)
|
||||
active_session.update!(web_push_subscription: push_subscription)
|
||||
|
||||
render json: web_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
render json: push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
params.require([:id])
|
||||
|
||||
web_subscription = ::Web::PushSubscription.find(params[:id])
|
||||
web_subscription.update!(data: data_params)
|
||||
|
||||
render json: web_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
@push_subscription.update!(data: data_params)
|
||||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_push_subscription
|
||||
@push_subscription = ::Web::PushSubscription.find(params[:id])
|
||||
end
|
||||
|
||||
def subscription_params
|
||||
@subscription_params ||= params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
|
||||
end
|
||||
|
||||
def data_params
|
||||
@data_params ||= params.require(:data).permit(alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll, :status])
|
||||
@data_params ||= params.require(:data).permit(:policy, alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll, :status])
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,17 +2,16 @@
|
||||
|
||||
class Api::Web::SettingsController < Api::Web::BaseController
|
||||
before_action :require_user!
|
||||
before_action :set_setting
|
||||
|
||||
def update
|
||||
setting.data = params[:data]
|
||||
setting.save!
|
||||
|
||||
@setting.update!(data: params[:data])
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def setting
|
||||
@_setting ||= ::Web::Setting.where(user: current_user).first_or_initialize(user: current_user)
|
||||
def set_setting
|
||||
@setting = ::Web::Setting.where(user: current_user).first_or_initialize(user: current_user)
|
||||
end
|
||||
end
|
||||
|
||||
@ -5,8 +5,6 @@ class ApplicationController < ActionController::Base
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
force_ssl if: :https_enabled?
|
||||
|
||||
include Localized
|
||||
include UserTrackingConcern
|
||||
include SessionTrackingConcern
|
||||
@ -20,17 +18,16 @@ class ApplicationController < ActionController::Base
|
||||
helper_method :use_seamless_external_login?
|
||||
helper_method :whitelist_mode?
|
||||
|
||||
rescue_from ActionController::RoutingError, with: :not_found
|
||||
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
|
||||
rescue_from ActionController::UnknownFormat, with: :not_acceptable
|
||||
rescue_from ActionController::ParameterMissing, with: :bad_request
|
||||
rescue_from Paperclip::AdapterRegistry::NoHandlerError, with: :bad_request
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||
rescue_from ActionController::ParameterMissing, Paperclip::AdapterRegistry::NoHandlerError, with: :bad_request
|
||||
rescue_from Mastodon::NotPermittedError, with: :forbidden
|
||||
rescue_from HTTP::Error, OpenSSL::SSL::SSLError, with: :internal_server_error
|
||||
rescue_from Mastodon::RaceConditionError, Seahorse::Client::NetworkingError, Stoplight::Error::RedLight, with: :service_unavailable
|
||||
rescue_from ActionController::RoutingError, ActiveRecord::RecordNotFound, with: :not_found
|
||||
rescue_from ActionController::UnknownFormat, with: :not_acceptable
|
||||
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
|
||||
rescue_from Mastodon::RateLimitExceededError, with: :too_many_requests
|
||||
|
||||
rescue_from HTTP::Error, OpenSSL::SSL::SSLError, with: :internal_server_error
|
||||
rescue_from Mastodon::RaceConditionError, Seahorse::Client::NetworkingError, Stoplight::Error::RedLight, ActiveRecord::SerializationFailure, with: :service_unavailable
|
||||
|
||||
before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
|
||||
before_action :require_functional!, if: :user_signed_in?
|
||||
|
||||
@ -42,10 +39,6 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
private
|
||||
|
||||
def https_enabled?
|
||||
Rails.env.production? && !request.path.start_with?('/health')
|
||||
end
|
||||
|
||||
def authorized_fetch_mode?
|
||||
ENV['AUTHORIZED_FETCH'] == 'true' || Rails.configuration.x.whitelist_mode
|
||||
end
|
||||
|
||||
@ -17,7 +17,9 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||
private
|
||||
|
||||
def require_unconfirmed!
|
||||
redirect_to edit_user_registration_path if user_signed_in? && current_user.confirmed? && current_user.unconfirmed_email.blank?
|
||||
if user_signed_in? && current_user.confirmed? && current_user.unconfirmed_email.blank?
|
||||
redirect_to(current_user.approved? ? root_path : edit_user_registration_path)
|
||||
end
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
|
||||
@ -31,21 +31,23 @@ module CacheConcern
|
||||
def cache_collection(raw, klass)
|
||||
return raw unless klass.respond_to?(:with_includes)
|
||||
|
||||
raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation)
|
||||
raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation)
|
||||
return [] if raw.empty?
|
||||
|
||||
cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id)
|
||||
uncached_ids = raw.map(&:id) - cached_keys_with_value.keys
|
||||
|
||||
klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!)
|
||||
|
||||
unless uncached_ids.empty?
|
||||
uncached = klass.where(id: uncached_ids).with_includes.each_with_object({}) { |item, h| h[item.id] = item }
|
||||
uncached = klass.where(id: uncached_ids).with_includes.index_by(&:id)
|
||||
|
||||
uncached.each_value do |item|
|
||||
Rails.cache.write(item, item)
|
||||
end
|
||||
end
|
||||
|
||||
raw.map { |item| cached_keys_with_value[item.id] || uncached[item.id] }.compact
|
||||
raw.filter_map { |item| cached_keys_with_value[item.id] || uncached[item.id] }
|
||||
end
|
||||
|
||||
def cache_collection_paginated_by_id(raw, klass, limit, options)
|
||||
|
||||
@ -133,6 +133,7 @@ module SignatureVerification
|
||||
|
||||
def verify_body_digest!
|
||||
return unless signed_headers.include?('digest')
|
||||
raise SignatureVerificationError, 'Digest header missing' unless request.headers.key?('Digest')
|
||||
|
||||
digests = request.headers['Digest'].split(',').map { |digest| digest.split('=', 2) }.map { |key, value| [key.downcase, value] }
|
||||
sha256 = digests.assoc('sha-256')
|
||||
|
||||
@ -6,7 +6,6 @@ class DirectoriesController < ApplicationController
|
||||
before_action :authenticate_user!, if: :whitelist_mode?
|
||||
before_action :require_enabled!
|
||||
before_action :set_instance_presenter
|
||||
before_action :set_tag, only: :show
|
||||
before_action :set_accounts
|
||||
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
@ -15,23 +14,14 @@ class DirectoriesController < ApplicationController
|
||||
render :index
|
||||
end
|
||||
|
||||
def show
|
||||
render :index
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_enabled!
|
||||
return not_found unless Setting.profile_directory
|
||||
end
|
||||
|
||||
def set_tag
|
||||
@tag = Tag.discoverable.find_normalized!(params[:id])
|
||||
end
|
||||
|
||||
def set_accounts
|
||||
@accounts = Account.local.discoverable.by_recent_status.page(params[:page]).per(20).tap do |query|
|
||||
query.merge!(Account.tagged_with(@tag.id)) if @tag
|
||||
query.merge!(Account.not_excluded_by_account(current_account)) if current_account
|
||||
end
|
||||
end
|
||||
|
||||
7
app/controllers/health_controller.rb
Normal file
7
app/controllers/health_controller.rb
Normal file
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class HealthController < ActionController::Base
|
||||
def show
|
||||
render plain: 'OK'
|
||||
end
|
||||
end
|
||||
@ -13,7 +13,7 @@ class InstanceActorsController < ApplicationController
|
||||
private
|
||||
|
||||
def set_account
|
||||
@account = Account.find(-99)
|
||||
@account = Account.representative
|
||||
end
|
||||
|
||||
def restrict_fields_to
|
||||
|
||||
@ -37,7 +37,7 @@ class MediaProxyController < ApplicationController
|
||||
end
|
||||
|
||||
def version
|
||||
if request.path.ends_with?('/small')
|
||||
if request.path.end_with?('/small')
|
||||
:small
|
||||
else
|
||||
:original
|
||||
|
||||
@ -7,8 +7,12 @@ module Settings
|
||||
|
||||
def destroy
|
||||
if valid_picture?
|
||||
msg = I18n.t('generic.changes_saved_msg') if UpdateAccountService.new.call(@account, { @picture => nil, "#{@picture}_remote_url" => '' })
|
||||
redirect_to settings_profile_path, notice: msg, status: 303
|
||||
if UpdateAccountService.new.call(@account, { @picture => nil, "#{@picture}_remote_url" => '' })
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
redirect_to settings_profile_path, notice: I18n.t('generic.changes_saved_msg'), status: 303
|
||||
else
|
||||
redirect_to settings_profile_path
|
||||
end
|
||||
else
|
||||
bad_request
|
||||
end
|
||||
|
||||
@ -8,7 +8,7 @@ class StatusesController < ApplicationController
|
||||
|
||||
layout 'public'
|
||||
|
||||
before_action :require_signature!, only: :show, if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :require_signature!, only: [:show, :activity], if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :set_status
|
||||
before_action :set_instance_presenter
|
||||
before_action :set_link_headers
|
||||
@ -16,7 +16,6 @@ class StatusesController < ApplicationController
|
||||
before_action :set_referrer_policy_header, only: :show
|
||||
before_action :set_cache_headers
|
||||
before_action :set_body_classes
|
||||
before_action :set_autoplay, only: :embed
|
||||
|
||||
skip_around_action :set_locale, if: -> { request.format == :json }
|
||||
skip_before_action :require_functional!, only: [:show, :embed], unless: :whitelist_mode?
|
||||
@ -82,8 +81,4 @@ class StatusesController < ApplicationController
|
||||
def set_referrer_policy_header
|
||||
response.headers['Referrer-Policy'] = 'origin' unless @status.distributable?
|
||||
end
|
||||
|
||||
def set_autoplay
|
||||
@autoplay = truthy_param?(:autoplay)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user