Merge remote-tracking branch 'parent/main' into upstream-20231204
This commit is contained in:
commit
94c2396a34
179 changed files with 1036 additions and 775 deletions
|
@ -26,7 +26,7 @@ Lint/NonLocalExitFromIterator:
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 144
|
Max: 125
|
||||||
|
|
||||||
# Configuration parameters: CountBlocks, Max.
|
# Configuration parameters: CountBlocks, Max.
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
|
@ -109,25 +109,11 @@ Rails/ApplicationController:
|
||||||
# Include: app/models/**/*.rb
|
# Include: app/models/**/*.rb
|
||||||
Rails/HasAndBelongsToMany:
|
Rails/HasAndBelongsToMany:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/models/concerns/account_associations.rb'
|
- 'app/models/concerns/account/associations.rb'
|
||||||
- 'app/models/preview_card.rb'
|
- 'app/models/preview_card.rb'
|
||||||
- 'app/models/status.rb'
|
- 'app/models/status.rb'
|
||||||
- 'app/models/tag.rb'
|
- 'app/models/tag.rb'
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: app/models/**/*.rb
|
|
||||||
Rails/HasManyOrHasOneDependent:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/concerns/account_counters.rb'
|
|
||||||
- 'app/models/conversation.rb'
|
|
||||||
- 'app/models/custom_emoji.rb'
|
|
||||||
- 'app/models/custom_emoji_category.rb'
|
|
||||||
- 'app/models/domain_block.rb'
|
|
||||||
- 'app/models/invite.rb'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
- 'app/models/web/push_subscription.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
# Configuration parameters: Include.
|
||||||
# Include: app/controllers/**/*.rb, app/mailers/**/*.rb
|
# Include: app/controllers/**/*.rb, app/mailers/**/*.rb
|
||||||
Rails/LexicallyScopedActionFilter:
|
Rails/LexicallyScopedActionFilter:
|
||||||
|
@ -174,7 +160,7 @@ Rails/SkipsModelValidations:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/controllers/admin/invites_controller.rb'
|
- 'app/controllers/admin/invites_controller.rb'
|
||||||
- 'app/controllers/concerns/session_tracking_concern.rb'
|
- 'app/controllers/concerns/session_tracking_concern.rb'
|
||||||
- 'app/models/concerns/account_merging.rb'
|
- 'app/models/concerns/account/merging.rb'
|
||||||
- 'app/models/concerns/expireable.rb'
|
- 'app/models/concerns/expireable.rb'
|
||||||
- 'app/models/status.rb'
|
- 'app/models/status.rb'
|
||||||
- 'app/models/trends/links.rb'
|
- 'app/models/trends/links.rb'
|
||||||
|
@ -254,7 +240,7 @@ Rails/WhereExists:
|
||||||
- 'app/lib/feed_manager.rb'
|
- 'app/lib/feed_manager.rb'
|
||||||
- 'app/lib/status_cache_hydrator.rb'
|
- 'app/lib/status_cache_hydrator.rb'
|
||||||
- 'app/lib/suspicious_sign_in_detector.rb'
|
- 'app/lib/suspicious_sign_in_detector.rb'
|
||||||
- 'app/models/concerns/account_interactions.rb'
|
- 'app/models/concerns/account/interactions.rb'
|
||||||
- 'app/models/featured_tag.rb'
|
- 'app/models/featured_tag.rb'
|
||||||
- 'app/models/poll.rb'
|
- 'app/models/poll.rb'
|
||||||
- 'app/models/session_activation.rb'
|
- 'app/models/session_activation.rb'
|
||||||
|
@ -309,7 +295,7 @@ Style/FetchEnvVar:
|
||||||
- 'config/initializers/devise.rb'
|
- 'config/initializers/devise.rb'
|
||||||
- 'config/initializers/paperclip.rb'
|
- 'config/initializers/paperclip.rb'
|
||||||
- 'config/initializers/vapid.rb'
|
- 'config/initializers/vapid.rb'
|
||||||
- 'lib/mastodon/premailer_webpack_strategy.rb'
|
- 'lib/premailer_webpack_strategy.rb'
|
||||||
- 'lib/mastodon/redis_config.rb'
|
- 'lib/mastodon/redis_config.rb'
|
||||||
- 'lib/tasks/repo.rake'
|
- 'lib/tasks/repo.rake'
|
||||||
- 'spec/features/profile_spec.rb'
|
- 'spec/features/profile_spec.rb'
|
||||||
|
@ -344,8 +330,8 @@ Style/GuardClause:
|
||||||
- 'app/lib/request_pool.rb'
|
- 'app/lib/request_pool.rb'
|
||||||
- 'app/lib/webfinger.rb'
|
- 'app/lib/webfinger.rb'
|
||||||
- 'app/lib/webfinger_resource.rb'
|
- 'app/lib/webfinger_resource.rb'
|
||||||
- 'app/models/concerns/account_counters.rb'
|
- 'app/models/concerns/account/counters.rb'
|
||||||
- 'app/models/concerns/ldap_authenticable.rb'
|
- 'app/models/concerns/user/ldap_authenticable.rb'
|
||||||
- 'app/models/tag.rb'
|
- 'app/models/tag.rb'
|
||||||
- 'app/models/user.rb'
|
- 'app/models/user.rb'
|
||||||
- 'app/services/fan_out_on_write_service.rb'
|
- 'app/services/fan_out_on_write_service.rb'
|
||||||
|
@ -359,8 +345,8 @@ Style/GuardClause:
|
||||||
- 'config/initializers/devise.rb'
|
- 'config/initializers/devise.rb'
|
||||||
- 'db/migrate/20170901141119_truncate_preview_cards.rb'
|
- 'db/migrate/20170901141119_truncate_preview_cards.rb'
|
||||||
- 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb'
|
- 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb'
|
||||||
- 'lib/devise/two_factor_ldap_authenticatable.rb'
|
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
|
||||||
- 'lib/devise/two_factor_pam_authenticatable.rb'
|
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
|
||||||
- 'lib/mastodon/cli/accounts.rb'
|
- 'lib/mastodon/cli/accounts.rb'
|
||||||
- 'lib/mastodon/cli/maintenance.rb'
|
- 'lib/mastodon/cli/maintenance.rb'
|
||||||
- 'lib/mastodon/cli/media.rb'
|
- 'lib/mastodon/cli/media.rb'
|
||||||
|
@ -374,8 +360,8 @@ Style/HashAsLastArrayItem:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/controllers/admin/statuses_controller.rb'
|
- 'app/controllers/admin/statuses_controller.rb'
|
||||||
- 'app/controllers/api/v1/statuses_controller.rb'
|
- 'app/controllers/api/v1/statuses_controller.rb'
|
||||||
- 'app/models/concerns/account_counters.rb'
|
- 'app/models/concerns/account/counters.rb'
|
||||||
- 'app/models/concerns/status_threading_concern.rb'
|
- 'app/models/concerns/status/threading_concern.rb'
|
||||||
- 'app/models/status.rb'
|
- 'app/models/status.rb'
|
||||||
- 'app/services/batched_remove_status_service.rb'
|
- 'app/services/batched_remove_status_service.rb'
|
||||||
- 'app/services/notify_service.rb'
|
- 'app/services/notify_service.rb'
|
||||||
|
@ -488,15 +474,15 @@ Style/RedundantReturn:
|
||||||
# AllowedMethods: present?, blank?, presence, try, try!
|
# AllowedMethods: present?, blank?, presence, try, try!
|
||||||
Style/SafeNavigation:
|
Style/SafeNavigation:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/models/concerns/account_finder_concern.rb'
|
- 'app/models/concerns/account/finder_concern.rb'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
# SupportedStyles: only_raise, only_fail, semantic
|
# SupportedStyles: only_raise, only_fail, semantic
|
||||||
Style/SignalException:
|
Style/SignalException:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/devise/two_factor_ldap_authenticatable.rb'
|
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
|
||||||
- 'lib/devise/two_factor_pam_authenticatable.rb'
|
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
Style/SingleArgumentDig:
|
Style/SingleArgumentDig:
|
||||||
|
|
|
@ -247,7 +247,9 @@ RUN \
|
||||||
RUN \
|
RUN \
|
||||||
# Pre-create and chown system volume to Mastodon user
|
# Pre-create and chown system volume to Mastodon user
|
||||||
mkdir -p /opt/mastodon/public/system; \
|
mkdir -p /opt/mastodon/public/system; \
|
||||||
chown mastodon:mastodon /opt/mastodon/public/system;
|
chown mastodon:mastodon /opt/mastodon/public/system; \
|
||||||
|
# Set Mastodon user as owner of tmp folder
|
||||||
|
chown -R mastodon:mastodon /opt/mastodon/tmp;
|
||||||
|
|
||||||
# Set the running user for resulting container
|
# Set the running user for resulting container
|
||||||
USER mastodon
|
USER mastodon
|
||||||
|
|
|
@ -245,7 +245,7 @@ GEM
|
||||||
docile (1.4.0)
|
docile (1.4.0)
|
||||||
domain_name (0.5.20190701)
|
domain_name (0.5.20190701)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
doorkeeper (5.6.7)
|
doorkeeper (5.6.8)
|
||||||
railties (>= 5)
|
railties (>= 5)
|
||||||
dotenv (2.8.1)
|
dotenv (2.8.1)
|
||||||
dotenv-rails (2.8.1)
|
dotenv-rails (2.8.1)
|
||||||
|
@ -522,7 +522,7 @@ GEM
|
||||||
pastel (0.8.0)
|
pastel (0.8.0)
|
||||||
tty-color (~> 0.5)
|
tty-color (~> 0.5)
|
||||||
pg (1.5.4)
|
pg (1.5.4)
|
||||||
pghero (3.3.4)
|
pghero (3.4.0)
|
||||||
activerecord (>= 6)
|
activerecord (>= 6)
|
||||||
posix-spawn (0.3.15)
|
posix-spawn (0.3.15)
|
||||||
premailer (1.21.0)
|
premailer (1.21.0)
|
||||||
|
@ -617,7 +617,7 @@ GEM
|
||||||
redlock (1.3.2)
|
redlock (1.3.2)
|
||||||
redis (>= 3.0.0, < 6.0)
|
redis (>= 3.0.0, < 6.0)
|
||||||
regexp_parser (2.8.2)
|
regexp_parser (2.8.2)
|
||||||
reline (0.4.0)
|
reline (0.4.1)
|
||||||
io-console (~> 0.5)
|
io-console (~> 0.5)
|
||||||
request_store (1.5.1)
|
request_store (1.5.1)
|
||||||
rack (>= 1.4)
|
rack (>= 1.4)
|
||||||
|
|
6
Vagrantfile
vendored
6
Vagrantfile
vendored
|
@ -10,7 +10,11 @@ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
|
||||||
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
||||||
|
|
||||||
# Add repo for NodeJS
|
# Add repo for NodeJS
|
||||||
curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -
|
sudo mkdir -p /etc/apt/keyrings
|
||||||
|
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||||
|
NODE_MAJOR=20
|
||||||
|
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
|
||||||
|
sudo apt-get update
|
||||||
|
|
||||||
# Add firewall rule to redirect 80 to PORT and save
|
# Add firewall rule to redirect 80 to PORT and save
|
||||||
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
|
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
|
||||||
|
|
|
@ -52,7 +52,7 @@ class AccountsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def only_media_scope
|
def only_media_scope
|
||||||
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
|
Status.joins(:media_attachments).merge(@account.media_attachments).group(:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def no_replies_scope
|
def no_replies_scope
|
||||||
|
|
|
@ -16,7 +16,7 @@ module Admin
|
||||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
@moderation_notes = @account.targeted_moderation_notes.latest
|
||||||
@warnings = @account.strikes.custom.latest
|
@warnings = @account.strikes.custom.latest
|
||||||
|
|
||||||
render template: 'admin/accounts/show'
|
render 'admin/accounts/show'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :audit_log, :index?
|
authorize :audit_log, :index?
|
||||||
@auditable_accounts = Account.where(id: Admin::ActionLog.reorder(nil).select('distinct account_id')).select(:id, :username)
|
@auditable_accounts = Account.where(id: Admin::ActionLog.select('distinct account_id')).select(:id, :username)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -4,7 +4,7 @@ require 'csv'
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class ExportDomainAllowsController < BaseController
|
class ExportDomainAllowsController < BaseController
|
||||||
include AdminExportControllerConcern
|
include Admin::ExportControllerConcern
|
||||||
|
|
||||||
before_action :set_dummy_import!, only: [:new]
|
before_action :set_dummy_import!, only: [:new]
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ require 'csv'
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class ExportDomainBlocksController < BaseController
|
class ExportDomainBlocksController < BaseController
|
||||||
include AdminExportControllerConcern
|
include Admin::ExportControllerConcern
|
||||||
|
|
||||||
before_action :set_dummy_import!, only: [:new]
|
before_action :set_dummy_import!, only: [:new]
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ module Admin
|
||||||
@relay.enable!
|
@relay.enable!
|
||||||
redirect_to admin_relays_path
|
redirect_to admin_relays_path
|
||||||
else
|
else
|
||||||
render action: :new
|
render :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ module Admin
|
||||||
@form = Admin::StatusBatchAction.new
|
@form = Admin::StatusBatchAction.new
|
||||||
@statuses = @report.statuses.with_includes
|
@statuses = @report.statuses.with_includes
|
||||||
|
|
||||||
render template: 'admin/reports/show'
|
render 'admin/reports/show'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ class Api::BaseController < ApplicationController
|
||||||
DEFAULT_STATUSES_LIMIT = 20
|
DEFAULT_STATUSES_LIMIT = 20
|
||||||
DEFAULT_ACCOUNTS_LIMIT = 40
|
DEFAULT_ACCOUNTS_LIMIT = 40
|
||||||
|
|
||||||
include RateLimitHeaders
|
include Api::RateLimitHeaders
|
||||||
include AccessTokenTrackingConcern
|
include Api::AccessTokenTrackingConcern
|
||||||
include ApiCachingConcern
|
include Api::CachingConcern
|
||||||
include Api::ContentSecurityPolicy
|
include Api::ContentSecurityPolicy
|
||||||
|
|
||||||
skip_before_action :require_functional!, unless: :limited_federation_mode?
|
skip_before_action :require_functional!, unless: :limited_federation_mode?
|
||||||
|
@ -64,7 +64,7 @@ class Api::BaseController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def doorkeeper_unauthorized_render_options(error: nil)
|
def doorkeeper_unauthorized_render_options(error: nil)
|
||||||
{ json: { error: (error.try(:description) || 'Not authorized') } }
|
{ json: { error: error.try(:description) || 'Not authorized' } }
|
||||||
end
|
end
|
||||||
|
|
||||||
def doorkeeper_forbidden_render_options(*)
|
def doorkeeper_forbidden_render_options(*)
|
||||||
|
@ -105,7 +105,7 @@ class Api::BaseController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_not_suspended!
|
def require_not_suspended!
|
||||||
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.suspended?
|
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_user!
|
def require_user!
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def hide_results?
|
def hide_results?
|
||||||
@account.suspended? || (@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
|
@account.unavailable? || (@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_accounts
|
def default_accounts
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def hide_results?
|
def hide_results?
|
||||||
@account.suspended? || (@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
|
@account.unavailable? || (@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_accounts
|
def default_accounts
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_statuses
|
def load_statuses
|
||||||
@account.suspended? ? [] : cached_account_statuses
|
@account.unavailable? ? [] : cached_account_statuses
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_account_statuses
|
def cached_account_statuses
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def mute
|
def mute
|
||||||
MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: (params[:duration]&.to_i || 0))
|
MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications), duration: params[:duration].to_i)
|
||||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
|
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,11 @@ class Api::V2::SearchController < Api::BaseController
|
||||||
before_action -> { authorize_if_got_token! :read, :'read:search' }
|
before_action -> { authorize_if_got_token! :read, :'read:search' }
|
||||||
before_action :validate_search_params!
|
before_action :validate_search_params!
|
||||||
|
|
||||||
|
with_options unless: :user_signed_in? do
|
||||||
|
before_action :query_pagination_error, if: :pagination_requested?
|
||||||
|
before_action :remote_resolve_error, if: :remote_resolve_requested?
|
||||||
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@search = Search.new(search_results)
|
@search = Search.new(search_results)
|
||||||
render json: @search, serializer: REST::SearchSerializer
|
render json: @search, serializer: REST::SearchSerializer
|
||||||
|
@ -21,12 +26,22 @@ class Api::V2::SearchController < Api::BaseController
|
||||||
|
|
||||||
def validate_search_params!
|
def validate_search_params!
|
||||||
params.require(:q)
|
params.require(:q)
|
||||||
|
end
|
||||||
|
|
||||||
return if user_signed_in?
|
def query_pagination_error
|
||||||
|
render json: { error: 'Search queries pagination is not supported without authentication' }, status: 401
|
||||||
|
end
|
||||||
|
|
||||||
return render json: { error: 'Search queries pagination is not supported without authentication' }, status: 401 if params[:offset].present?
|
def remote_resolve_error
|
||||||
|
render json: { error: 'Search queries that resolve remote resources are not supported without authentication' }, status: 401
|
||||||
|
end
|
||||||
|
|
||||||
render json: { error: 'Search queries that resolve remote resources are not supported without authentication' }, status: 401 if truthy_param?(:resolve)
|
def remote_resolve_requested?
|
||||||
|
truthy_param?(:resolve)
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_requested?
|
||||||
|
params[:offset].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_results
|
def search_results
|
||||||
|
@ -34,7 +49,15 @@ class Api::V2::SearchController < Api::BaseController
|
||||||
params[:q],
|
params[:q],
|
||||||
current_account,
|
current_account,
|
||||||
limit_param(RESULTS_LIMIT),
|
limit_param(RESULTS_LIMIT),
|
||||||
search_params.merge(resolve: truthy_param?(:resolve), exclude_unreviewed: truthy_param?(:exclude_unreviewed), following: truthy_param?(:following))
|
combined_search_params
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def combined_search_params
|
||||||
|
search_params.merge(
|
||||||
|
resolve: truthy_param?(:resolve),
|
||||||
|
exclude_unreviewed: truthy_param?(:exclude_unreviewed),
|
||||||
|
following: truthy_param?(:following)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||||
include CaptchaConcern
|
include Auth::CaptchaConcern
|
||||||
|
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
class Auth::RegistrationsController < Devise::RegistrationsController
|
class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
include RegistrationHelper
|
include RegistrationHelper
|
||||||
include RegistrationSpamConcern
|
include Auth::RegistrationSpamConcern
|
||||||
|
|
||||||
layout :determine_layout
|
layout :determine_layout
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_not_suspended!
|
def require_not_suspended!
|
||||||
forbidden if current_account.suspended?
|
forbidden if current_account.unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_rules
|
def set_rules
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
|
|
||||||
prepend_before_action :check_suspicious!, only: [:create]
|
prepend_before_action :check_suspicious!, only: [:create]
|
||||||
|
|
||||||
include TwoFactorAuthenticationConcern
|
include Auth::TwoFactorAuthenticationConcern
|
||||||
|
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ module AccountOwnedConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_account_suspension
|
def check_account_suspension
|
||||||
if @account.suspended_permanently?
|
if @account.permanently_unavailable?
|
||||||
permanent_suspension_response
|
permanent_unavailability_response
|
||||||
elsif @account.suspended? && !skip_temporary_suspension_response?
|
elsif @account.suspended? && !skip_temporary_suspension_response?
|
||||||
temporary_suspension_response
|
temporary_suspension_response
|
||||||
end
|
end
|
||||||
|
@ -45,7 +45,7 @@ module AccountOwnedConcern
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def permanent_suspension_response
|
def permanent_unavailability_response
|
||||||
expires_in(3.minutes, public: true)
|
expires_in(3.minutes, public: true)
|
||||||
gone
|
gone
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AdminExportControllerConcern
|
module Admin::ExportControllerConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
private
|
private
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccessTokenTrackingConcern
|
module Api::AccessTokenTrackingConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
ACCESS_TOKEN_UPDATE_FREQUENCY = 24.hours.freeze
|
ACCESS_TOKEN_UPDATE_FREQUENCY = 24.hours.freeze
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module ApiCachingConcern
|
module Api::CachingConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def cache_if_unauthenticated!
|
def cache_if_unauthenticated!
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module RateLimitHeaders
|
module Api::RateLimitHeaders
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module CaptchaConcern
|
module Auth::CaptchaConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
include Hcaptcha::Adapters::ViewMethods
|
include Hcaptcha::Adapters::ViewMethods
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module RegistrationSpamConcern
|
module Auth::RegistrationSpamConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def set_registration_form_time
|
def set_registration_form_time
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module TwoFactorAuthenticationConcern
|
module Auth::TwoFactorAuthenticationConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -43,7 +43,7 @@ module ChallengableConcern
|
||||||
|
|
||||||
def render_challenge
|
def render_challenge
|
||||||
@body_classes = 'lighter'
|
@body_classes = 'lighter'
|
||||||
render template: 'auth/challenges/new', layout: 'auth'
|
render 'auth/challenges/new', layout: 'auth'
|
||||||
end
|
end
|
||||||
|
|
||||||
def challenge_passed?
|
def challenge_passed?
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module ExportControllerConcern
|
module Settings::ExportControllerConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -11,7 +11,7 @@ class Disputes::AppealsController < Disputes::BaseController
|
||||||
redirect_to disputes_strike_path(@strike), notice: I18n.t('disputes.strikes.appealed_msg')
|
redirect_to disputes_strike_path(@strike), notice: I18n.t('disputes.strikes.appealed_msg')
|
||||||
rescue ActiveRecord::RecordInvalid => e
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
@appeal = e.record
|
@appeal = e.record
|
||||||
render template: 'disputes/strikes/show'
|
render 'disputes/strikes/show'
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -25,7 +25,7 @@ class FiltersController < ApplicationController
|
||||||
if @filter.save
|
if @filter.save
|
||||||
redirect_to filters_path
|
redirect_to filters_path
|
||||||
else
|
else
|
||||||
render action: :new
|
render :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class FiltersController < ApplicationController
|
||||||
if @filter.update(resource_params)
|
if @filter.update(resource_params)
|
||||||
redirect_to filters_path
|
redirect_to filters_path
|
||||||
else
|
else
|
||||||
render action: :edit
|
render :edit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_not_suspended!
|
def require_not_suspended!
|
||||||
forbidden if current_account.suspended?
|
forbidden if current_account.unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_cache_headers
|
def set_cache_headers
|
||||||
|
|
|
@ -18,6 +18,6 @@ class Settings::BaseController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_not_suspended!
|
def require_not_suspended!
|
||||||
forbidden if current_account.suspended?
|
forbidden if current_account.unavailable?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Settings::DeletesController < Settings::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_not_suspended!
|
def require_not_suspended!
|
||||||
forbidden if current_account.suspended?
|
forbidden if current_account.unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def challenge_passed?
|
def challenge_passed?
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module Settings
|
module Settings
|
||||||
module Exports
|
module Exports
|
||||||
class BlockedAccountsController < BaseController
|
class BlockedAccountsController < BaseController
|
||||||
include ExportControllerConcern
|
include Settings::ExportControllerConcern
|
||||||
|
|
||||||
def index
|
def index
|
||||||
send_export_file
|
send_export_file
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module Settings
|
module Settings
|
||||||
module Exports
|
module Exports
|
||||||
class BlockedDomainsController < BaseController
|
class BlockedDomainsController < BaseController
|
||||||
include ExportControllerConcern
|
include Settings::ExportControllerConcern
|
||||||
|
|
||||||
def index
|
def index
|
||||||
send_export_file
|
send_export_file
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module Settings
|
module Settings
|
||||||
module Exports
|
module Exports
|
||||||
class BookmarksController < BaseController
|
class BookmarksController < BaseController
|
||||||
include ExportControllerConcern
|
include Settings::ExportControllerConcern
|
||||||
|
|
||||||
def index
|
def index
|
||||||
send_export_file
|
send_export_file
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module Settings
|
module Settings
|
||||||
module Exports
|
module Exports
|
||||||
class FollowingAccountsController < BaseController
|
class FollowingAccountsController < BaseController
|
||||||
include ExportControllerConcern
|
include Settings::ExportControllerConcern
|
||||||
|
|
||||||
def index
|
def index
|
||||||
send_export_file
|
send_export_file
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module Settings
|
module Settings
|
||||||
module Exports
|
module Exports
|
||||||
class ListsController < BaseController
|
class ListsController < BaseController
|
||||||
include ExportControllerConcern
|
include Settings::ExportControllerConcern
|
||||||
|
|
||||||
def index
|
def index
|
||||||
send_export_file
|
send_export_file
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module Settings
|
module Settings
|
||||||
module Exports
|
module Exports
|
||||||
class MutedAccountsController < BaseController
|
class MutedAccountsController < BaseController
|
||||||
include ExportControllerConcern
|
include Settings::ExportControllerConcern
|
||||||
|
|
||||||
def index
|
def index
|
||||||
send_export_file
|
send_export_file
|
||||||
|
|
|
@ -14,7 +14,7 @@ class StatusesCleanupController < ApplicationController
|
||||||
if @policy.update(resource_params)
|
if @policy.update(resource_params)
|
||||||
redirect_to statuses_cleanup_path, notice: I18n.t('generic.changes_saved_msg')
|
redirect_to statuses_cleanup_path, notice: I18n.t('generic.changes_saved_msg')
|
||||||
else
|
else
|
||||||
render action: :show
|
render :show
|
||||||
end
|
end
|
||||||
rescue ActionController::ParameterMissing
|
rescue ActionController::ParameterMissing
|
||||||
# Do nothing
|
# Do nothing
|
||||||
|
|
|
@ -42,7 +42,7 @@ module WellKnown
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_account_suspension
|
def check_account_suspension
|
||||||
gone if @account.suspended_permanently?
|
gone if @account.permanently_unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def gone
|
def gone
|
||||||
|
|
12
app/helpers/admin/account_actions_helper.rb
Normal file
12
app/helpers/admin/account_actions_helper.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin::AccountActionsHelper
|
||||||
|
def account_action_type_label(type)
|
||||||
|
safe_join(
|
||||||
|
[
|
||||||
|
I18n.t("simple_form.labels.admin_account_action.types.#{type}"),
|
||||||
|
content_tag(:span, I18n.t("simple_form.hints.admin_account_action.types.#{type}"), class: 'hint'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
19
app/helpers/admin/accounts_helper.rb
Normal file
19
app/helpers/admin/accounts_helper.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin::AccountsHelper
|
||||||
|
def admin_accounts_moderation_options
|
||||||
|
[
|
||||||
|
[t('admin.accounts.moderation.active'), 'active'],
|
||||||
|
[t('admin.accounts.moderation.silenced'), 'silenced'],
|
||||||
|
[t('admin.accounts.moderation.disabled'), 'disabled'],
|
||||||
|
[t('admin.accounts.moderation.suspended'), 'suspended'],
|
||||||
|
[safe_join([t('admin.accounts.moderation.pending'), "(#{pending_user_count_label})"], ' '), 'pending'],
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def pending_user_count_label
|
||||||
|
number_with_delimiter User.pending.count
|
||||||
|
end
|
||||||
|
end
|
12
app/helpers/admin/ip_blocks_helper.rb
Normal file
12
app/helpers/admin/ip_blocks_helper.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin::IpBlocksHelper
|
||||||
|
def ip_blocks_severity_label(severity)
|
||||||
|
safe_join(
|
||||||
|
[
|
||||||
|
I18n.t("simple_form.labels.ip_block.severities.#{severity}"),
|
||||||
|
content_tag(:span, I18n.t("simple_form.hints.ip_block.severities.#{severity}"), class: 'hint'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
24
app/helpers/admin/roles_helper.rb
Normal file
24
app/helpers/admin/roles_helper.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module RolesHelper
|
||||||
|
def privilege_label(privilege)
|
||||||
|
safe_join(
|
||||||
|
[
|
||||||
|
t("admin.roles.privileges.#{privilege}"),
|
||||||
|
content_tag(:span, t("admin.roles.privileges.#{privilege}_description"), class: 'hint'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable_permissions?(permissions)
|
||||||
|
permissions.filter { |privilege| role_flag_value(privilege).zero? }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def role_flag_value(privilege)
|
||||||
|
UserRole::FLAGS[privilege] & current_user.role.computed_permissions
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
app/helpers/admin/settings/discovery_helper.rb
Normal file
15
app/helpers/admin/settings/discovery_helper.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin::Settings::DiscoveryHelper
|
||||||
|
def discovery_warning_hint_text
|
||||||
|
authorized_fetch_overridden? ? t('admin.settings.security.authorized_fetch_overridden_hint') : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def discovery_hint_text
|
||||||
|
t('admin.settings.security.authorized_fetch_hint')
|
||||||
|
end
|
||||||
|
|
||||||
|
def discovery_recommended_value
|
||||||
|
authorized_fetch_overridden? ? :overridden : nil
|
||||||
|
end
|
||||||
|
end
|
12
app/helpers/filters_helper.rb
Normal file
12
app/helpers/filters_helper.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module FiltersHelper
|
||||||
|
def filter_action_label(action)
|
||||||
|
safe_join(
|
||||||
|
[
|
||||||
|
t("simple_form.labels.filters.actions.#{action}"),
|
||||||
|
content_tag(:span, t("simple_form.hints.filters.actions.#{action}"), class: 'hint'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,11 +1,18 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call,
|
||||||
|
@typescript-eslint/no-unsafe-return,
|
||||||
|
@typescript-eslint/no-unsafe-assignment,
|
||||||
|
@typescript-eslint/no-unsafe-member-access
|
||||||
|
-- the settings store is not yet typed */
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState, useEffect } from 'react';
|
||||||
|
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
|
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
|
||||||
|
|
||||||
|
import { changeSetting } from 'mastodon/actions/settings';
|
||||||
import { bannerSettings } from 'mastodon/settings';
|
import { bannerSettings } from 'mastodon/settings';
|
||||||
|
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
import { IconButton } from './icon_button';
|
import { IconButton } from './icon_button';
|
||||||
|
|
||||||
|
@ -21,13 +28,25 @@ export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
|
||||||
id,
|
id,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const [visible, setVisible] = useState(!bannerSettings.get(id));
|
const dismissed = useAppSelector((state) =>
|
||||||
|
state.settings.getIn(['dismissed_banners', id], false),
|
||||||
|
);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const [visible, setVisible] = useState(!bannerSettings.get(id) && !dismissed);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleDismiss = useCallback(() => {
|
const handleDismiss = useCallback(() => {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
bannerSettings.set(id, true);
|
bannerSettings.set(id, true);
|
||||||
}, [id]);
|
dispatch(changeSetting(['dismissed_banners', id], true));
|
||||||
|
}, [id, dispatch]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!visible && !dismissed) {
|
||||||
|
dispatch(changeSetting(['dismissed_banners', id], true));
|
||||||
|
}
|
||||||
|
}, [id, dispatch, visible, dismissed]);
|
||||||
|
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -113,6 +113,15 @@ const initialState = ImmutableMap({
|
||||||
body: '',
|
body: '',
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
dismissed_banners: ImmutableMap({
|
||||||
|
'public_timeline': false,
|
||||||
|
'community_timeline': false,
|
||||||
|
'home.explore_prompt': false,
|
||||||
|
'explore/links': false,
|
||||||
|
'explore/statuses': false,
|
||||||
|
'explore/tags': false,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultColumns = fromJS([
|
const defaultColumns = fromJS([
|
||||||
|
|
|
@ -2815,22 +2815,16 @@ $ui-header-height: 55px;
|
||||||
&__description {
|
&__description {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
color: $highlight-text-color;
|
color: $highlight-text-color;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
color: $darker-text-color;
|
color: $darker-text-color;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,9 @@ class AccountStatusesFilter
|
||||||
private
|
private
|
||||||
|
|
||||||
def initial_scope
|
def initial_scope
|
||||||
if (suspended? || (domain_block&.reject_send_dissubscribable && !@account.all_subscribable?)) || domain_block&.reject_send_media || blocked?
|
return Status.none if account.unavailable?
|
||||||
|
|
||||||
|
if (domain_block&.reject_send_dissubscribable && !@account.all_subscribable?) || domain_block&.reject_send_media || blocked?
|
||||||
Status.none
|
Status.none
|
||||||
elsif anonymous?
|
elsif anonymous?
|
||||||
account.statuses.where(visibility: %i(public unlisted public_unlisted))
|
account.statuses.where(visibility: %i(public unlisted public_unlisted))
|
||||||
|
@ -80,7 +82,7 @@ class AccountStatusesFilter
|
||||||
end
|
end
|
||||||
|
|
||||||
def only_media_scope
|
def only_media_scope
|
||||||
Status.joins(:media_attachments).merge(account.media_attachments.reorder(nil)).group(Status.arel_table[:id])
|
Status.joins(:media_attachments).merge(account.media_attachments).group(Status.arel_table[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def no_replies_scope
|
def no_replies_scope
|
||||||
|
@ -105,10 +107,6 @@ class AccountStatusesFilter
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def suspended?
|
|
||||||
account.suspended?
|
|
||||||
end
|
|
||||||
|
|
||||||
def anonymous?
|
def anonymous?
|
||||||
current_account.nil?
|
current_account.nil?
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ class ActivityPub::Activity::Move < ActivityPub::Activity
|
||||||
|
|
||||||
target_account = ActivityPub::FetchRemoteAccountService.new.call(target_uri)
|
target_account = ActivityPub::FetchRemoteAccountService.new.call(target_uri)
|
||||||
|
|
||||||
if target_account.nil? || target_account.suspended? || !target_account.also_known_as.include?(origin_account.uri)
|
if target_account.nil? || target_account.unavailable? || !target_account.also_known_as.include?(origin_account.uri)
|
||||||
unmark_as_processing!
|
unmark_as_processing!
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,8 +9,8 @@ class ContentSecurityPolicy
|
||||||
url_from_configured_asset_host || url_from_base_host
|
url_from_configured_asset_host || url_from_base_host
|
||||||
end
|
end
|
||||||
|
|
||||||
def media_host
|
def media_hosts
|
||||||
cdn_host_value || assets_host
|
[assets_host, cdn_host_value].compact
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -459,7 +459,7 @@ class FeedManager
|
||||||
check_for_blocks.push(status.in_reply_to_account) if status.reply? && !status.in_reply_to_account_id.nil?
|
check_for_blocks.push(status.in_reply_to_account) if status.reply? && !status.in_reply_to_account_id.nil?
|
||||||
|
|
||||||
should_filter = blocks_or_mutes?(receiver_id, check_for_blocks, :mentions) # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted)
|
should_filter = blocks_or_mutes?(receiver_id, check_for_blocks, :mentions) # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted)
|
||||||
should_filter ||= (status.account.silenced? && !Follow.where(account_id: receiver_id, target_account_id: status.account_id).exists?) # of if the account is silenced and I'm not following them
|
should_filter ||= status.account.silenced? && !Follow.where(account_id: receiver_id, target_account_id: status.account_id).exists? # of if the account is silenced and I'm not following them
|
||||||
|
|
||||||
should_filter
|
should_filter
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,11 +27,11 @@ class Vacuum::MediaAttachmentsVacuum
|
||||||
end
|
end
|
||||||
|
|
||||||
def media_attachments_past_retention_period
|
def media_attachments_past_retention_period
|
||||||
MediaAttachment.unscoped.remote.cached.where(MediaAttachment.arel_table[:created_at].lt(@retention_period.ago)).where(MediaAttachment.arel_table[:updated_at].lt(@retention_period.ago))
|
MediaAttachment.remote.cached.where(MediaAttachment.arel_table[:created_at].lt(@retention_period.ago)).where(MediaAttachment.arel_table[:updated_at].lt(@retention_period.ago))
|
||||||
end
|
end
|
||||||
|
|
||||||
def orphaned_media_attachments
|
def orphaned_media_attachments
|
||||||
MediaAttachment.unscoped.unattached.where(MediaAttachment.arel_table[:created_at].lt(TTL.ago))
|
MediaAttachment.unattached.where(MediaAttachment.arel_table[:created_at].lt(TTL.ago))
|
||||||
end
|
end
|
||||||
|
|
||||||
def retention_period?
|
def retention_period?
|
||||||
|
|
|
@ -74,21 +74,22 @@ class Account < ApplicationRecord
|
||||||
URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
|
URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
|
||||||
USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i
|
USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i
|
||||||
|
|
||||||
include Attachmentable
|
include Attachmentable # Load prior to Avatar & Header concerns
|
||||||
include AccountAssociations
|
|
||||||
include AccountAvatar
|
include Account::Associations
|
||||||
include AccountFinderConcern
|
include Account::Avatar
|
||||||
include AccountHeader
|
include Account::Counters
|
||||||
include AccountInteractions
|
include Account::FinderConcern
|
||||||
include Paginable
|
include Account::Header
|
||||||
include AccountCounters
|
include Account::Interactions
|
||||||
include DomainNormalizable
|
include Account::Merging
|
||||||
|
include Account::Search
|
||||||
|
include Account::StatusesSearch
|
||||||
|
include Account::OtherSettings
|
||||||
|
include Account::MasterSettings
|
||||||
include DomainMaterializable
|
include DomainMaterializable
|
||||||
include AccountMerging
|
include DomainNormalizable
|
||||||
include AccountSearch
|
include Paginable
|
||||||
include AccountStatusesSearch
|
|
||||||
include AccountOtherSettings
|
|
||||||
include AccountMasterSettings
|
|
||||||
|
|
||||||
enum protocol: { ostatus: 0, activitypub: 1 }
|
enum protocol: { ostatus: 0, activitypub: 1 }
|
||||||
enum suspension_origin: { local: 0, remote: 1 }, _prefix: true
|
enum suspension_origin: { local: 0, remote: 1 }, _prefix: true
|
||||||
|
@ -273,6 +274,9 @@ class Account < ApplicationRecord
|
||||||
suspended? && deletion_request.present?
|
suspended? && deletion_request.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias unavailable? suspended?
|
||||||
|
alias permanently_unavailable? suspended_permanently?
|
||||||
|
|
||||||
def suspend!(date: Time.now.utc, origin: :local, block_email: true)
|
def suspend!(date: Time.now.utc, origin: :local, block_email: true)
|
||||||
transaction do
|
transaction do
|
||||||
create_deletion_request!
|
create_deletion_request!
|
||||||
|
|
|
@ -24,12 +24,12 @@ class Admin::ActionLog < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
belongs_to :target, polymorphic: true, optional: true
|
belongs_to :target, polymorphic: true, optional: true
|
||||||
|
|
||||||
default_scope -> { order('id desc') }
|
|
||||||
|
|
||||||
before_validation :set_human_identifier
|
before_validation :set_human_identifier
|
||||||
before_validation :set_route_param
|
before_validation :set_route_param
|
||||||
before_validation :set_permalink
|
before_validation :set_permalink
|
||||||
|
|
||||||
|
scope :latest, -> { order(id: :desc) }
|
||||||
|
|
||||||
def action
|
def action
|
||||||
super.to_sym
|
super.to_sym
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Admin::ActionLogFilter
|
||||||
end
|
end
|
||||||
|
|
||||||
def results
|
def results
|
||||||
scope = Admin::ActionLog.includes(:target)
|
scope = latest_action_logs.includes(:target)
|
||||||
|
|
||||||
params.each do |key, value|
|
params.each do |key, value|
|
||||||
next if key.to_s == 'page'
|
next if key.to_s == 'page'
|
||||||
|
@ -88,14 +88,18 @@ class Admin::ActionLogFilter
|
||||||
def scope_for(key, value)
|
def scope_for(key, value)
|
||||||
case key
|
case key
|
||||||
when 'action_type'
|
when 'action_type'
|
||||||
Admin::ActionLog.where(ACTION_TYPE_MAP[value.to_sym])
|
latest_action_logs.where(ACTION_TYPE_MAP[value.to_sym])
|
||||||
when 'account_id'
|
when 'account_id'
|
||||||
Admin::ActionLog.where(account_id: value)
|
latest_action_logs.where(account_id: value)
|
||||||
when 'target_account_id'
|
when 'target_account_id'
|
||||||
account = Account.find_or_initialize_by(id: value)
|
account = Account.find_or_initialize_by(id: value)
|
||||||
Admin::ActionLog.where(target: [account, account.user].compact)
|
latest_action_logs.where(target: [account, account.user].compact)
|
||||||
else
|
else
|
||||||
raise Mastodon::InvalidParameterError, "Unknown filter: #{key}"
|
raise Mastodon::InvalidParameterError, "Unknown filter: #{key}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def latest_action_logs
|
||||||
|
Admin::ActionLog.latest
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Admin::StatusFilter
|
||||||
def scope_for(key, _value)
|
def scope_for(key, _value)
|
||||||
case key.to_s
|
case key.to_s
|
||||||
when 'media'
|
when 'media'
|
||||||
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id).reorder('statuses.id desc')
|
Status.joins(:media_attachments).merge(@account.media_attachments).group(:id).reorder('statuses.id desc')
|
||||||
else
|
else
|
||||||
raise Mastodon::InvalidParameterError, "Unknown filter: #{key}"
|
raise Mastodon::InvalidParameterError, "Unknown filter: #{key}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountAssociations
|
module Account::Associations
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountAvatar
|
module Account::Avatar
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
|
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
|
|
@ -1,12 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountCounters
|
module Account::Counters
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
ALLOWED_COUNTER_KEYS = %i(statuses_count following_count followers_count).freeze
|
ALLOWED_COUNTER_KEYS = %i(statuses_count following_count followers_count).freeze
|
||||||
|
|
||||||
included do
|
included do
|
||||||
has_one :account_stat, inverse_of: :account
|
has_one :account_stat, inverse_of: :account, dependent: nil
|
||||||
after_save :save_account_stat
|
after_save :save_account_stat
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountFinderConcern
|
module Account::FinderConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountHeader
|
module Account::Header
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
|
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountInteractions
|
module Account::Interactions
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountMasterSettings
|
module Account::MasterSettings
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountMerging
|
module Account::Merging
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def merge_with!(other_account)
|
def merge_with!(other_account)
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountOtherSettings
|
module Account::OtherSettings
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountSearch
|
module Account::Search
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
DISALLOWED_TSQUERY_CHARACTERS = /['?\\:‘’]/
|
DISALLOWED_TSQUERY_CHARACTERS = /['?\\:‘’]/
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module AccountStatusesSearch
|
module Account::StatusesSearch
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -5,7 +5,7 @@ module Remotable
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
||||||
def remotable_attachment(attachment_name, limit, suppress_errors: true, download_on_assign: true, attribute_name: nil)
|
def remotable_attachment(attachment_name, limit, suppress_errors: true, download_on_assign: true, attribute_name: nil)
|
||||||
attribute_name ||= "#{attachment_name}_remote_url".to_sym
|
attribute_name ||= :"#{attachment_name}_remote_url"
|
||||||
|
|
||||||
define_method("download_#{attachment_name}!") do |url = nil|
|
define_method("download_#{attachment_name}!") do |url = nil|
|
||||||
url ||= self[attribute_name]
|
url ||= self[attribute_name]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module StatusSafeReblogInsert
|
module Status::SafeReblogInsert
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module StatusSearchConcern
|
module Status::SearchConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module StatusSnapshotConcern
|
module Status::SnapshotConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module StatusThreadingConcern
|
module Status::ThreadingConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def ancestors(limit, account = nil)
|
def ancestors(limit, account = nil)
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module HasUserSettings
|
module User::HasSettings
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module LdapAuthenticable
|
module User::LdapAuthenticable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
class_methods do
|
class_methods do
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Omniauthable
|
module User::Omniauthable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
TEMP_EMAIL_PREFIX = 'change@me'
|
TEMP_EMAIL_PREFIX = 'change@me'
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module PamAuthenticable
|
module User::PamAuthenticable
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
|
@ -15,7 +15,7 @@
|
||||||
class Conversation < ApplicationRecord
|
class Conversation < ApplicationRecord
|
||||||
validates :uri, uniqueness: true, if: :uri?
|
validates :uri, uniqueness: true, if: :uri?
|
||||||
|
|
||||||
has_many :statuses
|
has_many :statuses, dependent: nil
|
||||||
belongs_to :ancestor_status, class_name: 'Status', inverse_of: :owned_conversation, optional: true
|
belongs_to :ancestor_status, class_name: 'Status', inverse_of: :owned_conversation, optional: true
|
||||||
|
|
||||||
def local?
|
def local?
|
||||||
|
|
|
@ -39,7 +39,7 @@ class CustomEmoji < ApplicationRecord
|
||||||
IMAGE_MIME_TYPES = %w(image/png image/gif image/webp image/jpeg).freeze
|
IMAGE_MIME_TYPES = %w(image/png image/gif image/webp image/jpeg).freeze
|
||||||
|
|
||||||
belongs_to :category, class_name: 'CustomEmojiCategory', optional: true
|
belongs_to :category, class_name: 'CustomEmojiCategory', optional: true
|
||||||
has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode, inverse_of: false
|
has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode, inverse_of: false, dependent: nil
|
||||||
has_many :emoji_reactions, inverse_of: :custom_emoji, dependent: :destroy
|
has_many :emoji_reactions, inverse_of: :custom_emoji, dependent: :destroy
|
||||||
|
|
||||||
has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' } }, validate_media_type: false
|
has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' } }, validate_media_type: false
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class CustomEmojiCategory < ApplicationRecord
|
class CustomEmojiCategory < ApplicationRecord
|
||||||
has_many :emojis, class_name: 'CustomEmoji', foreign_key: 'category_id', inverse_of: :category
|
has_many :emojis, class_name: 'CustomEmoji', foreign_key: 'category_id', inverse_of: :category, dependent: nil
|
||||||
|
|
||||||
validates :name, presence: true, uniqueness: true
|
validates :name, presence: true, uniqueness: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,7 +40,7 @@ class DomainBlock < ApplicationRecord
|
||||||
|
|
||||||
validates :domain, presence: true, uniqueness: true, domain: true
|
validates :domain, presence: true, uniqueness: true, domain: true
|
||||||
|
|
||||||
has_many :accounts, foreign_key: :domain, primary_key: :domain, inverse_of: false
|
has_many :accounts, foreign_key: :domain, primary_key: :domain, inverse_of: false, dependent: nil
|
||||||
delegate :count, to: :accounts, prefix: true
|
delegate :count, to: :accounts, prefix: true
|
||||||
|
|
||||||
scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
|
scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) }
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Invite < ApplicationRecord
|
||||||
include Expireable
|
include Expireable
|
||||||
|
|
||||||
belongs_to :user, inverse_of: :invites
|
belongs_to :user, inverse_of: :invites
|
||||||
has_many :users, inverse_of: :invite
|
has_many :users, inverse_of: :invite, dependent: nil
|
||||||
|
|
||||||
scope :available, -> { where(expires_at: nil).or(where('expires_at >= ?', Time.now.utc)) }
|
scope :available, -> { where(expires_at: nil).or(where('expires_at >= ?', Time.now.utc)) }
|
||||||
|
|
||||||
|
|
|
@ -210,13 +210,11 @@ class MediaAttachment < ApplicationRecord
|
||||||
validates :thumbnail, absence: true, if: -> { local? && !audio_or_video? }
|
validates :thumbnail, absence: true, if: -> { local? && !audio_or_video? }
|
||||||
|
|
||||||
scope :attached, -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) }
|
scope :attached, -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) }
|
||||||
scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) }
|
|
||||||
scope :local, -> { where(remote_url: '') }
|
|
||||||
scope :remote, -> { where.not(remote_url: '') }
|
|
||||||
scope :cached, -> { remote.where.not(file_file_name: nil) }
|
scope :cached, -> { remote.where.not(file_file_name: nil) }
|
||||||
scope :local_attached, -> { attached.where(remote_url: '') }
|
scope :local, -> { where(remote_url: '') }
|
||||||
|
scope :ordered, -> { order(id: :asc) }
|
||||||
default_scope { order(id: :asc) }
|
scope :remote, -> { where.not(remote_url: '') }
|
||||||
|
scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) }
|
||||||
|
|
||||||
attr_accessor :skip_download
|
attr_accessor :skip_download
|
||||||
|
|
||||||
|
|
|
@ -131,25 +131,25 @@ class Report < ApplicationRecord
|
||||||
Admin::ActionLog.where(
|
Admin::ActionLog.where(
|
||||||
target_type: 'Report',
|
target_type: 'Report',
|
||||||
target_id: id
|
target_id: id
|
||||||
).unscope(:order).arel,
|
).arel,
|
||||||
|
|
||||||
Admin::ActionLog.where(
|
Admin::ActionLog.where(
|
||||||
target_type: 'Account',
|
target_type: 'Account',
|
||||||
target_id: target_account_id
|
target_id: target_account_id
|
||||||
).unscope(:order).arel,
|
).arel,
|
||||||
|
|
||||||
Admin::ActionLog.where(
|
Admin::ActionLog.where(
|
||||||
target_type: 'Status',
|
target_type: 'Status',
|
||||||
target_id: status_ids
|
target_id: status_ids
|
||||||
).unscope(:order).arel,
|
).arel,
|
||||||
|
|
||||||
Admin::ActionLog.where(
|
Admin::ActionLog.where(
|
||||||
target_type: 'AccountWarning',
|
target_type: 'AccountWarning',
|
||||||
target_id: AccountWarning.where(report_id: id).select(:id)
|
target_id: AccountWarning.where(report_id: id).select(:id)
|
||||||
).unscope(:order).arel,
|
).arel,
|
||||||
].reduce { |union, query| Arel::Nodes::UnionAll.new(union, query) }
|
].reduce { |union, query| Arel::Nodes::UnionAll.new(union, query) }
|
||||||
|
|
||||||
Admin::ActionLog.from(Arel::Nodes::As.new(subquery, Admin::ActionLog.arel_table))
|
Admin::ActionLog.latest.from(Arel::Nodes::As.new(subquery, Admin::ActionLog.arel_table))
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -36,14 +36,14 @@
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
|
||||||
class Status < ApplicationRecord
|
class Status < ApplicationRecord
|
||||||
|
include Cacheable
|
||||||
include Discard::Model
|
include Discard::Model
|
||||||
include Paginable
|
include Paginable
|
||||||
include Cacheable
|
|
||||||
include StatusThreadingConcern
|
|
||||||
include StatusSnapshotConcern
|
|
||||||
include RateLimitable
|
include RateLimitable
|
||||||
include StatusSafeReblogInsert
|
include Status::SafeReblogInsert
|
||||||
include StatusSearchConcern
|
include Status::SearchConcern
|
||||||
|
include Status::SnapshotConcern
|
||||||
|
include Status::ThreadingConcern
|
||||||
include DtlHelper
|
include DtlHelper
|
||||||
|
|
||||||
rate_limit by: :account, family: :statuses
|
rate_limit by: :account, family: :statuses
|
||||||
|
@ -78,13 +78,11 @@ class Status < ApplicationRecord
|
||||||
has_many :bookmarks, inverse_of: :status, dependent: :destroy
|
has_many :bookmarks, inverse_of: :status, dependent: :destroy
|
||||||
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy
|
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy
|
||||||
has_many :reblogged_by_accounts, through: :reblogs, class_name: 'Account', source: :account
|
has_many :reblogged_by_accounts, through: :reblogs, class_name: 'Account', source: :account
|
||||||
has_many :quotes, foreign_key: 'quote_of_id', class_name: 'Status', inverse_of: :quote
|
has_many :quotes, foreign_key: 'quote_of_id', class_name: 'Status', inverse_of: :quote, dependent: nil
|
||||||
has_many :quoted_by_accounts, through: :quotes, class_name: 'Account', source: :account
|
has_many :quoted_by_accounts, through: :quotes, class_name: 'Account', source: :account
|
||||||
has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :thread
|
has_many :replies, foreign_key: 'in_reply_to_id', class_name: 'Status', inverse_of: :thread, dependent: nil
|
||||||
has_many :mentions, dependent: :destroy, inverse_of: :status
|
has_many :mentions, dependent: :destroy, inverse_of: :status
|
||||||
has_many :mentioned_accounts, through: :mentions, source: :account, class_name: 'Account'
|
has_many :mentioned_accounts, through: :mentions, source: :account, class_name: 'Account'
|
||||||
has_many :active_mentions, -> { active }, class_name: 'Mention', inverse_of: :status
|
|
||||||
has_many :silent_mentions, -> { silent }, class_name: 'Mention', inverse_of: :status
|
|
||||||
has_many :media_attachments, dependent: :nullify
|
has_many :media_attachments, dependent: :nullify
|
||||||
has_many :reference_objects, class_name: 'StatusReference', inverse_of: :status, dependent: :destroy
|
has_many :reference_objects, class_name: 'StatusReference', inverse_of: :status, dependent: :destroy
|
||||||
has_many :references, through: :reference_objects, class_name: 'Status', source: :target_status
|
has_many :references, through: :reference_objects, class_name: 'Status', source: :target_status
|
||||||
|
@ -95,6 +93,10 @@ class Status < ApplicationRecord
|
||||||
has_many :bookmark_categories, class_name: 'BookmarkCategory', through: :bookmark_category_relationships, source: :bookmark_category
|
has_many :bookmark_categories, class_name: 'BookmarkCategory', through: :bookmark_category_relationships, source: :bookmark_category
|
||||||
has_many :joined_bookmark_categories, class_name: 'BookmarkCategory', through: :bookmark_category_relationships, source: :bookmark_category
|
has_many :joined_bookmark_categories, class_name: 'BookmarkCategory', through: :bookmark_category_relationships, source: :bookmark_category
|
||||||
|
|
||||||
|
# The `dependent` option is enabled by the initial `mentions` association declaration
|
||||||
|
has_many :active_mentions, -> { active }, class_name: 'Mention', inverse_of: :status # rubocop:disable Rails/HasManyOrHasOneDependent
|
||||||
|
has_many :silent_mentions, -> { silent }, class_name: 'Mention', inverse_of: :status # rubocop:disable Rails/HasManyOrHasOneDependent
|
||||||
|
|
||||||
# Those associations are used for the private search index
|
# Those associations are used for the private search index
|
||||||
has_many :local_mentioned, -> { merge(Account.local) }, through: :active_mentions, source: :account
|
has_many :local_mentioned, -> { merge(Account.local) }, through: :active_mentions, source: :account
|
||||||
has_many :local_favorited, -> { merge(Account.local) }, through: :favourites, source: :account
|
has_many :local_favorited, -> { merge(Account.local) }, through: :favourites, source: :account
|
||||||
|
@ -106,11 +108,13 @@ class Status < ApplicationRecord
|
||||||
|
|
||||||
has_and_belongs_to_many :tags
|
has_and_belongs_to_many :tags
|
||||||
|
|
||||||
has_one :preview_cards_status, inverse_of: :status # Because of a composite primary key, the dependent option cannot be used
|
# Because of a composite primary key, the `dependent` option cannot be used on this association
|
||||||
|
has_one :preview_cards_status, inverse_of: :status # rubocop:disable Rails/HasManyOrHasOneDependent
|
||||||
|
|
||||||
has_one :notification, as: :activity, dependent: :destroy
|
has_one :notification, as: :activity, dependent: :destroy
|
||||||
has_one :status_stat, inverse_of: :status
|
has_one :status_stat, inverse_of: :status, dependent: nil
|
||||||
has_one :poll, inverse_of: :status, dependent: :destroy
|
has_one :poll, inverse_of: :status, dependent: :destroy
|
||||||
has_one :trend, class_name: 'StatusTrend', inverse_of: :status
|
has_one :trend, class_name: 'StatusTrend', inverse_of: :status, dependent: nil
|
||||||
has_one :scheduled_expiration_status, inverse_of: :status, dependent: :destroy
|
has_one :scheduled_expiration_status, inverse_of: :status, dependent: :destroy
|
||||||
has_one :circle_status, inverse_of: :status, dependent: :destroy
|
has_one :circle_status, inverse_of: :status, dependent: :destroy
|
||||||
has_many :list_status, inverse_of: :status, dependent: :destroy
|
has_many :list_status, inverse_of: :status, dependent: :destroy
|
||||||
|
|
|
@ -37,7 +37,7 @@ class Trends::History
|
||||||
end
|
end
|
||||||
|
|
||||||
def uses
|
def uses
|
||||||
with_redis { |redis| redis.get(key_for(:uses))&.to_i || 0 }
|
with_redis { |redis| redis.get(key_for(:uses)).to_i }
|
||||||
end
|
end
|
||||||
|
|
||||||
def add(account_id)
|
def add(account_id)
|
||||||
|
|
|
@ -53,9 +53,12 @@ class User < ApplicationRecord
|
||||||
filtered_languages
|
filtered_languages
|
||||||
)
|
)
|
||||||
|
|
||||||
include Redisable
|
|
||||||
include LanguagesHelper
|
include LanguagesHelper
|
||||||
include HasUserSettings
|
include Redisable
|
||||||
|
include User::HasSettings
|
||||||
|
include User::LdapAuthenticable
|
||||||
|
include User::Omniauthable
|
||||||
|
include User::PamAuthenticable
|
||||||
|
|
||||||
# The home and list feeds will be stored in Redis for this amount
|
# The home and list feeds will be stored in Redis for this amount
|
||||||
# of time, and status fan-out to followers will include only people
|
# of time, and status fan-out to followers will include only people
|
||||||
|
@ -77,22 +80,18 @@ class User < ApplicationRecord
|
||||||
devise :registerable, :recoverable, :validatable,
|
devise :registerable, :recoverable, :validatable,
|
||||||
:confirmable
|
:confirmable
|
||||||
|
|
||||||
include Omniauthable
|
|
||||||
include PamAuthenticable
|
|
||||||
include LdapAuthenticable
|
|
||||||
|
|
||||||
belongs_to :account, inverse_of: :user
|
belongs_to :account, inverse_of: :user
|
||||||
belongs_to :invite, counter_cache: :uses, optional: true
|
belongs_to :invite, counter_cache: :uses, optional: true
|
||||||
belongs_to :created_by_application, class_name: 'Doorkeeper::Application', optional: true
|
belongs_to :created_by_application, class_name: 'Doorkeeper::Application', optional: true
|
||||||
belongs_to :role, class_name: 'UserRole', optional: true
|
belongs_to :role, class_name: 'UserRole', optional: true
|
||||||
accepts_nested_attributes_for :account
|
accepts_nested_attributes_for :account
|
||||||
|
|
||||||
has_many :applications, class_name: 'Doorkeeper::Application', as: :owner
|
has_many :applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: nil
|
||||||
has_many :backups, inverse_of: :user
|
has_many :backups, inverse_of: :user, dependent: nil
|
||||||
has_many :invites, inverse_of: :user
|
has_many :invites, inverse_of: :user, dependent: nil
|
||||||
has_many :markers, inverse_of: :user, dependent: :destroy
|
has_many :markers, inverse_of: :user, dependent: :destroy
|
||||||
has_many :webauthn_credentials, dependent: :destroy
|
has_many :webauthn_credentials, dependent: :destroy
|
||||||
has_many :ips, class_name: 'UserIp', inverse_of: :user
|
has_many :ips, class_name: 'UserIp', inverse_of: :user, dependent: nil
|
||||||
|
|
||||||
has_one :invite_request, class_name: 'UserInviteRequest', inverse_of: :user, dependent: :destroy
|
has_one :invite_request, class_name: 'UserInviteRequest', inverse_of: :user, dependent: :destroy
|
||||||
accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? && !Setting.require_invite_text }
|
accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? && !Setting.require_invite_text }
|
||||||
|
@ -252,7 +251,7 @@ class User < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def functional_or_moved?
|
def functional_or_moved?
|
||||||
confirmed? && approved? && !disabled? && !account.suspended? && !account.memorial?
|
confirmed? && approved? && !disabled? && !account.unavailable? && !account.memorial?
|
||||||
end
|
end
|
||||||
|
|
||||||
def unconfirmed?
|
def unconfirmed?
|
||||||
|
|
|
@ -51,7 +51,7 @@ class UserRole < ApplicationRecord
|
||||||
invite_users
|
invite_users
|
||||||
).freeze,
|
).freeze,
|
||||||
|
|
||||||
moderation: %w(
|
moderation: %i(
|
||||||
view_dashboard
|
view_dashboard
|
||||||
view_audit_log
|
view_audit_log
|
||||||
manage_users
|
manage_users
|
||||||
|
@ -67,7 +67,7 @@ class UserRole < ApplicationRecord
|
||||||
manage_sensitive_words
|
manage_sensitive_words
|
||||||
).freeze,
|
).freeze,
|
||||||
|
|
||||||
administration: %w(
|
administration: %i(
|
||||||
manage_settings
|
manage_settings
|
||||||
manage_rules
|
manage_rules
|
||||||
manage_roles
|
manage_roles
|
||||||
|
@ -76,7 +76,7 @@ class UserRole < ApplicationRecord
|
||||||
manage_announcements
|
manage_announcements
|
||||||
).freeze,
|
).freeze,
|
||||||
|
|
||||||
devops: %w(
|
devops: %i(
|
||||||
view_devops
|
view_devops
|
||||||
).freeze,
|
).freeze,
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ class UserSettings::Setting
|
||||||
|
|
||||||
def key
|
def key
|
||||||
if namespace
|
if namespace
|
||||||
"#{namespace}.#{name}".to_sym
|
:"#{namespace}.#{name}"
|
||||||
else
|
else
|
||||||
name
|
name
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Web::PushSubscription < ApplicationRecord
|
||||||
belongs_to :user, optional: true
|
belongs_to :user, optional: true
|
||||||
belongs_to :access_token, class_name: 'Doorkeeper::AccessToken', optional: true
|
belongs_to :access_token, class_name: 'Doorkeeper::AccessToken', optional: true
|
||||||
|
|
||||||
has_one :session_activation, foreign_key: 'web_push_subscription_id', inverse_of: :web_push_subscription
|
has_one :session_activation, foreign_key: 'web_push_subscription_id', inverse_of: :web_push_subscription, dependent: nil
|
||||||
|
|
||||||
validates :endpoint, presence: true
|
validates :endpoint, presence: true
|
||||||
validates :key_p256dh, presence: true
|
validates :key_p256dh, presence: true
|
||||||
|
|
|
@ -11,7 +11,7 @@ class StatusPolicy < ApplicationPolicy
|
||||||
delegate :reply?, :expired?, to: :record
|
delegate :reply?, :expired?, to: :record
|
||||||
|
|
||||||
def show?
|
def show?
|
||||||
return false if author.suspended?
|
return false if author.unavailable?
|
||||||
|
|
||||||
if requires_mention?
|
if requires_mention?
|
||||||
owned? || mention_exists?
|
owned? || mention_exists?
|
||||||
|
|
|
@ -104,19 +104,19 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def original_discoverable
|
def original_discoverable
|
||||||
object.suspended? ? false : (object.discoverable || false)
|
object.unavailable? ? false : (object.discoverable || false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def indexable
|
def indexable
|
||||||
object.suspended? ? false : (object.indexable || false)
|
object.unavailable? ? false : (object.indexable || false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
object.suspended? ? object.username : (object.display_name.presence || object.username)
|
object.unavailable? ? object.username : (object.display_name.presence || object.username)
|
||||||
end
|
end
|
||||||
|
|
||||||
def summary
|
def summary
|
||||||
object.suspended? ? '' : account_bio_format(object)
|
object.unavailable? ? '' : account_bio_format(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
def icon
|
def icon
|
||||||
|
@ -140,23 +140,23 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def avatar_exists?
|
def avatar_exists?
|
||||||
!object.suspended? && object.avatar?
|
!object.unavailable? && object.avatar?
|
||||||
end
|
end
|
||||||
|
|
||||||
def header_exists?
|
def header_exists?
|
||||||
!object.suspended? && object.header?
|
!object.unavailable? && object.header?
|
||||||
end
|
end
|
||||||
|
|
||||||
def manually_approves_followers
|
def manually_approves_followers
|
||||||
object.suspended? ? false : object.locked
|
object.unavailable? ? false : object.locked
|
||||||
end
|
end
|
||||||
|
|
||||||
def virtual_tags
|
def virtual_tags
|
||||||
object.suspended? ? [] : (object.emojis + object.tags)
|
object.unavailable? ? [] : (object.emojis + object.tags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def virtual_attachments
|
def virtual_attachments
|
||||||
object.suspended? ? [] : object.fields
|
object.unavailable? ? [] : object.fields
|
||||||
end
|
end
|
||||||
|
|
||||||
def moved_to
|
def moved_to
|
||||||
|
@ -164,11 +164,11 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def moved?
|
def moved?
|
||||||
!object.suspended? && object.moved?
|
!object.unavailable? && object.moved?
|
||||||
end
|
end
|
||||||
|
|
||||||
def also_known_as?
|
def also_known_as?
|
||||||
!object.suspended? && !object.also_known_as.empty?
|
!object.unavailable? && !object.also_known_as.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def published
|
def published
|
||||||
|
|
|
@ -43,32 +43,32 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
if object.current_account
|
if object.current_account
|
||||||
store[:me] = object.current_account.id.to_s
|
store[:me] = object.current_account.id.to_s
|
||||||
store[:unfollow_modal] = object.current_account.user.setting_unfollow_modal
|
store[:unfollow_modal] = object_account_user.setting_unfollow_modal
|
||||||
store[:boost_modal] = object.current_account.user.setting_boost_modal
|
store[:boost_modal] = object_account_user.setting_boost_modal
|
||||||
store[:delete_modal] = object.current_account.user.setting_delete_modal
|
store[:delete_modal] = object_account_user.setting_delete_modal
|
||||||
store[:auto_play_gif] = object.current_account.user.setting_auto_play_gif
|
store[:auto_play_gif] = object_account_user.setting_auto_play_gif
|
||||||
store[:display_media] = object.current_account.user.setting_display_media
|
store[:display_media] = object_account_user.setting_display_media
|
||||||
store[:display_media_expand] = object.current_account.user.setting_display_media_expand
|
store[:display_media_expand] = object_account_user.setting_display_media_expand
|
||||||
store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
|
store[:expand_spoilers] = object_account_user.setting_expand_spoilers
|
||||||
store[:enable_emoji_reaction] = object.current_account.user.setting_enable_emoji_reaction && Setting.enable_emoji_reaction
|
store[:enable_emoji_reaction] = object_account_user.setting_enable_emoji_reaction && Setting.enable_emoji_reaction
|
||||||
store[:enable_login_privacy] = object.current_account.user.setting_enable_login_privacy
|
store[:enable_login_privacy] = object_account_user.setting_enable_login_privacy
|
||||||
store[:enable_dtl_menu] = object.current_account.user.setting_enable_dtl_menu
|
store[:enable_dtl_menu] = object_account_user.setting_enable_dtl_menu
|
||||||
store[:reduce_motion] = object.current_account.user.setting_reduce_motion
|
store[:reduce_motion] = object_account_user.setting_reduce_motion
|
||||||
store[:disable_swiping] = object.current_account.user.setting_disable_swiping
|
store[:disable_swiping] = object_account_user.setting_disable_swiping
|
||||||
store[:advanced_layout] = object.current_account.user.setting_advanced_layout
|
store[:advanced_layout] = object_account_user.setting_advanced_layout
|
||||||
store[:use_blurhash] = object.current_account.user.setting_use_blurhash
|
store[:use_blurhash] = object_account_user.setting_use_blurhash
|
||||||
store[:use_pending_items] = object.current_account.user.setting_use_pending_items
|
store[:use_pending_items] = object_account_user.setting_use_pending_items
|
||||||
store[:show_trends] = Setting.trends && object.current_account.user.setting_trends
|
store[:show_trends] = Setting.trends && object_account_user.setting_trends
|
||||||
store[:bookmark_category_needed] = object.current_account.user.setting_bookmark_category_needed
|
store[:bookmark_category_needed] = object_account_user.setting_bookmark_category_needed
|
||||||
store[:simple_timeline_menu] = object.current_account.user.setting_simple_timeline_menu
|
store[:simple_timeline_menu] = object_account_user.setting_simple_timeline_menu
|
||||||
store[:hide_items] = [
|
store[:hide_items] = [
|
||||||
object.current_account.user.setting_hide_favourite_menu ? 'favourite_menu' : nil,
|
object_account_user.setting_hide_favourite_menu ? 'favourite_menu' : nil,
|
||||||
object.current_account.user.setting_hide_recent_emojis ? 'recent_emojis' : nil,
|
object_account_user.setting_hide_recent_emojis ? 'recent_emojis' : nil,
|
||||||
object.current_account.user.setting_hide_blocking_quote ? 'blocking_quote' : nil,
|
object_account_user.setting_hide_blocking_quote ? 'blocking_quote' : nil,
|
||||||
object.current_account.user.setting_hide_emoji_reaction_unavailable_server ? 'emoji_reaction_unavailable_server' : nil,
|
object_account_user.setting_hide_emoji_reaction_unavailable_server ? 'emoji_reaction_unavailable_server' : nil,
|
||||||
object.current_account.user.setting_show_emoji_reaction_on_timeline ? nil : 'emoji_reaction_on_timeline',
|
object_account_user.setting_show_emoji_reaction_on_timeline ? nil : 'emoji_reaction_on_timeline',
|
||||||
object.current_account.user.setting_show_quote_in_home ? nil : 'quote_in_home',
|
object_account_user.setting_show_quote_in_home ? nil : 'quote_in_home',
|
||||||
object.current_account.user.setting_show_quote_in_public ? nil : 'quote_in_public',
|
object_account_user.setting_show_quote_in_public ? nil : 'quote_in_public',
|
||||||
].compact
|
].compact
|
||||||
else
|
else
|
||||||
store[:auto_play_gif] = Setting.auto_play_gif
|
store[:auto_play_gif] = Setting.auto_play_gif
|
||||||
|
@ -94,11 +94,11 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
if object.current_account
|
if object.current_account
|
||||||
store[:me] = object.current_account.id.to_s
|
store[:me] = object.current_account.id.to_s
|
||||||
store[:default_privacy] = object.visibility || object.current_account.user.setting_default_privacy
|
store[:default_privacy] = object.visibility || object_account_user.setting_default_privacy
|
||||||
store[:stay_privacy] = object.current_account.user.setting_stay_privacy
|
store[:stay_privacy] = object_account_user.setting_stay_privacy
|
||||||
store[:default_searchability] = object.searchability || object.current_account.user.setting_default_searchability
|
store[:default_searchability] = object.searchability || object_account_user.setting_default_searchability
|
||||||
store[:default_sensitive] = object.current_account.user.setting_default_sensitive
|
store[:default_sensitive] = object_account_user.setting_default_sensitive
|
||||||
store[:default_language] = object.current_account.user.preferred_posting_language
|
store[:default_language] = object_account_user.preferred_posting_language
|
||||||
end
|
end
|
||||||
|
|
||||||
store[:text] = object.text if object.text
|
store[:text] = object.text if object.text
|
||||||
|
@ -114,11 +114,11 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
associations: [:account_stat, :user, { moved_to_account: [:account_stat, :user] }]
|
associations: [:account_stat, :user, { moved_to_account: [:account_stat, :user] }]
|
||||||
)
|
)
|
||||||
|
|
||||||
store[object.current_account.id.to_s] = ActiveModelSerializers::SerializableResource.new(object.current_account, serializer: REST::AccountSerializer) if object.current_account
|
store[object.current_account.id.to_s] = serialized_account(object.current_account) if object.current_account
|
||||||
store[object.admin.id.to_s] = ActiveModelSerializers::SerializableResource.new(object.admin, serializer: REST::AccountSerializer) if object.admin
|
store[object.admin.id.to_s] = serialized_account(object.admin) if object.admin
|
||||||
store[object.owner.id.to_s] = ActiveModelSerializers::SerializableResource.new(object.owner, serializer: REST::AccountSerializer) if object.owner
|
store[object.owner.id.to_s] = serialized_account(object.owner) if object.owner
|
||||||
store[object.disabled_account.id.to_s] = ActiveModelSerializers::SerializableResource.new(object.disabled_account, serializer: REST::AccountSerializer) if object.disabled_account
|
store[object.disabled_account.id.to_s] = serialized_account(object.disabled_account) if object.disabled_account
|
||||||
store[object.moved_to_account.id.to_s] = ActiveModelSerializers::SerializableResource.new(object.moved_to_account, serializer: REST::AccountSerializer) if object.moved_to_account
|
store[object.moved_to_account.id.to_s] = serialized_account(object.moved_to_account) if object.moved_to_account
|
||||||
|
|
||||||
store
|
store
|
||||||
end
|
end
|
||||||
|
@ -133,6 +133,14 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def object_account_user
|
||||||
|
object.current_account.user
|
||||||
|
end
|
||||||
|
|
||||||
|
def serialized_account(account)
|
||||||
|
ActiveModelSerializers::SerializableResource.new(account, serializer: REST::AccountSerializer)
|
||||||
|
end
|
||||||
|
|
||||||
def instance_presenter
|
def instance_presenter
|
||||||
@instance_presenter ||= InstancePresenter.new
|
@instance_presenter ||= InstancePresenter.new
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,7 +60,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def note
|
def note
|
||||||
object.suspended? ? '' : account_bio_format(object)
|
object.unavailable? ? '' : account_bio_format(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
|
@ -72,19 +72,19 @@ class REST::AccountSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def avatar
|
def avatar
|
||||||
full_asset_url(object.suspended? ? object.avatar.default_url : object.avatar_original_url)
|
full_asset_url(object.unavailable? ? object.avatar.default_url : object.avatar_original_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def avatar_static
|
def avatar_static
|
||||||
full_asset_url(object.suspended? ? object.avatar.default_url : object.avatar_static_url)
|
full_asset_url(object.unavailable? ? object.avatar.default_url : object.avatar_static_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def header
|
def header
|
||||||
full_asset_url(object.suspended? ? object.header.default_url : object.header_original_url)
|
full_asset_url(object.unavailable? ? object.header.default_url : object.header_original_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def header_static
|
def header_static
|
||||||
full_asset_url(object.suspended? ? object.header.default_url : object.header_static_url)
|
full_asset_url(object.unavailable? ? object.header.default_url : object.header_static_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def created_at
|
def created_at
|
||||||
|
@ -96,19 +96,19 @@ class REST::AccountSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def display_name
|
def display_name
|
||||||
object.suspended? ? '' : object.display_name
|
object.unavailable? ? '' : object.display_name
|
||||||
end
|
end
|
||||||
|
|
||||||
def locked
|
def locked
|
||||||
object.suspended? ? false : object.locked
|
object.unavailable? ? false : object.locked
|
||||||
end
|
end
|
||||||
|
|
||||||
def bot
|
def bot
|
||||||
object.suspended? ? false : object.bot
|
object.unavailable? ? false : object.bot
|
||||||
end
|
end
|
||||||
|
|
||||||
def discoverable
|
def discoverable
|
||||||
object.suspended? ? false : object.discoverable
|
object.unavailable? ? false : object.discoverable
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscribable
|
def subscribable
|
||||||
|
@ -116,23 +116,23 @@ class REST::AccountSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def indexable
|
def indexable
|
||||||
object.suspended? ? false : object.indexable
|
object.unavailable? ? false : object.indexable
|
||||||
end
|
end
|
||||||
|
|
||||||
def moved_to_account
|
def moved_to_account
|
||||||
object.suspended? ? nil : AccountDecorator.new(object.moved_to_account)
|
object.unavailable? ? nil : AccountDecorator.new(object.moved_to_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def emojis
|
def emojis
|
||||||
object.suspended? ? [] : object.emojis
|
object.unavailable? ? [] : object.emojis
|
||||||
end
|
end
|
||||||
|
|
||||||
def fields
|
def fields
|
||||||
object.suspended? ? [] : object.fields
|
object.unavailable? ? [] : object.fields
|
||||||
end
|
end
|
||||||
|
|
||||||
def suspended
|
def suspended
|
||||||
object.suspended?
|
object.unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def silenced
|
def silenced
|
||||||
|
@ -144,7 +144,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def roles
|
def roles
|
||||||
if object.suspended? || object.user.nil?
|
if object.unavailable? || object.user.nil?
|
||||||
[]
|
[]
|
||||||
else
|
else
|
||||||
[object.user.role].compact.filter(&:highlighted?)
|
[object.user.role].compact.filter(&:highlighted?)
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
|
|
||||||
class REST::ApplicationSerializer < ActiveModel::Serializer
|
class REST::ApplicationSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :name, :website, :scopes, :redirect_uri,
|
attributes :id, :name, :website, :scopes, :redirect_uri,
|
||||||
:client_id, :client_secret, :vapid_key
|
:client_id, :client_secret
|
||||||
|
|
||||||
|
# NOTE: Deprecated in 4.3.0, needs to be removed in 5.0.0
|
||||||
|
attribute :vapid_key
|
||||||
|
|
||||||
def id
|
def id
|
||||||
object.id.to_s
|
object.id.to_s
|
||||||
|
|
|
@ -49,6 +49,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
||||||
status: object.status_page_url,
|
status: object.status_page_url,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
vapid: {
|
||||||
|
public_key: Rails.configuration.x.vapid_public_key,
|
||||||
|
},
|
||||||
|
|
||||||
accounts: {
|
accounts: {
|
||||||
max_featured_tags: FeaturedTag::LIMIT,
|
max_featured_tags: FeaturedTag::LIMIT,
|
||||||
},
|
},
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue