Merge tag 'v2.6.0rc1' into instance_only_statuses
This commit is contained in:
@ -95,7 +95,7 @@ module Admin
|
||||
:remote,
|
||||
:by_domain,
|
||||
:silenced,
|
||||
:recent,
|
||||
:alphabetic,
|
||||
:suspended,
|
||||
:username,
|
||||
:display_name,
|
||||
|
@ -46,7 +46,7 @@ module Admin
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :retroactive)
|
||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :retroactive)
|
||||
end
|
||||
|
||||
def retroactive_unblock?
|
||||
|
@ -44,6 +44,14 @@ module Admin
|
||||
when 'resolve'
|
||||
@report.resolve!(current_account)
|
||||
log_action :resolve, @report
|
||||
when 'disable'
|
||||
@report.resolve!(current_account)
|
||||
@report.target_account.user.disable!
|
||||
|
||||
log_action :resolve, @report
|
||||
log_action :disable, @report.target_account.user
|
||||
|
||||
resolve_all_target_account_reports
|
||||
when 'silence'
|
||||
@report.resolve!(current_account)
|
||||
@report.target_account.update!(silenced: true)
|
||||
@ -55,6 +63,7 @@ module Admin
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
@report.reload
|
||||
end
|
||||
|
||||
|
@ -19,6 +19,7 @@ module Admin
|
||||
theme
|
||||
thumbnail
|
||||
hero
|
||||
mascot
|
||||
min_invite_role
|
||||
activity_api_enabled
|
||||
peers_api_enabled
|
||||
@ -41,6 +42,7 @@ module Admin
|
||||
UPLOAD_SETTINGS = %w(
|
||||
thumbnail
|
||||
hero
|
||||
mascot
|
||||
).freeze
|
||||
|
||||
def edit
|
||||
|
@ -53,8 +53,8 @@ class Api::BaseController < ApplicationController
|
||||
[params[:limit].to_i.abs, default_limit * 2].min
|
||||
end
|
||||
|
||||
def truthy_param?(key)
|
||||
ActiveModel::Type::Boolean.new.cast(params[key])
|
||||
def params_slice(*keys)
|
||||
params.slice(*keys).permit(*keys)
|
||||
end
|
||||
|
||||
def current_resource_owner
|
||||
|
@ -28,10 +28,9 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||
|
||||
def account_statuses
|
||||
statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses
|
||||
statuses = statuses.paginate_by_max_id(
|
||||
statuses = statuses.paginate_by_id(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
|
||||
statuses.merge!(only_media_scope) if truthy_param?(:only_media)
|
||||
@ -82,7 +81,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||
|
||||
def prev_path
|
||||
unless @statuses.empty?
|
||||
api_v1_account_statuses_url pagination_params(since_id: pagination_since_id)
|
||||
api_v1_account_statuses_url pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
71
app/controllers/api/v1/conversations_controller.rb
Normal file
71
app/controllers/api/v1/conversations_controller.rb
Normal file
@ -0,0 +1,71 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::ConversationsController < Api::BaseController
|
||||
LIMIT = 20
|
||||
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :index
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:conversations' }, except: :index
|
||||
before_action :require_user!
|
||||
before_action :set_conversation, except: :index
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
@conversations = paginated_conversations
|
||||
render json: @conversations, each_serializer: REST::ConversationSerializer
|
||||
end
|
||||
|
||||
def read
|
||||
@conversation.update!(unread: false)
|
||||
render json: @conversation, serializer: REST::ConversationSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
@conversation.destroy!
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_conversation
|
||||
@conversation = AccountConversation.where(account: current_account).find(params[:id])
|
||||
end
|
||||
|
||||
def paginated_conversations
|
||||
AccountConversation.where(account: current_account)
|
||||
.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
def next_path
|
||||
if records_continue?
|
||||
api_v1_conversations_url pagination_params(max_id: pagination_max_id)
|
||||
end
|
||||
end
|
||||
|
||||
def prev_path
|
||||
unless @conversations.empty?
|
||||
api_v1_conversations_url pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
@conversations.last.last_status_id
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
@conversations.first.last_status_id
|
||||
end
|
||||
|
||||
def records_continue?
|
||||
@conversations.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
@ -26,10 +26,9 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||
end
|
||||
|
||||
def results
|
||||
@_results ||= account_favourites.paginate_by_max_id(
|
||||
@_results ||= account_favourites.paginate_by_id(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
end
|
||||
|
||||
@ -49,7 +48,7 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||
|
||||
def prev_path
|
||||
unless results.empty?
|
||||
api_v1_favourites_url pagination_params(since_id: pagination_since_id)
|
||||
api_v1_favourites_url pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4,6 +4,8 @@ class Api::V1::InstancesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def show
|
||||
render json: {}, serializer: REST::InstanceSerializer
|
||||
render_cached_json('api:v1:instances', expires_in: 5.minutes) do
|
||||
ActiveModelSerializers::SerializableResource.new({}, serializer: REST::InstanceSerializer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -37,10 +37,9 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||
end
|
||||
|
||||
def paginated_notifications
|
||||
browserable_account_notifications.paginate_by_max_id(
|
||||
browserable_account_notifications.paginate_by_id(
|
||||
limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
end
|
||||
|
||||
@ -64,7 +63,7 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||
|
||||
def prev_path
|
||||
unless @notifications.empty?
|
||||
api_v1_notifications_url pagination_params(since_id: pagination_since_id)
|
||||
api_v1_notifications_url pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,17 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::ReportsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:reports' }, except: [:create]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
@reports = current_account.reports
|
||||
render json: @reports, each_serializer: REST::ReportSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
@report = ReportService.new.call(
|
||||
current_account,
|
||||
@ -27,7 +21,7 @@ class Api::V1::ReportsController < Api::BaseController
|
||||
private
|
||||
|
||||
def reported_status_ids
|
||||
Status.find(status_ids).pluck(:id)
|
||||
reported_account.statuses.find(status_ids).pluck(:id)
|
||||
end
|
||||
|
||||
def status_ids
|
||||
|
@ -30,7 +30,8 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||
account_home_feed.get(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
params[:since_id],
|
||||
params[:min_id]
|
||||
)
|
||||
end
|
||||
|
||||
@ -51,7 +52,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_timelines_home_url pagination_params(since_id: pagination_since_id)
|
||||
api_v1_timelines_home_url pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
|
@ -32,7 +32,8 @@ class Api::V1::Timelines::ListController < Api::BaseController
|
||||
list_feed.get(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
params[:since_id],
|
||||
params[:min_id]
|
||||
)
|
||||
end
|
||||
|
||||
@ -53,7 +54,7 @@ class Api::V1::Timelines::ListController < Api::BaseController
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_timelines_list_url params[:id], pagination_params(since_id: pagination_since_id)
|
||||
api_v1_timelines_list_url params[:id], pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
|
@ -21,10 +21,9 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||
end
|
||||
|
||||
def public_statuses
|
||||
statuses = public_timeline_statuses.paginate_by_max_id(
|
||||
statuses = public_timeline_statuses.paginate_by_id(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
|
||||
if truthy_param?(:only_media)
|
||||
@ -53,7 +52,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_timelines_public_url pagination_params(since_id: pagination_since_id)
|
||||
api_v1_timelines_public_url pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
|
@ -29,10 +29,9 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||
if @tag.nil?
|
||||
[]
|
||||
else
|
||||
statuses = tag_timeline_statuses.paginate_by_max_id(
|
||||
statuses = tag_timeline_statuses.paginate_by_id(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
|
||||
if truthy_param?(:only_media)
|
||||
@ -62,7 +61,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_timelines_tag_url params[:id], pagination_params(since_id: pagination_since_id)
|
||||
api_v1_timelines_tag_url params[:id], pagination_params(min_id: pagination_since_id)
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
|
@ -58,6 +58,10 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
protected
|
||||
|
||||
def truthy_param?(key)
|
||||
ActiveModel::Type::Boolean.new.cast(params[key])
|
||||
end
|
||||
|
||||
def forbidden
|
||||
respond_with_error(403)
|
||||
end
|
||||
|
@ -10,6 +10,7 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
|
||||
before_action :set_instance_presenter, only: [:new]
|
||||
before_action :set_body_classes
|
||||
after_action :clear_site_data, only: [:destroy]
|
||||
|
||||
def new
|
||||
Devise.omniauth_configs.each do |provider, config|
|
||||
@ -27,8 +28,10 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
end
|
||||
|
||||
def destroy
|
||||
tmp_stored_location = stored_location_for(:user)
|
||||
super
|
||||
flash.delete(:notice)
|
||||
store_location_for(:user, tmp_stored_location) if continue_after?
|
||||
end
|
||||
|
||||
protected
|
||||
@ -121,4 +124,16 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
end
|
||||
paths
|
||||
end
|
||||
|
||||
def clear_site_data
|
||||
return if continue_after?
|
||||
|
||||
# Should be '"*"' but that doesn't work in Chrome (neither does '"executionContexts"')
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data
|
||||
response.headers['Clear-Site-Data'] = '"cache", "cookies", "storage"'
|
||||
end
|
||||
|
||||
def continue_after?
|
||||
truthy_param?(:continue)
|
||||
end
|
||||
end
|
||||
|
@ -22,6 +22,12 @@ module SignatureVerification
|
||||
return
|
||||
end
|
||||
|
||||
if request.headers['Date'].present? && !matches_time_window?
|
||||
@signature_verification_failure_reason = 'Signed request date outside acceptable time window'
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
|
||||
raw_signature = request.headers['Signature']
|
||||
signature_params = {}
|
||||
|
||||
@ -76,7 +82,7 @@ module SignatureVerification
|
||||
def build_signed_string(signed_headers)
|
||||
signed_headers = 'date' if signed_headers.blank?
|
||||
|
||||
signed_headers.split(' ').map do |signed_header|
|
||||
signed_headers.downcase.split(' ').map do |signed_header|
|
||||
if signed_header == Request::REQUEST_TARGET
|
||||
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
||||
elsif signed_header == 'digest'
|
||||
@ -89,12 +95,12 @@ module SignatureVerification
|
||||
|
||||
def matches_time_window?
|
||||
begin
|
||||
time_sent = DateTime.httpdate(request.headers['Date'])
|
||||
time_sent = Time.httpdate(request.headers['Date'])
|
||||
rescue ArgumentError
|
||||
return false
|
||||
end
|
||||
|
||||
(Time.now.utc - time_sent).abs <= 30
|
||||
(Time.now.utc - time_sent).abs <= 12.hours
|
||||
end
|
||||
|
||||
def body_digest
|
||||
|
@ -13,4 +13,18 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
||||
def store_current_location
|
||||
store_location_for(:user, request.url)
|
||||
end
|
||||
|
||||
def render_success
|
||||
if skip_authorization? || (matching_token? && !truthy_param?('force_login'))
|
||||
redirect_or_render authorize_response
|
||||
elsif Doorkeeper.configuration.api_only
|
||||
render json: pre_auth
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def truthy_param?(key)
|
||||
ActiveModel::Type::Boolean.new.cast(params[key])
|
||||
end
|
||||
end
|
||||
|
@ -41,7 +41,8 @@ class Settings::PreferencesController < ApplicationController
|
||||
:setting_boost_modal,
|
||||
:setting_delete_modal,
|
||||
:setting_auto_play_gif,
|
||||
:setting_display_sensitive_media,
|
||||
:setting_display_media,
|
||||
:setting_expand_spoilers,
|
||||
:setting_reduce_motion,
|
||||
:setting_system_font_ui,
|
||||
:setting_noindex,
|
||||
|
@ -19,6 +19,10 @@ class StatusesController < ApplicationController
|
||||
before_action :set_referrer_policy_header, only: [:show]
|
||||
before_action :set_cache_headers
|
||||
|
||||
content_security_policy only: :embed do |p|
|
||||
p.frame_ancestors(false)
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
|
Reference in New Issue
Block a user