Browse Source

Merge remote-tracking branch 'origin/master' into closed-social-v3

pull/4/head
欧醚 2 months ago
parent
commit
eee3899b2c
231 changed files with 4309 additions and 2228 deletions
  1. +1
    -1
      .codeclimate.yml
  2. +167
    -8
      .rubocop.yml
  3. +0
    -1
      Aptfile
  4. +12
    -7
      Dockerfile
  5. +6
    -5
      Gemfile
  6. +66
    -40
      Gemfile.lock
  7. +1
    -1
      Procfile
  8. +8
    -4
      app/controllers/accounts_controller.rb
  9. +18
    -14
      app/controllers/activitypub/collections_controller.rb
  10. +22
    -7
      app/controllers/activitypub/outboxes_controller.rb
  11. +1
    -0
      app/controllers/api/base_controller.rb
  12. +22
    -0
      app/controllers/api/v1/accounts/featured_tags_controller.rb
  13. +1
    -1
      app/controllers/api/v1/accounts/follower_accounts_controller.rb
  14. +1
    -1
      app/controllers/api/v1/accounts/following_accounts_controller.rb
  15. +1
    -1
      app/controllers/api/v1/accounts/identity_proofs_controller.rb
  16. +1
    -1
      app/controllers/api/v1/accounts/lists_controller.rb
  17. +1
    -1
      app/controllers/api/v1/accounts/relationships_controller.rb
  18. +8
    -17
      app/controllers/api/v1/accounts/statuses_controller.rb
  19. +0
    -5
      app/controllers/api/v1/accounts_controller.rb
  20. +1
    -1
      app/controllers/api/v1/admin/accounts_controller.rb
  21. +1
    -1
      app/controllers/api/v1/admin/reports_controller.rb
  22. +2
    -0
      app/controllers/api/v1/blocks_controller.rb
  23. +2
    -5
      app/controllers/api/v1/bookmarks_controller.rb
  24. +1
    -1
      app/controllers/api/v1/conversations_controller.rb
  25. +1
    -1
      app/controllers/api/v1/crypto/encrypted_messages_controller.rb
  26. +1
    -1
      app/controllers/api/v1/endorsements_controller.rb
  27. +2
    -5
      app/controllers/api/v1/favourites_controller.rb
  28. +4
    -4
      app/controllers/api/v1/featured_tags/suggestions_controller.rb
  29. +1
    -1
      app/controllers/api/v1/follow_requests_controller.rb
  30. +2
    -2
      app/controllers/api/v1/lists/accounts_controller.rb
  31. +1
    -1
      app/controllers/api/v1/lists_controller.rb
  32. +2
    -0
      app/controllers/api/v1/mutes_controller.rb
  33. +5
    -7
      app/controllers/api/v1/notifications_controller.rb
  34. +1
    -1
      app/controllers/api/v1/scheduled_statuses_controller.rb
  35. +1
    -0
      app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
  36. +1
    -1
      app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
  37. +14
    -15
      app/controllers/api/v1/timelines/public_controller.rb
  38. +19
    -20
      app/controllers/api/v1/timelines/tag_controller.rb
  39. +17
    -1
      app/controllers/auth/sessions_controller.rb
  40. +4
    -0
      app/controllers/concerns/cache_concern.rb
  41. +0
    -1
      app/controllers/concerns/challengable_concern.rb
  42. +0
    -5
      app/controllers/concerns/export_controller_concern.rb
  43. +109
    -56
      app/controllers/concerns/signature_verification.rb
  44. +41
    -4
      app/controllers/concerns/two_factor_authentication_concern.rb
  45. +1
    -1
      app/controllers/instance_actors_controller.rb
  46. +5
    -0
      app/controllers/oauth/authorized_applications_controller.rb
  47. +2
    -2
      app/controllers/settings/aliases_controller.rb
  48. +0
    -3
      app/controllers/settings/applications_controller.rb
  49. +7
    -0
      app/controllers/settings/base_controller.rb
  50. +2
    -5
      app/controllers/settings/deletes_controller.rb
  51. +1
    -1
      app/controllers/settings/exports/blocked_accounts_controller.rb
  52. +1
    -1
      app/controllers/settings/exports/blocked_domains_controller.rb
  53. +1
    -1
      app/controllers/settings/exports/following_accounts_controller.rb
  54. +1
    -1
      app/controllers/settings/exports/lists_controller.rb
  55. +1
    -1
      app/controllers/settings/exports/muted_accounts_controller.rb
  56. +0
    -11
      app/controllers/settings/exports_controller.rb
  57. +4
    -7
      app/controllers/settings/featured_tags_controller.rb
  58. +0
    -3
      app/controllers/settings/identity_proofs_controller.rb
  59. +0
    -3
      app/controllers/settings/imports_controller.rb
  60. +1
    -8
      app/controllers/settings/migration/redirects_controller.rb
  61. +1
    -8
      app/controllers/settings/migrations_controller.rb
  62. +0
    -1
      app/controllers/settings/pictures_controller.rb
  63. +0
    -4
      app/controllers/settings/preferences_controller.rb
  64. +0
    -3
      app/controllers/settings/profiles_controller.rb
  65. +3
    -3
      app/controllers/settings/sessions_controller.rb
  66. +11
    -8
      app/controllers/settings/two_factor_authentication/confirmations_controller.rb
  67. +39
    -0
      app/controllers/settings/two_factor_authentication/otp_authentication_controller.rb
  68. +1
    -4
      app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb
  69. +102
    -0
      app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb
  70. +27
    -0
      app/controllers/settings/two_factor_authentication_methods_controller.rb
  71. +0
    -53
      app/controllers/settings/two_factor_authentications_controller.rb
  72. +16
    -15
      app/controllers/tags_controller.rb
  73. +2
    -0
      app/helpers/application_helper.rb
  74. +2
    -35
      app/javascript/mastodon/actions/accounts.js
  75. +2
    -2
      app/javascript/mastodon/actions/lists.js
  76. +3
    -61
      app/javascript/mastodon/actions/statuses.js
  77. +0
    -2
      app/javascript/mastodon/components/gifv.js
  78. +3
    -2
      app/javascript/mastodon/components/status_action_bar.js
  79. +35
    -29
      app/javascript/mastodon/features/account/components/header.js
  80. +21
    -10
      app/javascript/mastodon/features/account_gallery/index.js
  81. +5
    -3
      app/javascript/mastodon/features/account_timeline/index.js
  82. +1
    -1
      app/javascript/mastodon/features/emoji/emoji.js
  83. +22
    -15
      app/javascript/mastodon/features/getting_started/index.js
  84. +27
    -3
      app/javascript/mastodon/features/list_timeline/index.js
  85. +3
    -2
      app/javascript/mastodon/features/status/components/action_bar.js
  86. +36
    -13
      app/javascript/mastodon/features/ui/components/focal_point_modal.js
  87. +1
    -1
      app/javascript/mastodon/locales/bg.json
  88. +1
    -1
      app/javascript/mastodon/locales/br.json
  89. +2
    -2
      app/javascript/mastodon/locales/defaultMessages.json
  90. +1
    -1
      app/javascript/mastodon/locales/en.json
  91. +1
    -1
      app/javascript/mastodon/locales/ga.json
  92. +1
    -1
      app/javascript/mastodon/locales/he.json
  93. +1
    -1
      app/javascript/mastodon/locales/hi.json
  94. +1
    -1
      app/javascript/mastodon/locales/hr.json
  95. +1
    -1
      app/javascript/mastodon/locales/io.json
  96. +1
    -1
      app/javascript/mastodon/locales/kab.json
  97. +1
    -1
      app/javascript/mastodon/locales/kn.json
  98. +1
    -1
      app/javascript/mastodon/locales/ku.json
  99. +1
    -1
      app/javascript/mastodon/locales/lt.json
  100. +1
    -1
      app/javascript/mastodon/locales/lv.json

+ 1
- 1
.codeclimate.yml View File

@ -30,7 +30,7 @@ plugins:
channel: eslint-7
rubocop:
enabled: true
channel: rubocop-0-82
channel: rubocop-0-88
sass-lint:
enabled: true
exclude_patterns:

+ 167
- 8
.rubocop.yml View File

@ -25,30 +25,68 @@ Layout/AccessModifierIndentation:
Layout/EmptyLineAfterMagicComment:
Enabled: false
Layout/EmptyLineAfterGuardClause:
Enabled: false
Layout/EmptyLinesAroundAttributeAccessor:
Enabled: true
Layout/HashAlignment:
Enabled: false
# EnforcedHashRocketStyle: table
# EnforcedColonStyle: table
Layout/SpaceAroundMethodCallOperator:
Enabled: true
Layout/SpaceInsideHashLiteralBraces:
EnforcedStyle: space
Lint/DeprecatedOpenSSLConstant:
Enabled: true
Lint/DuplicateElsifCondition:
Enabled: true
Lint/MixedRegexpCaptureTypes:
Enabled: true
Lint/RaiseException:
Enabled: true
Lint/StructNewOverride:
Enabled: true
Lint/UselessAccessModifier:
ContextCreatingMethods:
- class_methods
Metrics/AbcSize:
Max: 100
Exclude:
- 'lib/mastodon/*_cli.rb'
Metrics/BlockLength:
Max: 35
Max: 55
Exclude:
- 'lib/tasks/**/*'
- 'lib/mastodon/*_cli.rb'
Metrics/BlockNesting:
Max: 3
Exclude:
- 'lib/mastodon/*_cli.rb'
Metrics/ClassLength:
CountComments: false
Max: 300
Max: 400
Exclude:
- 'lib/mastodon/*_cli.rb'
Metrics/CyclomaticComplexity:
Max: 25
Exclude:
- 'lib/mastodon/*_cli.rb'
Layout/LineLength:
AllowURI: true
@ -56,7 +94,9 @@ Layout/LineLength:
Metrics/MethodLength:
CountComments: false
Max: 55
Max: 65
Exclude:
- 'lib/mastodon/*_cli.rb'
Metrics/ModuleLength:
CountComments: false
@ -67,24 +107,29 @@ Metrics/ParameterLists:
CountKeywordArgs: true
Metrics/PerceivedComplexity:
Max: 20
Max: 25
Naming/MemoizedInstanceVariableName:
Enabled: false
Naming/MethodParameterName:
Enabled: true
Rails:
Enabled: true
Rails/EnumHash:
Rails/ApplicationController:
Enabled: false
Exclude:
- 'app/controllers/well_known/**/*.rb'
Rails/HasAndBelongsToMany:
Rails/BelongsTo:
Enabled: false
Rails/SkipsModelValidations:
Rails/ContentTag:
Enabled: false
Rails/HttpStatus:
Rails/EnumHash:
Enabled: false
Rails/Exit:
@ -92,9 +137,60 @@ Rails/Exit:
- 'lib/mastodon/*'
- 'lib/cli.rb'
Rails/FilePath:
Enabled: false
Rails/HasAndBelongsToMany:
Enabled: false
Rails/HasManyOrHasOneDependent:
Enabled: false
Rails/HelperInstanceVariable:
Enabled: false
Rails/HttpStatus:
Enabled: false
Rails/IndexBy:
Enabled: false
Rails/InverseOf:
Enabled: false
Rails/LexicallyScopedActionFilter:
Enabled: false
Rails/OutputSafety:
Enabled: true
Rails/RakeEnvironment:
Enabled: false
Rails/RedundantForeignKey:
Enabled: false
Rails/SkipsModelValidations:
Enabled: false
Rails/UniqueValidationWithoutIndex:
Enabled: false
Style/AccessorGrouping:
Enabled: true
Style/AccessModifierDeclarations:
Enabled: false
Style/ArrayCoercion:
Enabled: true
Style/BisectedAttrAccessor:
Enabled: true
Style/CaseLikeIf:
Enabled: false
Style/ClassAndModuleChildren:
Enabled: false
@ -109,6 +205,15 @@ Style/Documentation:
Style/DoubleNegation:
Enabled: true
Style/ExpandPathArguments:
Enabled: false
Style/ExponentialNotation:
Enabled: true
Style/FormatString:
Enabled: false
Style/FormatStringToken:
Enabled: false
@ -118,9 +223,33 @@ Style/FrozenStringLiteralComment:
Style/GuardClause:
Enabled: false
Style/HashAsLastArrayItem:
Enabled: false
Style/HashEachMethods:
Enabled: true
Style/HashLikeCase:
Enabled: true
Style/HashTransformKeys:
Enabled: true
Style/HashTransformValues:
Enabled: false
Style/IfUnlessModifier:
Enabled: false
Style/InverseMethods:
Enabled: false
Style/Lambda:
Enabled: false
Style/MutableConstant:
Enabled: false
Style/PercentLiteralDelimiters:
PreferredDelimiters:
'%i': '()'
@ -129,9 +258,36 @@ Style/PercentLiteralDelimiters:
Style/PerlBackrefs:
AutoCorrect: false
Style/RedundantAssignment:
Enabled: false
Style/RedundantFetchBlock:
Enabled: true
Style/RedundantFileExtensionInRequire:
Enabled: true
Style/RedundantRegexpCharacterClass:
Enabled: false
Style/RedundantRegexpEscape:
Enabled: false
Style/RedundantReturn:
Enabled: true
Style/RegexpLiteral:
Enabled: false
Style/RescueStandardError:
Enabled: false
Style/SignalException:
Enabled: false
Style/SlicingWithRange:
Enabled: true
Style/SymbolArray:
Enabled: false
@ -140,3 +296,6 @@ Style/TrailingCommaInArrayLiteral:
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: 'comma'
Style/UnpackFirst:
Enabled: false

+ 0
- 1
Aptfile View File

@ -5,7 +5,6 @@ libidn11
libidn11-dev
libpq-dev
libprotobuf-dev
libssl-dev
libxdamage1
libxfixes3
protobuf-compiler

+ 12
- 7
Dockerfile View File

@ -36,7 +36,8 @@ RUN apt update && \
./autogen.sh && \
./configure --prefix=/opt/jemalloc && \
make -j$(nproc) > /dev/null && \
make install_bin install_include install_lib
make install_bin install_include install_lib && \
cd .. && rm -rf jemalloc-$JE_VER $JE_VER.tar.gz
# Install Ruby
ENV RUBY_VER="2.6.6"
@ -56,7 +57,8 @@ RUN apt update && \
--disable-install-doc && \
ln -s /opt/jemalloc/lib/* /usr/lib/ && \
make -j$(nproc) > /dev/null && \
make install
make install && \
cd .. && rm -rf ruby-$RUBY_VER.tar.gz ruby-$RUBY_VER
ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin"
@ -107,11 +109,14 @@ RUN apt -y --no-install-recommends install \
rm -rf /var/lib/apt/lists/*
# Add tini
ENV TINI_VERSION="0.18.0"
ENV TINI_SUM="12d20136605531b09a2c2dac02ccee85e1b874eb322ef6baf7561cd93f93c855"
ADD https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini /tini
RUN echo "$TINI_SUM tini" | sha256sum -c -
RUN chmod +x /tini
ENV TINI_VERSION="0.19.0"
RUN dpkgArch="$(dpkg --print-architecture)" && \
ARCH=$dpkgArch && \
wget https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-$ARCH \
https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-$ARCH.sha256sum && \
cat tini-$ARCH.sha256sum | sha256sum -c - && \
mv tini-$ARCH /tini && rm tini-$ARCH.sha256sum && \
chmod +x /tini
# Copy over mastodon source, and dependencies from building, and set permissions
COPY --chown=mastodon:mastodon . /opt/mastodon

+ 6
- 5
Gemfile View File

@ -20,7 +20,7 @@ gem 'makara', '~> 0.4'
gem 'pghero', '~> 2.7'
gem 'dotenv-rails', '~> 2.7'
gem 'aws-sdk-s3', '~> 1.78', require: false
gem 'aws-sdk-s3', '~> 1.79', require: false
gem 'fog-core', '<= 2.1.0'
gem 'fog-openstack', '~> 0.3', require: false
gem 'paperclip', '~> 6.0'
@ -56,7 +56,7 @@ gem 'fast_blank', '~> 1.0'
gem 'fastimage'
gem 'goldfinger', '~> 2.1'
gem 'hiredis', '~> 0.6'
gem 'redis-namespace', '~> 1.7'
gem 'redis-namespace', '~> 1.8'
gem 'health_check', git: 'https://github.com/ianheggie/health_check', ref: '0b799ead604f900ed50685e9b2d469cd2befba5b'
gem 'htmlentities', '~> 4.3'
gem 'http', '~> 4.4'
@ -99,6 +99,7 @@ gem 'twitter-text', '~> 1.14'
gem 'tzinfo-data', '~> 1.2020'
gem 'webpacker', '~> 5.2'
gem 'webpush'
gem 'webauthn', '~> 3.0.0.alpha1'
gem 'json-ld'
gem 'json-ld-preloaded', '~> 3.1'
@ -126,7 +127,7 @@ group :test do
gem 'rspec-sidekiq', '~> 3.1'
gem 'simplecov', '~> 0.19', require: false
gem 'webmock', '~> 3.8'
gem 'parallel_tests', '~> 3.1'
gem 'parallel_tests', '~> 3.2'
gem 'rspec_junit_formatter', '~> 0.4'
end
@ -139,8 +140,8 @@ group :development do
gem 'letter_opener', '~> 1.7'
gem 'letter_opener_web', '~> 1.4'
gem 'memory_profiler'
gem 'rubocop', '~> 0.86', require: false
gem 'rubocop-rails', '~> 2.6', require: false
gem 'rubocop', '~> 0.90', require: false
gem 'rubocop-rails', '~> 2.8', require: false
gem 'brakeman', '~> 4.9', require: false
gem 'bundler-audit', '~> 0.7', require: false

+ 66
- 40
Gemfile.lock View File

@ -67,6 +67,7 @@ GEM
public_suffix (>= 2.0.2, < 5.0)
airbrussh (1.4.0)
sshkit (>= 1.6.1, != 1.7.0)
android_key_attestation (0.3.0)
annotate (3.1.1)
activerecord (>= 3.2, < 7.0)
rake (>= 10.4, < 14.0)
@ -76,34 +77,36 @@ GEM
encryptor (~> 3.0.0)
av (0.9.0)
cocaine (~> 0.5.3)
awrence (1.1.1)
aws-eventstream (1.1.0)
aws-partitions (1.356.0)
aws-sdk-core (3.104.3)
aws-partitions (1.365.0)
aws-sdk-core (3.105.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.36.0)
aws-sdk-kms (1.37.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.78.0)
aws-sdk-s3 (1.79.1)
aws-sdk-core (~> 3, >= 3.104.3)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2)
aws-eventstream (~> 1, >= 1.0.2)
bcrypt (3.1.15)
bcrypt (3.1.16)
better_errors (2.7.1)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
rack (>= 0.9.0)
bindata (2.4.8)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
blurhash (0.1.4)
ffi (~> 1.10.0)
bootsnap (1.4.8)
msgpack (~> 1.0)
brakeman (4.9.0)
brakeman (4.9.1)
browser (4.2.0)
builder (3.2.4)
bullet (6.1.0)
@ -138,6 +141,7 @@ GEM
xpath (~> 3.2)
case_transform (0.2)
activesupport
cbor (0.5.9.6)
charlock_holmes (0.7.7)
chewy (5.1.0)
activesupport (>= 4.0)
@ -153,6 +157,9 @@ GEM
color_diff (0.1)
concurrent-ruby (1.1.7)
connection_pool (2.2.3)
cose (1.0.0)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 0.4.0)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.6)
@ -188,13 +195,13 @@ GEM
railties (>= 3.2)
e2mmap (0.1.0)
ed25519 (1.2.4)
elasticsearch (7.8.1)
elasticsearch-api (= 7.8.1)
elasticsearch-transport (= 7.8.1)
elasticsearch-api (7.8.1)
elasticsearch (7.9.0)
elasticsearch-api (= 7.9.0)
elasticsearch-transport (= 7.9.0)
elasticsearch-api (7.9.0)
multi_json
elasticsearch-dsl (0.1.9)
elasticsearch-transport (7.8.1)
elasticsearch-transport (7.9.0)
faraday (~> 1)
multi_json
encryptor (3.0.0)
@ -239,7 +246,7 @@ GEM
http (~> 4.0)
nokogiri (~> 1.8)
oj (~> 3.0)
hamlit (2.11.0)
hamlit (2.11.1)
temple (>= 0.8.2)
thor
tilt
@ -299,7 +306,7 @@ GEM
json-ld (~> 3.1)
rdf (~> 3.1)
jsonapi-renderer (0.2.2)
jwt (2.2.1)
jwt (2.2.2)
kaminari (1.2.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.1)
@ -326,7 +333,7 @@ GEM
activesupport (>= 4)
railties (>= 4)
request_store (~> 1.0)
loofah (2.6.0)
loofah (2.7.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
@ -339,7 +346,7 @@ GEM
redis (>= 3.0.5)
memory_profiler (0.9.14)
method_source (1.0.0)
microformats (4.2.0)
microformats (4.2.1)
json (~> 2.2)
nokogiri (~> 1.10)
mime-types (3.3.1)
@ -348,15 +355,15 @@ GEM
mimemagic (0.3.5)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.1)
minitest (5.14.2)
msgpack (1.3.3)
multi_json (1.15.0)
multipart-post (2.1.1)
net-ldap (0.16.2)
net-ldap (0.16.3)
net-scp (3.0.0)
net-ssh (>= 2.6.5, < 7.0.0)
net-ssh (6.1.0)
nio4r (2.5.2)
nio4r (2.5.3)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
nokogumbo (2.0.2)
@ -366,7 +373,7 @@ GEM
concurrent-ruby (~> 1.0, >= 1.0.2)
sidekiq (>= 3.5)
statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.10.8)
oj (3.10.14)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
@ -377,8 +384,10 @@ GEM
omniauth-saml (1.10.2)
omniauth (~> 1.3, >= 1.3.2)
ruby-saml (~> 1.9)
openssl (2.2.0)
openssl-signature_algorithm (0.4.0)
orm_adapter (0.5.0)
ox (2.13.2)
ox (2.13.3)
paperclip (6.0.0)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
@ -389,7 +398,7 @@ GEM
av (~> 0.9.0)
paperclip (>= 2.5.2)
parallel (1.19.2)
parallel_tests (3.1.0)
parallel_tests (3.2.0)
parallel
parser (2.7.1.4)
ast (~> 2.4.1)
@ -417,8 +426,8 @@ GEM
pry (~> 0.13.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (4.0.5)
puma (4.3.5)
public_suffix (4.0.6)
puma (4.3.6)
nio4r (~> 2.0)
pundit (2.1.0)
activesupport (>= 3.0.0)
@ -467,7 +476,7 @@ GEM
thor (>= 0.19.0, < 2.0)
rainbow (3.0.0)
rake (13.0.1)
rdf (3.1.5)
rdf (3.1.6)
hamster (~> 3.0)
link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.4.0)
@ -480,7 +489,7 @@ GEM
redis-activesupport (5.2.0)
activesupport (>= 3, < 7)
redis-store (>= 1.3, < 2)
redis-namespace (1.7.0)
redis-namespace (1.8.0)
redis (>= 3.0.4)
redis-rack (2.1.3)
rack (>= 2.0.8, < 3)
@ -526,31 +535,34 @@ GEM
rspec-support (3.9.3)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
rubocop (0.86.0)
rubocop (0.90.0)
parallel (~> 1.10)
parser (>= 2.7.0.1)
parser (>= 2.7.1.1)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.7)
rexml
rubocop-ast (>= 0.0.3, < 1.0)
rubocop-ast (>= 0.3.0, < 1.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
rubocop-ast (0.3.0)
parser (>= 2.7.1.4)
rubocop-rails (2.6.0)
rubocop-rails (2.8.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 0.82.0)
rubocop (>= 0.87.0)
ruby-progressbar (1.10.1)
ruby-saml (1.11.0)
nokogiri (>= 1.5.10)
rufus-scheduler (3.6.0)
fugit (~> 1.1, >= 1.1.6)
safe_yaml (1.0.5)
safety_net_attestation (0.4.0)
jwt (~> 2.0)
sanitize (5.2.1)
crass (~> 1.0.2)
nokogiri (>= 1.8.0)
nokogumbo (~> 2.0)
securecompare (1.0.0)
semantic_range (2.3.0)
sidekiq (6.1.1)
connection_pool (>= 2.2.2)
@ -565,10 +577,10 @@ GEM
sidekiq (>= 3)
thwait
tilt (>= 1.4.0)
sidekiq-unique-jobs (6.0.22)
sidekiq-unique-jobs (6.0.23)
concurrent-ruby (~> 1.0, >= 1.0.5)
sidekiq (>= 4.0, < 7.0)
thor (~> 0)
thor (>= 0.20, < 2.0)
simple-navigation (4.1.0)
activesupport (>= 2.3.2)
simple_form (5.0.2)
@ -605,6 +617,9 @@ GEM
thwait (0.2.0)
e2mmap
tilt (2.0.10)
tpm-key_attestation (0.9.0)
bindata (~> 2.4)
openssl-signature_algorithm (~> 0.4.0)
tty-color (0.5.2)
tty-cursor (0.7.1)
tty-prompt (0.22.0)
@ -626,13 +641,23 @@ GEM
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
uniform_notifier (1.13.0)
warden (1.2.8)
rack (>= 2.0.6)
warden (1.2.9)
rack (>= 2.0.9)
webauthn (3.0.0.alpha1)
android_key_attestation (~> 0.3.0)
awrence (~> 1.1)
bindata (~> 2.4)
cbor (~> 0.5.9)
cose (~> 1.0)
openssl (~> 2.0)
safety_net_attestation (~> 0.4.0)
securecompare (~> 1.0)
tpm-key_attestation (~> 0.9.0)
webmock (3.8.3)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (5.2.0)
webpacker (5.2.1)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
railties (>= 5.2)
@ -655,7 +680,7 @@ DEPENDENCIES
active_record_query_trace (~> 1.7)
addressable (~> 2.7)
annotate (~> 3.1)
aws-sdk-s3 (~> 1.78)
aws-sdk-s3 (~> 1.79)
better_errors (~> 2.7)
binding_of_caller (~> 0.7)
blurhash (~> 0.1)
@ -726,7 +751,7 @@ DEPENDENCIES
paperclip (~> 6.0)
paperclip-av-transcoder (~> 0.6)
parallel (~> 1.19)
parallel_tests (~> 3.1)
parallel_tests (~> 3.2)
parslet
pg (~> 1.2)
pghero (~> 2.7)
@ -747,14 +772,14 @@ DEPENDENCIES
rails-settings-cached (~> 0.6)
rdf-normalize (~> 0.4)
redis (~> 4.2)
redis-namespace (~> 1.7)
redis-namespace (~> 1.8)
redis-rails (~> 5.0)
rqrcode (~> 1.1)
rspec-rails (~> 4.0)
rspec-sidekiq (~> 3.1)
rspec_junit_formatter (~> 0.4)
rubocop (~> 0.86)
rubocop-rails (~> 2.6)
rubocop (~> 0.90)
rubocop-rails (~> 2.8)
ruby-progressbar (~> 1.10)
sanitize (~> 5.2)
sidekiq (~> 6.1)
@ -775,6 +800,7 @@ DEPENDENCIES
tty-prompt (~> 0.22)
twitter-text (~> 1.14)
tzinfo-data (~> 1.2020)
webauthn (~> 3.0.0.alpha1)
webmock (~> 3.8)
webpacker (~> 5.2)
webpush

+ 1
- 1
Procfile View File

@ -1,4 +1,4 @@
web: if [ "$RUN_STREAMING" != "true" ]; then BIND=0.0.0.0 bundle exec puma -C config/puma.rb; else BIND=0.0.0.0 node ./streaming; fi
web: bin/heroku-web
worker: bundle exec sidekiq
# For the streaming API, you need a separate app that shares Postgres and Redis:

+ 8
- 4
app/controllers/accounts_controller.rb View File

@ -28,8 +28,7 @@ class AccountsController < ApplicationController
end
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
@statuses = filtered_status_page
@statuses = cache_collection(@statuses, Status)
@statuses = cached_filtered_status_page
@rss_url = rss_url
unless @statuses.empty?
@ -142,8 +141,13 @@ class AccountsController < ApplicationController
request.path.split('.').first.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
end
def filtered_status_page
filtered_statuses.paginate_by_id(PAGE_SIZE, params_slice(:max_id, :min_id, :since_id))
def cached_filtered_status_page
cache_collection_paginated_by_id(
filtered_statuses,
Status,
PAGE_SIZE,
params_slice(:max_id, :min_id, :since_id)
)
end
def params_slice(*keys)

+ 18
- 14
app/controllers/activitypub/collections_controller.rb View File

@ -12,7 +12,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
def show
expires_in 3.minutes, public: public_fetch_mode?
render_with_cache json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, skip_activities: true
render_with_cache json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter
end
private
@ -20,17 +20,9 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
def set_items
case params[:id]
when 'featured'
@items = begin
# Because in public fetch mode we cache the response, there would be no
# benefit from performing the check below, since a blocked account or domain
# would likely be served the cache from the reverse proxy anyway
if authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
[]
else
cache_collection(@account.pinned_statuses, Status)
end
end
@items = for_signed_account { cache_collection(@account.pinned_statuses, Status) }
when 'tags'
@items = for_signed_account { @account.featured_tags }
when 'devices'
@items = @account.devices
else
@ -40,7 +32,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
def set_size
case params[:id]
when 'featured', 'devices'
when 'featured', 'devices', 'tags'
@size = @items.size
else
not_found
@ -51,7 +43,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
case params[:id]
when 'featured'
@type = :ordered
when 'devices'
when 'devices', 'tags'
@type = :unordered
else
not_found
@ -66,4 +58,16 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
items: @items
)
end
def for_signed_account
# Because in public fetch mode we cache the response, there would be no
# benefit from performing the check below, since a blocked account or domain
# would likely be served the cache from the reverse proxy anyway
if authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
[]
else
yield
end
end
end

+ 22
- 7
app/controllers/activitypub/outboxes_controller.rb View File

@ -20,9 +20,9 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
def outbox_presenter
if page_requested?
ActivityPub::CollectionPresenter.new(
id: account_outbox_url(@account, page_params),
id: outbox_url(page_params),
type: :ordered,
part_of: account_outbox_url(@account),
part_of: outbox_url,
prev: prev_page,
next: next_page,
items: @statuses
@ -32,12 +32,20 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
id: account_outbox_url(@account),
type: :ordered,
size: @account.statuses_count,
first: account_outbox_url(@account, page: true),
last: account_outbox_url(@account, page: true, min_id: 0)
first: outbox_url(page: true),
last: outbox_url(page: true, min_id: 0)
)
end
end
def outbox_url(**kwargs)
if params[:account_username].present?
account_outbox_url(@account, **kwargs)
else
instance_actor_outbox_url(**kwargs)
end
end
def next_page
account_outbox_url(@account, page: true, max_id: @statuses.last.id) if @statuses.size == LIMIT
end
@ -49,9 +57,12 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
def set_statuses
return unless page_requested?
@statuses = @account.statuses.permitted_for(@account, signed_request_account)
@statuses = @statuses.paginate_by_id(LIMIT, params_slice(:max_id, :min_id, :since_id))
@statuses = cache_collection(@statuses, Status)
@statuses = cache_collection_paginated_by_id(
@account.statuses.permitted_for(@account, signed_request_account),
Status,
LIMIT,
params_slice(:max_id, :min_id, :since_id)
)
end
def page_requested?
@ -61,4 +72,8 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
def page_params
{ page: true, max_id: params[:max_id], min_id: params[:min_id] }.compact
end
def set_account
@account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative
end
end

+ 1
- 0
app/controllers/api/base_controller.rb View File

@ -71,6 +71,7 @@ class Api::BaseController < ApplicationController
def limit_param(default_limit)
return default_limit unless params[:limit]
[params[:limit].to_i.abs, default_limit * 2].min
end

+ 22
- 0
app/controllers/api/v1/accounts/featured_tags_controller.rb View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
class Api::V1::Accounts::FeaturedTagsController < Api::BaseController
before_action :set_account
before_action :set_featured_tags
respond_to :json
def index
render json: @featured_tags, each_serializer: REST::AccountFeaturedTagSerializer
end
private
def set_account
@account = Account.find(params[:account_id])
end
def set_featured_tags
@featured_tags = @account.suspended? ? @account.featured_tags : []
end
end

+ 1
- 1
app/controllers/api/v1/accounts/follower_accounts_controller.rb View File

@ -25,7 +25,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
end
def hide_results?
(@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
@account.suspended? || (@account.hides_followers? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
end
def default_accounts

+ 1
- 1
app/controllers/api/v1/accounts/following_accounts_controller.rb View File

@ -25,7 +25,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
end
def hide_results?
(@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
@account.suspended? || (@account.hides_following? && current_account&.id != @account.id) || (current_account && @account.blocking?(current_account))
end
def default_accounts

+ 1
- 1
app/controllers/api/v1/accounts/identity_proofs_controller.rb View File

@ -5,7 +5,7 @@ class Api::V1::Accounts::IdentityProofsController < Api::BaseController
before_action :set_account
def index
@proofs = @account.identity_proofs.active
@proofs = @account.suspended? ? [] : @account.identity_proofs.active
render json: @proofs, each_serializer: REST::IdentityProofSerializer
end

+ 1
- 1
app/controllers/api/v1/accounts/lists_controller.rb View File

@ -6,7 +6,7 @@ class Api::V1::Accounts::ListsController < Api::BaseController
before_action :set_account
def index
@lists = @account.lists.where(account: current_account)
@lists = @account.suspended? ? [] : @account.lists.where(account: current_account)
render json: @lists, each_serializer: REST::ListSerializer
end

+ 1
- 1
app/controllers/api/v1/accounts/relationships_controller.rb View File

@ -5,7 +5,7 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController
before_action :require_user!
def index
accounts = Account.where(id: account_ids).select('id')
accounts = Account.without_suspended.where(id: account_ids).select('id')
# .where doesn't guarantee that our results are in the same order
# we requested them, so return the "right" order to the requestor.
@accounts = accounts.index_by(&:id).values_at(*account_ids).compact

+ 8
- 17
app/controllers/api/v1/accounts/statuses_controller.rb View File

@ -18,14 +18,10 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
end
def load_statuses
cached_account_statuses
@account.suspended? ? [] : cached_account_statuses
end
def cached_account_statuses
cache_collection account_statuses, Status
end
def account_statuses
statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses
statuses.merge!(only_media_scope) if truthy_param?(:only_media)
@ -33,7 +29,12 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
statuses.merge!(no_reblogs_scope) if truthy_param?(:exclude_reblogs)
statuses.merge!(hashtag_scope) if params[:tagged].present?
statuses.paginate_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id))
cache_collection_paginated_by_id(
statuses,
Status,
limit_param(DEFAULT_STATUSES_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)
end
def permitted_account_statuses
@ -41,17 +42,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
end
def only_media_scope
Status.where(id: account_media_status_ids)
end
def account_media_status_ids
# `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
# Also, Avoid getting slow by not narrowing down by `statuses.account_id`.
# When narrowing down by `statuses.account_id`, `index_statuses_20180106` will be used
# and the table will be joined by `Merge Semi Join`, so the query will be slow.
@account.statuses.joins(:media_attachments).merge(@account.media_attachments).permitted_for(@account, current_account)
.paginate_by_max_id(limit_param(DEFAULT_STATUSES_LIMIT), params[:max_id], params[:since_id])
.reorder(id: :desc).distinct(:id).pluck(:id)
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
end
def pinned_scope

+ 0
- 5
app/controllers/api/v1/accounts_controller.rb View File

@ -9,7 +9,6 @@ class Api::V1::AccountsController < Api::BaseController
before_action :require_user!, except: [:show, :create]
before_action :set_account, except: [:create]
before_action :check_account_suspension, only: [:show]
before_action :check_enabled_registrations, only: [:create]
skip_before_action :require_authenticated_user!, only: :create
@ -73,10 +72,6 @@ class Api::V1::AccountsController < Api::BaseController
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
end
def check_account_suspension
gone if @account.suspended?
end
def account_params
params.permit(:username, :email, :password, :agreement, :locale, :reason)
end

+ 1
- 1
app/controllers/api/v1/admin/accounts_controller.rb View File

@ -79,7 +79,7 @@ class Api::V1::Admin::AccountsController < Api::BaseController
private
def set_accounts
@accounts = filtered_accounts.order(id: :desc).includes(user: [:invite_request, :invite]).paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
@accounts = filtered_accounts.order(id: :desc).includes(user: [:invite_request, :invite]).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def set_account

+ 1
- 1
app/controllers/api/v1/admin/reports_controller.rb View File

@ -63,7 +63,7 @@ class Api::V1::Admin::ReportsController < Api::BaseController
private
def set_reports
@reports = filtered_reports.order(id: :desc).with_accounts.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
@reports = filtered_reports.order(id: :desc).with_accounts.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def set_report

+ 2
- 0
app/controllers/api/v1/blocks_controller.rb View File

@ -18,6 +18,8 @@ class Api::V1::BlocksController < Api::BaseController
def paginated_blocks
@paginated_blocks ||= Block.eager_load(target_account: :account_stat)
.joins(:target_account)
.merge(Account.without_suspended)
.where(account: current_account)
.paginate_by_max_id(
limit_param(DEFAULT_ACCOUNTS_LIMIT),

+ 2
- 5
app/controllers/api/v1/bookmarks_controller.rb View File

@ -17,14 +17,11 @@ class Api::V1::BookmarksController < Api::BaseController
end
def cached_bookmarks
cache_collection(
Status.reorder(nil).joins(:bookmarks).merge(results),
Status
)
cache_collection(results.map(&:status), Status)
end
def results
@_results ||= account_bookmarks.paginate_by_id(
@_results ||= account_bookmarks.eager_load(:status).to_a_paginated_by_id(
limit_param(DEFAULT_STATUSES_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)

+ 1
- 1
app/controllers/api/v1/conversations_controller.rb View File

@ -32,7 +32,7 @@ class Api::V1::ConversationsController < Api::BaseController
def paginated_conversations
AccountConversation.where(account: current_account)
.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def insert_pagination_headers

+ 1
- 1
app/controllers/api/v1/crypto/encrypted_messages_controller.rb View File

@ -26,7 +26,7 @@ class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController
end
def set_encrypted_messages
@encrypted_messages = @current_device.encrypted_messages.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
@encrypted_messages = @current_device.encrypted_messages.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def insert_pagination_headers

+ 1
- 1
app/controllers/api/v1/endorsements_controller.rb View File

@ -25,7 +25,7 @@ class Api::V1::EndorsementsController < Api::BaseController
end
def endorsed_accounts
current_account.endorsed_accounts.includes(:account_stat)
current_account.endorsed_accounts.includes(:account_stat).without_suspended
end
def insert_pagination_headers

+ 2
- 5
app/controllers/api/v1/favourites_controller.rb View File

@ -17,14 +17,11 @@ class Api::V1::FavouritesController < Api::BaseController
end
def cached_favourites
cache_collection(
Status.reorder(nil).joins(:favourites).merge(results),
Status
)
cache_collection(results.map(&:status), Status)
end
def results
@_results ||= account_favourites.paginate_by_id(
@_results ||= account_favourites.eager_load(:status).to_a_paginated_by_id(
limit_param(DEFAULT_STATUSES_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)

+ 4
- 4
app/controllers/api/v1/featured_tags/suggestions_controller.rb View File

@ -3,15 +3,15 @@
class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index
before_action :require_user!
before_action :set_most_used_tags, only: :index
before_action :set_recently_used_tags, only: :index
def index
render json: @most_used_tags, each_serializer: REST::TagSerializer
render json: @recently_used_tags, each_serializer: REST::TagSerializer
end
private
def set_most_used_tags
@most_used_tags = Tag.most_used(current_account).where.not(id: current_account.featured_tags).limit(10)
def set_recently_used_tags
@recently_used_tags = Tag.recently_used(current_account).where.not(id: current_account.featured_tags).limit(10)
end
end

+ 1
- 1
app/controllers/api/v1/follow_requests_controller.rb View File

@ -37,7 +37,7 @@ class Api::V1::FollowRequestsController < Api::BaseController
end
def default_accounts
Account.includes(:follow_requests, :account_stat).references(:follow_requests)
Account.without_suspended.includes(:follow_requests, :account_stat).references(:follow_requests)
end
def paginated_follow_requests

+ 2
- 2
app/controllers/api/v1/lists/accounts_controller.rb View File

@ -37,9 +37,9 @@ class Api::V1::Lists::AccountsController < Api::BaseController
def load_accounts
if unlimited?
@list.accounts.includes(:account_stat).all
@list.accounts.without_suspended.includes(:account_stat).all
else
@list.accounts.includes(:account_stat).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
@list.accounts.without_suspended.includes(:account_stat).paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
end
end

+ 1
- 1
app/controllers/api/v1/lists_controller.rb View File

@ -38,6 +38,6 @@ class Api::V1::ListsController < Api::BaseController
end
def list_params
params.permit(:title)
params.permit(:title, :replies_policy)
end
end

+ 2
- 0
app/controllers/api/v1/mutes_controller.rb View File

@ -18,6 +18,8 @@ class Api::V1::MutesController < Api::BaseController
def paginated_mutes
@paginated_mutes ||= Mute.eager_load(:target_account)
.joins(:target_account)
.merge(Account.without_suspended)
.where(account: current_account)
.paginate_by_max_id(
limit_param(DEFAULT_ACCOUNTS_LIMIT),

+ 5
- 7
app/controllers/api/v1/notifications_controller.rb View File

@ -14,7 +14,7 @@ class Api::V1::NotificationsController < Api::BaseController
end
def show
@notification = current_account.notifications.find(params[:id])
@notification = current_account.notifications.without_suspended.find(params[:id])
render json: @notification, serializer: REST::NotificationSerializer
end
@ -31,18 +31,16 @@ class Api::V1::NotificationsController < Api::BaseController
private
def load_notifications
cache_collection paginated_notifications, Notification
end
def paginated_notifications
browserable_account_notifications.paginate_by_id(
cache_collection_paginated_by_id(
browserable_account_notifications,
Notification,
limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)
end
def browserable_account_notifications
current_account.notifications.browserable(exclude_types, from_account)
current_account.notifications.without_suspended.browserable(exclude_types, from_account)
end
def target_statuses_from_notifications

+ 1
- 1
app/controllers/api/v1/scheduled_statuses_controller.rb View File

@ -32,7 +32,7 @@ class Api::V1::ScheduledStatusesController < Api::BaseController
private
def set_statuses
@statuses = current_account.scheduled_statuses.paginate_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id))
@statuses = current_account.scheduled_statuses.to_a_paginated_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def set_status

+ 1
- 0
app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb View File

@ -22,6 +22,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
def default_accounts
Account
.without_suspended
.includes(:favourites, :account_stat)
.references(:favourites)
.where(favourites: { status_id: @status.id })

+ 1
- 1
app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb View File

@ -21,7 +21,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
end
def default_accounts
Account.includes(:statuses, :account_stat).references(:statuses)
Account.without_suspended.includes(:statuses, :account_stat).references(:statuses)
end
def paginated_statuses

+ 14
- 15
app/controllers/api/v1/timelines/public_controller.rb View File

@ -16,30 +16,29 @@ class Api::V1::Timelines::PublicController < Api::BaseController
end
def load_statuses
cached_public_statuses
cached_public_statuses_page
end
def cached_public_statuses
cache_collection public_statuses, Status
def cached_public_statuses_page
cache_collection class="p">(public_statuses, Status)
end
def public_statuses
statuses = public_timeline_statuses.paginate_by_id(
public_feed.get(
limit_param(DEFAULT_STATUSES_LIMIT),
params_slice(:max_id, :since_id, :min_id)
params[:max_id],
params[:since_id],
params[:min_id]
)
if truthy_param?(:only_media)
# `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
status_ids = statuses.joins(:media_attachments).distinct(:id).pluck(:id)
statuses.where(id: status_ids)
else
statuses
end
end
def public_timeline_statuses
Status.as_public_timeline(current_account, truthy_param?(:remote) ? :remote : truthy_param?(:local))
def public_feed
PublicFeed.new(
current_account,
local: truthy_param?(:local),
remote: truthy_param?(:remote),
only_media: truthy_param?(:only_media)
)
end
def insert_pagination_headers

+ 19
- 20
app/controllers/api/v1/timelines/tag_controller.rb View File

@ -20,30 +20,29 @@ class Api::V1::Timelines::TagController < Api::BaseController
end
def cached_tagged_statuses
cache_collection tagged_statuses, Status
@tag.nil? ? [] : cache_collection(tag_timeline_statuses, Status)
end
def tagged_statuses
if @tag.nil?
[]
else
statuses = tag_timeline_statuses.paginate_by_id(
limit_param(DEFAULT_STATUSES_LIMIT),
params_slice(:max_id, :since_id, :min_id)
)
if truthy_param?(:only_media)
# `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
status_ids = statuses.joins(:media_attachments).distinct(:id).pluck(:id)
statuses.where(id: status_ids)
else
statuses
end
end
def tag_timeline_statuses
tag_feed.get(
limit_param(DEFAULT_STATUSES_LIMIT),
params[:max_id],
params[:since_id],
params[:min_id]
)
end
def tag_timeline_statuses
HashtagQueryService.new.call(@tag, params.slice(:any, :all, :none), current_account, truthy_param?(:local))
def tag_feed
TagFeed.new(
@tag,
current_account,
any: params[:any],
all: params[:all],
none: params[:none],
local: truthy_param?(:local),
remote: truthy_param?(:remote),
only_media: truthy_param?(:only_media)
)
end
def insert_pagination_headers

+ 17
- 1
app/controllers/auth/sessions_controller.rb View File

@ -37,6 +37,22 @@ class Auth::SessionsController < Devise::SessionsController
store_location_for(:user, tmp_stored_location) if continue_after?
end
def webauthn_options
user = find_user
if user.webauthn_enabled?
options_for_get = WebAuthn::Credential.options_for_get(
allow: user.webauthn_credentials.pluck(:external_id)
)
session[:webauthn_challenge] = options_for_get.challenge
render json: options_for_get, status: :ok
else
render json: { error: t('webauthn_credentials.not_enabled') }, status: :unauthorized
end
end
protected
def find_user
@ -51,7 +67,7 @@ class Auth::SessionsController < Devise::SessionsController
end
def user_params
params.require(:user).permit(:email, :password, :otp_attempt, :sign_in_token_attempt)
params.require(:user).permit(:email, :password, :otp_attempt, :sign_in_token_attempt, credential: {})
end
def after_sign_in_path_for(resource)

+ 4
- 0
app/controllers/concerns/cache_concern.rb View File

@ -47,4 +47,8 @@ module CacheConcern
raw.map { |item| cached_keys_with_value[item.id] || uncached[item.id] }.compact
end