Merge commit '272592d16d40e804ec325ef3b5e6de9bbad5f2dd' into glitch-soc/merge-upstream
Conflicts: - `.rubocop_todo.yml`: Upstream fixed a bunch lint issues, and changed the `Max` parameter of the `Metrics/AbcSize` cop. Glitch-soc has different code and slightly higher `AbcSize` complexity, modified the `.rubocop_todo.yml` file accordingly. - `app/policies/status_policy.rb`: Upstream changed `account.suspended?` to `account.unavailable?` to prepare for delete flags. Glitch-soc has additional local-only conditions. Ported upstream's refactor while keeping glitch-soc's additional condition. - `app/serializers/initial_state_serializer.rb`: Upstream refactored a bunch of stuff while glitch-soc has more settings. Refactored as upstream did while keeping glitch-soc's settings.shrike
commit
75580360cd
|
@ -26,9 +26,7 @@ Lint/NonLocalExitFromIterator:
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 144
|
Max: 130
|
||||||
Exclude:
|
|
||||||
- 'app/serializers/initial_state_serializer.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: CountBlocks, Max.
|
# Configuration parameters: CountBlocks, Max.
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
|
@ -109,7 +107,7 @@ 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'
|
||||||
|
@ -118,7 +116,7 @@ Rails/HasAndBelongsToMany:
|
||||||
# Include: app/models/**/*.rb
|
# Include: app/models/**/*.rb
|
||||||
Rails/HasManyOrHasOneDependent:
|
Rails/HasManyOrHasOneDependent:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/models/concerns/account_counters.rb'
|
- 'app/models/concerns/account/counters.rb'
|
||||||
- 'app/models/conversation.rb'
|
- 'app/models/conversation.rb'
|
||||||
- 'app/models/custom_emoji.rb'
|
- 'app/models/custom_emoji.rb'
|
||||||
- 'app/models/custom_emoji_category.rb'
|
- 'app/models/custom_emoji_category.rb'
|
||||||
|
@ -174,7 +172,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 +252,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'
|
||||||
|
@ -344,8 +342,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'
|
||||||
|
@ -374,8 +372,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,7 +486,7 @@ 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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
||||||
|
|
|
@ -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?
|
||||||
|
@ -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
|
||||||
|
|
|
@ -19,7 +19,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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
@ -125,7 +125,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
|
||||||
|
|
|
@ -11,7 +11,7 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
prepend_before_action :set_pack
|
prepend_before_action :set_pack
|
||||||
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
|
|
@ -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
|
|
@ -36,7 +36,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
|
||||||
|
|
|
@ -23,6 +23,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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -32,7 +32,7 @@ class AccountStatusesFilter
|
||||||
private
|
private
|
||||||
|
|
||||||
def initial_scope
|
def initial_scope
|
||||||
return Status.none if suspended?
|
return Status.none if account.unavailable?
|
||||||
|
|
||||||
if anonymous?
|
if anonymous?
|
||||||
account.statuses.not_local_only.where(visibility: %i(public unlisted))
|
account.statuses.not_local_only.where(visibility: %i(public unlisted))
|
||||||
|
@ -95,10 +95,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
|
||||||
|
|
|
@ -70,19 +70,20 @@ 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 DomainMaterializable
|
include DomainMaterializable
|
||||||
include AccountMerging
|
include DomainNormalizable
|
||||||
include AccountSearch
|
include Paginable
|
||||||
include AccountStatusesSearch
|
|
||||||
|
|
||||||
MAX_DISPLAY_NAME_LENGTH = (ENV['MAX_DISPLAY_NAME_CHARS'] || 30).to_i
|
MAX_DISPLAY_NAME_LENGTH = (ENV['MAX_DISPLAY_NAME_CHARS'] || 30).to_i
|
||||||
MAX_NOTE_LENGTH = (ENV['MAX_BIO_CHARS'] || 500).to_i
|
MAX_NOTE_LENGTH = (ENV['MAX_BIO_CHARS'] || 500).to_i
|
||||||
|
@ -250,6 +251,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!
|
||||||
|
|
|
@ -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,6 +1,6 @@
|
||||||
# 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
|
|
@ -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 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 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
|
|
@ -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
|
|
@ -32,14 +32,14 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
rate_limit by: :account, family: :statuses
|
rate_limit by: :account, family: :statuses
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
@ -75,10 +78,6 @@ 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
|
||||||
|
@ -250,7 +249,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?
|
||||||
|
|
|
@ -8,7 +8,7 @@ class StatusPolicy < ApplicationPolicy
|
||||||
end
|
end
|
||||||
|
|
||||||
def show?
|
def show?
|
||||||
return false if author.suspended?
|
return false if author.unavailable?
|
||||||
return false if local_only? && (current_account.nil? || !current_account.local?)
|
return false if local_only? && (current_account.nil? || !current_account.local?)
|
||||||
|
|
||||||
if requires_mention?
|
if requires_mention?
|
||||||
|
|
|
@ -96,19 +96,19 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def discoverable
|
def 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
|
||||||
|
@ -132,23 +132,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
|
||||||
|
@ -156,11 +156,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
|
||||||
|
|
|
@ -53,21 +53,21 @@ 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[:favourite_modal] = object.current_account.user.setting_favourite_modal
|
store[:favourite_modal] = object_account_user.setting_favourite_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[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
|
store[:expand_spoilers] = object_account_user.setting_expand_spoilers
|
||||||
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[:default_content_type] = object.current_account.user.setting_default_content_type
|
store[:default_content_type] = object_account_user.setting_default_content_type
|
||||||
store[:system_emoji_font] = object.current_account.user.setting_system_emoji_font
|
store[:system_emoji_font] = object_account_user.setting_system_emoji_font
|
||||||
store[:show_trends] = Setting.trends && object.current_account.user.setting_trends
|
store[:show_trends] = Setting.trends && object_account_user.setting_trends
|
||||||
else
|
else
|
||||||
store[:auto_play_gif] = Setting.auto_play_gif
|
store[:auto_play_gif] = Setting.auto_play_gif
|
||||||
store[:display_media] = Setting.display_media
|
store[:display_media] = Setting.display_media
|
||||||
|
@ -88,9 +88,9 @@ 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[: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
|
||||||
|
@ -106,11 +106,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
|
||||||
|
@ -125,6 +125,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
|
||||||
|
|
|
@ -61,7 +61,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
|
||||||
|
@ -73,19 +73,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
|
||||||
|
@ -101,39 +101,39 @@ 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 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
|
||||||
|
@ -145,7 +145,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?)
|
||||||
|
|
|
@ -50,7 +50,7 @@ class FollowService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def following_not_possible?
|
def following_not_possible?
|
||||||
@target_account.nil? || @target_account.id == @source_account.id || @target_account.suspended?
|
@target_account.nil? || @target_account.id == @source_account.id || @target_account.unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def following_not_allowed?
|
def following_not_allowed?
|
||||||
|
|
|
@ -108,7 +108,7 @@ class NotifyService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
def blocked?
|
def blocked?
|
||||||
blocked = @recipient.suspended?
|
blocked = @recipient.unavailable?
|
||||||
blocked ||= from_self? && @notification.type != :poll
|
blocked ||= from_self? && @notification.type != :poll
|
||||||
|
|
||||||
return blocked if message? && from_staff?
|
return blocked if message? && from_staff?
|
||||||
|
|
|
@ -51,7 +51,7 @@ class ProcessMentionsService < BaseService
|
||||||
|
|
||||||
# If after resolving it still isn't found or isn't the right
|
# If after resolving it still isn't found or isn't the right
|
||||||
# protocol, then give up
|
# protocol, then give up
|
||||||
next match if mention_undeliverable?(mentioned_account) || mentioned_account&.suspended?
|
next match if mention_undeliverable?(mentioned_account) || mentioned_account&.unavailable?
|
||||||
|
|
||||||
mention = @previous_mentions.find { |x| x.account_id == mentioned_account.id }
|
mention = @previous_mentions.find { |x| x.account_id == mentioned_account.id }
|
||||||
mention ||= @current_mentions.find { |x| x.account_id == mentioned_account.id }
|
mention ||= @current_mentions.find { |x| x.account_id == mentioned_account.id }
|
||||||
|
|
|
@ -12,7 +12,7 @@ class ReportService < BaseService
|
||||||
@rule_ids = options.delete(:rule_ids).presence
|
@rule_ids = options.delete(:rule_ids).presence
|
||||||
@options = options
|
@options = options
|
||||||
|
|
||||||
raise ActiveRecord::RecordNotFound if @target_account.suspended?
|
raise ActiveRecord::RecordNotFound if @target_account.unavailable?
|
||||||
|
|
||||||
create_report!
|
create_report!
|
||||||
notify_staff!
|
notify_staff!
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.batch-table__row{ class: [!account.suspended? && account.user_pending? && 'batch-table__row--attention', (account.suspended? || account.user_unconfirmed?) && 'batch-table__row--muted'] }
|
.batch-table__row{ class: [!account.unavailable? && account.user_pending? && 'batch-table__row--attention', (account.unavailable? || account.user_unconfirmed?) && 'batch-table__row--muted'] }
|
||||||
%label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
|
%label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox
|
||||||
= f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id
|
= f.check_box :account_ids, { multiple: true, include_hidden: false }, account.id
|
||||||
.batch-table__row__content.batch-table__row__content--unpadded
|
.batch-table__row__content.batch-table__row__content--unpadded
|
||||||
|
@ -8,13 +8,13 @@
|
||||||
%td
|
%td
|
||||||
= account_link_to account, path: admin_account_path(account.id)
|
= account_link_to account, path: admin_account_path(account.id)
|
||||||
%td.accounts-table__count.optional
|
%td.accounts-table__count.optional
|
||||||
- if account.suspended? || account.user_pending?
|
- if account.unavailable? || account.user_pending?
|
||||||
\-
|
\-
|
||||||
- else
|
- else
|
||||||
= friendly_number_to_human account.statuses_count
|
= friendly_number_to_human account.statuses_count
|
||||||
%small= t('accounts.posts', count: account.statuses_count).downcase
|
%small= t('accounts.posts', count: account.statuses_count).downcase
|
||||||
%td.accounts-table__count.optional
|
%td.accounts-table__count.optional
|
||||||
- if account.suspended? || account.user_pending?
|
- if account.unavailable? || account.user_pending?
|
||||||
\-
|
\-
|
||||||
- else
|
- else
|
||||||
= friendly_number_to_human account.followers_count
|
= friendly_number_to_human account.followers_count
|
||||||
|
@ -30,6 +30,6 @@
|
||||||
\-
|
\-
|
||||||
%br/
|
%br/
|
||||||
%samp.ellipsized-ip= relevant_account_ip(account, params[:ip])
|
%samp.ellipsized-ip= relevant_account_ip(account, params[:ip])
|
||||||
- if !account.suspended? && account.user_pending? && account.user&.invite_request&.text.present?
|
- if !account.unavailable? && account.user_pending? && account.user&.invite_request&.text.present?
|
||||||
.batch-table__row__content__quote
|
.batch-table__row__content__quote
|
||||||
%p= account.user&.invite_request&.text
|
%p= account.user&.invite_request&.text
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
= t('doorkeeper.authorized_applications.index.authorized_at', date: l(application.created_at.to_date))
|
= t('doorkeeper.authorized_applications.index.authorized_at', date: l(application.created_at.to_date))
|
||||||
|
|
||||||
- unless application.superapp? || current_account.suspended?
|
- unless application.superapp? || current_account.unavailable?
|
||||||
%div
|
%div
|
||||||
= table_link_to 'times', t('doorkeeper.authorized_applications.buttons.revoke'), oauth_authorized_application_path(application), method: :delete, data: { confirm: t('doorkeeper.authorized_applications.confirmations.revoke') }
|
= table_link_to 'times', t('doorkeeper.authorized_applications.buttons.revoke'), oauth_authorized_application_path(application), method: :delete, data: { confirm: t('doorkeeper.authorized_applications.confirmations.revoke') }
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
.fields-row
|
.fields-row
|
||||||
.fields-row__column.fields-row__column-6
|
.fields-row__column.fields-row__column-6
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :avatar, wrapper: :with_block_label, input_html: { accept: AccountAvatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(AccountAvatar::LIMIT))
|
= f.input :avatar, wrapper: :with_block_label, input_html: { accept: Account::Avatar::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.avatar', dimensions: '400x400', size: number_to_human_size(Account::Avatar::LIMIT))
|
||||||
|
|
||||||
.fields-row__column.fields-row__column-6
|
.fields-row__column.fields-row__column-6
|
||||||
.fields-group
|
.fields-group
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
.fields-row
|
.fields-row
|
||||||
.fields-row__column.fields-row__column-6
|
.fields-row__column.fields-row__column-6
|
||||||
.fields-group
|
.fields-group
|
||||||
= f.input :header, wrapper: :with_block_label, input_html: { accept: AccountHeader::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(AccountHeader::LIMIT))
|
= f.input :header, wrapper: :with_block_label, input_html: { accept: Account::Header::IMAGE_MIME_TYPES.join(',') }, hint: t('simple_form.hints.defaults.header', dimensions: '1500x500', size: number_to_human_size(Account::Header::LIMIT))
|
||||||
|
|
||||||
.fields-row__column.fields-row__column-6
|
.fields-row__column.fields-row__column-6
|
||||||
.fields-group
|
.fields-group
|
||||||
|
|
|
@ -7,7 +7,7 @@ class AccountDeletionWorker
|
||||||
|
|
||||||
def perform(account_id, options = {})
|
def perform(account_id, options = {})
|
||||||
account = Account.find(account_id)
|
account = Account.find(account_id)
|
||||||
return unless account.suspended?
|
return unless account.unavailable?
|
||||||
|
|
||||||
reserve_username = options.with_indifferent_access.fetch(:reserve_username, true)
|
reserve_username = options.with_indifferent_access.fetch(:reserve_username, true)
|
||||||
skip_activitypub = options.with_indifferent_access.fetch(:skip_activitypub, false)
|
skip_activitypub = options.with_indifferent_access.fetch(:skip_activitypub, false)
|
||||||
|
|
|
@ -21,12 +21,12 @@ class Scheduler::SuspendedUserCleanupScheduler
|
||||||
def perform
|
def perform
|
||||||
return if Sidekiq::Queue.new('pull').size > MAX_PULL_SIZE
|
return if Sidekiq::Queue.new('pull').size > MAX_PULL_SIZE
|
||||||
|
|
||||||
clean_suspended_accounts!
|
process_deletion_requests!
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def clean_suspended_accounts!
|
def process_deletion_requests!
|
||||||
# This should be fine because we only process a small amount of deletion requests at once and
|
# This should be fine because we only process a small amount of deletion requests at once and
|
||||||
# `id` and `created_at` should follow the same order.
|
# `id` and `created_at` should follow the same order.
|
||||||
AccountDeletionRequest.reorder(id: :asc).take(MAX_DELETIONS_PER_JOB).each do |deletion_request|
|
AccountDeletionRequest.reorder(id: :asc).take(MAX_DELETIONS_PER_JOB).each do |deletion_request|
|
||||||
|
|
|
@ -59,7 +59,7 @@ services:
|
||||||
image: ghcr.io/mastodon/mastodon:v4.2.0
|
image: ghcr.io/mastodon/mastodon:v4.2.0
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
command: bundle exec puma -C config/puma.rb
|
||||||
networks:
|
networks:
|
||||||
- external_network
|
- external_network
|
||||||
- internal_network
|
- internal_network
|
||||||
|
|
|
@ -67,8 +67,8 @@ module Mastodon::CLI
|
||||||
local? ? username : "#{username}@#{domain}"
|
local? ? username : "#{username}@#{domain}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# This is a duplicate of the AccountMerging concern because we need it to
|
# This is a duplicate of the Account::Merging concern because we need it
|
||||||
# be independent from code version.
|
# to be independent from code version.
|
||||||
def merge_with!(other_account)
|
def merge_with!(other_account)
|
||||||
# Since it's the same remote resource, the remote resource likely
|
# Since it's the same remote resource, the remote resource likely
|
||||||
# already believes we are following/blocking, so it's safe to
|
# already believes we are following/blocking, so it's safe to
|
||||||
|
|
|
@ -20,7 +20,7 @@ RSpec.describe Admin::AccountModerationNotesController do
|
||||||
|
|
||||||
it 'successfully creates a note' do
|
it 'successfully creates a note' do
|
||||||
expect { subject }.to change(AccountModerationNote, :count).by(1)
|
expect { subject }.to change(AccountModerationNote, :count).by(1)
|
||||||
expect(subject).to redirect_to admin_account_path(target_account.id)
|
expect(response).to redirect_to admin_account_path(target_account.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ RSpec.describe Admin::AccountModerationNotesController do
|
||||||
|
|
||||||
it 'falls to create a note' do
|
it 'falls to create a note' do
|
||||||
expect { subject }.to_not change(AccountModerationNote, :count)
|
expect { subject }.to_not change(AccountModerationNote, :count)
|
||||||
expect(subject).to render_template 'admin/accounts/show'
|
expect(response).to render_template 'admin/accounts/show'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -42,7 +42,7 @@ RSpec.describe Admin::AccountModerationNotesController do
|
||||||
|
|
||||||
it 'destroys note' do
|
it 'destroys note' do
|
||||||
expect { subject }.to change(AccountModerationNote, :count).by(-1)
|
expect { subject }.to change(AccountModerationNote, :count).by(-1)
|
||||||
expect(subject).to redirect_to admin_account_path(target_account.id)
|
expect(response).to redirect_to admin_account_path(target_account.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,24 +12,24 @@ describe Admin::CustomEmojisController do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #index' do
|
describe 'GET #index' do
|
||||||
subject { get :index }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Fabricate(:custom_emoji)
|
Fabricate(:custom_emoji)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders index page' do
|
it 'renders index page' do
|
||||||
expect(subject).to have_http_status 200
|
get :index
|
||||||
expect(subject).to render_template :index
|
|
||||||
|
expect(response).to have_http_status 200
|
||||||
|
expect(response).to render_template :index
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #new' do
|
describe 'GET #new' do
|
||||||
subject { get :new }
|
|
||||||
|
|
||||||
it 'renders new page' do
|
it 'renders new page' do
|
||||||
expect(subject).to have_http_status 200
|
get :new
|
||||||
expect(subject).to render_template :new
|
|
||||||
|
expect(response).to have_http_status 200
|
||||||
|
expect(response).to render_template :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ describe Admin::ReportNotesController do
|
||||||
it 'creates a report note and resolves report' do
|
it 'creates a report note and resolves report' do
|
||||||
expect { subject }.to change(ReportNote, :count).by(1)
|
expect { subject }.to change(ReportNote, :count).by(1)
|
||||||
expect(report.reload).to be_action_taken
|
expect(report.reload).to be_action_taken
|
||||||
expect(subject).to redirect_to admin_reports_path
|
expect(response).to redirect_to admin_reports_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ describe Admin::ReportNotesController do
|
||||||
it 'creates a report note and does not resolve report' do
|
it 'creates a report note and does not resolve report' do
|
||||||
expect { subject }.to change(ReportNote, :count).by(1)
|
expect { subject }.to change(ReportNote, :count).by(1)
|
||||||
expect(report.reload).to_not be_action_taken
|
expect(report.reload).to_not be_action_taken
|
||||||
expect(subject).to redirect_to admin_report_path(report)
|
expect(response).to redirect_to admin_report_path(report)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,7 +52,7 @@ describe Admin::ReportNotesController do
|
||||||
it 'creates a report note and unresolves report' do
|
it 'creates a report note and unresolves report' do
|
||||||
expect { subject }.to change(ReportNote, :count).by(1)
|
expect { subject }.to change(ReportNote, :count).by(1)
|
||||||
expect(report.reload).to_not be_action_taken
|
expect(report.reload).to_not be_action_taken
|
||||||
expect(subject).to redirect_to admin_report_path(report)
|
expect(response).to redirect_to admin_report_path(report)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ describe Admin::ReportNotesController do
|
||||||
it 'creates a report note and does not unresolve report' do
|
it 'creates a report note and does not unresolve report' do
|
||||||
expect { subject }.to change(ReportNote, :count).by(1)
|
expect { subject }.to change(ReportNote, :count).by(1)
|
||||||
expect(report.reload).to be_action_taken
|
expect(report.reload).to be_action_taken
|
||||||
expect(subject).to redirect_to admin_report_path(report)
|
expect(response).to redirect_to admin_report_path(report)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -86,7 +86,7 @@ describe Admin::ReportNotesController do
|
||||||
|
|
||||||
it 'deletes note' do
|
it 'deletes note' do
|
||||||
expect { subject }.to change(ReportNote, :count).by(-1)
|
expect { subject }.to change(ReportNote, :count).by(-1)
|
||||||
expect(subject).to redirect_to admin_report_path(report_note.report)
|
expect(response).to redirect_to admin_report_path(report_note.report)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe RateLimitHeaders do
|
describe Api::RateLimitHeaders do
|
||||||
controller(ApplicationController) do
|
controller(ApplicationController) do
|
||||||
include RateLimitHeaders
|
include Api::RateLimitHeaders
|
||||||
|
|
||||||
def show
|
def show
|
||||||
head 200
|
head 200
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe ExportControllerConcern do
|
describe Settings::ExportControllerConcern do
|
||||||
controller(ApplicationController) do
|
controller(ApplicationController) do
|
||||||
include ExportControllerConcern
|
include Settings::ExportControllerConcern
|
||||||
|
|
||||||
def index
|
def index
|
||||||
send_export_file
|
send_export_file
|
|
@ -451,7 +451,7 @@ RSpec.describe Account do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'limits via constant by default' do
|
it 'limits via constant by default' do
|
||||||
stub_const('AccountSearch::DEFAULT_LIMIT', 1)
|
stub_const('Account::Search::DEFAULT_LIMIT', 1)
|
||||||
2.times.each { Fabricate(:account, display_name: 'Display Name') }
|
2.times.each { Fabricate(:account, display_name: 'Display Name') }
|
||||||
results = described_class.search_for('display')
|
results = described_class.search_for('display')
|
||||||
expect(results.size).to eq 1
|
expect(results.size).to eq 1
|
||||||
|
@ -595,7 +595,7 @@ RSpec.describe Account do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'limits by 10 by default' do
|
it 'limits by 10 by default' do
|
||||||
stub_const('AccountSearch::DEFAULT_LIMIT', 1)
|
stub_const('Account::Search::DEFAULT_LIMIT', 1)
|
||||||
2.times { Fabricate(:account, display_name: 'Display Name') }
|
2.times { Fabricate(:account, display_name: 'Display Name') }
|
||||||
results = described_class.advanced_search_for('display', account)
|
results = described_class.advanced_search_for('display', account)
|
||||||
expect(results.size).to eq 1
|
expect(results.size).to eq 1
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe AccountCounters do
|
describe Account::Counters do
|
||||||
let!(:account) { Fabricate(:account) }
|
let!(:account) { Fabricate(:account) }
|
||||||
|
|
||||||
describe '#increment_count!' do
|
describe '#increment_count!' do
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe AccountFinderConcern do
|
describe Account::FinderConcern do
|
||||||
describe 'local finders' do
|
describe 'local finders' do
|
||||||
let!(:account) { Fabricate(:account, username: 'Alice') }
|
let!(:account) { Fabricate(:account, username: 'Alice') }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe AccountInteractions do
|
describe Account::Interactions do
|
||||||
let(:account) { Fabricate(:account, username: 'account') }
|
let(:account) { Fabricate(:account, username: 'account') }
|
||||||
let(:account_id) { account.id }
|
let(:account_id) { account.id }
|
||||||
let(:account_ids) { [account_id] }
|
let(:account_ids) { [account_id] }
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe AccountStatusesSearch do
|
describe Account::StatusesSearch do
|
||||||
let(:account) { Fabricate(:account, indexable: indexable) }
|
let(:account) { Fabricate(:account, indexable: indexable) }
|
||||||
|
|
||||||
before do
|
before do
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe StatusThreadingConcern do
|
describe Status::ThreadingConcern do
|
||||||
describe '#ancestors' do
|
describe '#ancestors' do
|
||||||
let!(:alice) { Fabricate(:account, username: 'alice') }
|
let!(:alice) { Fabricate(:account, username: 'alice') }
|
||||||
let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') }
|
let!(:bob) { Fabricate(:account, username: 'bob', domain: 'example.com') }
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe AccountSearch do
|
describe Account::Search do
|
||||||
describe 'a non-discoverable account becoming discoverable' do
|
describe 'a non-discoverable account becoming discoverable' do
|
||||||
let(:account) { Account.find_by(username: 'search_test_account_1') }
|
let(:account) { Account.find_by(username: 'search_test_account_1') }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
describe AccountStatusesSearch do
|
describe Account::StatusesSearch do
|
||||||
describe 'a non-indexable account becoming indexable' do
|
describe 'a non-indexable account becoming indexable' do
|
||||||
let(:account) { Account.find_by(username: 'search_test_account_1') }
|
let(:account) { Account.find_by(username: 'search_test_account_1') }
|
||||||
|
|
Loading…
Reference in New Issue