Merge branch 'refs/heads/glitch' into develop

This commit is contained in:
Jeremy Kescher 2024-07-04 18:15:12 +02:00
commit 4f80bc8493
No known key found for this signature in database
GPG key ID: 80A419A7A613DFA4
41 changed files with 243 additions and 77 deletions

View file

@ -4,6 +4,12 @@ All changes to Catstodon that aren't Mastodon or glitch-soc Mastodon changes wil
All release dates, as well as most other dates, are intended to be read as "within the day, in UTC time." All release dates, as well as most other dates, are intended to be read as "within the day, in UTC time."
## [v4.3.0-alpha.5+glitch+cat+1.0.0] - 2024-07-04
- Upstream changes. Important for security! Upgrade now.
- See version 4.2.10 in [CHANGELOG_glitch.md](CHANGELOG_glitch.md)
or [The vanilla Mastodon 4.2.10 release page](https://github.com/mastodon/mastodon/releases/tag/v4.2.10).
## [v4.3.0-alpha.4+glitch+cat+1.1.3] - 2024-07-02 ## [v4.3.0-alpha.4+glitch+cat+1.1.3] - 2024-07-02
- Upstream changes - Upstream changes

View file

@ -2,6 +2,37 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [4.2.10] - 2024-07-04
### Security
- Fix incorrect permission checking on multiple API endpoints ([GHSA-58x8-3qxw-6hm7](https://github.com/mastodon/mastodon/security/advisories/GHSA-58x8-3qxw-6hm7))
- Fix incorrect authorship checking when processing some activities (CVE-2024-37903, [GHSA-xjvf-fm67-4qc3](https://github.com/mastodon/mastodon/security/advisories/GHSA-xjvf-fm67-4qc3))
- Fix ongoing streaming sessions not being invalidated when application tokens get revoked ([GHSA-vp5r-5pgw-jwqx](https://github.com/mastodon/mastodon/security/advisories/GHSA-vp5r-5pgw-jwqx))
- Update dependencies
### Added
- Add yarn version specification to avoid confusion with Yarn 3 and Yarn 4
### Changed
- Change preview cards generation to skip unusually long URLs ([oneiros](https://github.com/mastodon/mastodon/pull/30854))
- Change search modifiers to be case-insensitive ([Gargron](https://github.com/mastodon/mastodon/pull/30865))
- Change `STATSD_ADDR` handling to emit a warning rather than crashing if the address is unreachable ([timothyjrogers](https://github.com/mastodon/mastodon/pull/30691))
- Change PWA start URL from `/home` to `/` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27377))
### Removed
- Removed dependency on `posix-spawn` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18559))
### Fixed
- Fix scheduled statuses scheduled in less than 5 minutes being immediately published ([danielmbrasil](https://github.com/mastodon/mastodon/pull/30584))
- Fix encoding detection for link cards ([oneiros](https://github.com/mastodon/mastodon/pull/30780))
- Fix `/admin/accounts/:account_id/statuses/:id` for edited posts with media attachments ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30819))
- Fix duplicate `@context` attribute in user archive export ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30653))
## [4.2.9] - 2024-05-30 ## [4.2.9] - 2024-05-30
### Security ### Security

View file

@ -25,7 +25,7 @@ gem 'ruby-vips', '~> 2.2', require: false
gem 'active_model_serializers', '~> 0.10' gem 'active_model_serializers', '~> 0.10'
gem 'addressable', '~> 2.8' gem 'addressable', '~> 2.8'
gem 'bootsnap', '~> 1.18.0', require: false gem 'bootsnap', '~> 1.18.0', require: false
gem 'browser' gem 'browser', '< 6' # https://github.com/fnando/browser/issues/543
gem 'charlock_holmes', '~> 0.7.7' gem 'charlock_holmes', '~> 0.7.7'
gem 'chewy', '~> 7.3' gem 'chewy', '~> 7.3'
gem 'devise', '~> 4.9' gem 'devise', '~> 4.9'
@ -114,7 +114,7 @@ group :opentelemetry do
gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false
gem 'opentelemetry-instrumentation-pg', '~> 0.27.1', require: false gem 'opentelemetry-instrumentation-pg', '~> 0.27.1', require: false
gem 'opentelemetry-instrumentation-rack', '~> 0.24.1', require: false gem 'opentelemetry-instrumentation-rack', '~> 0.24.1', require: false
gem 'opentelemetry-instrumentation-rails', '~> 0.30.0', require: false gem 'opentelemetry-instrumentation-rails', '~> 0.31.0', require: false
gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false
gem 'opentelemetry-sdk', '~> 1.4', require: false gem 'opentelemetry-sdk', '~> 1.4', require: false

View file

@ -100,19 +100,19 @@ GEM
attr_required (1.0.2) attr_required (1.0.2)
awrence (1.2.1) awrence (1.2.1)
aws-eventstream (1.3.0) aws-eventstream (1.3.0)
aws-partitions (1.949.0) aws-partitions (1.950.0)
aws-sdk-core (3.200.0) aws-sdk-core (3.201.0)
aws-eventstream (~> 1, >= 1.3.0) aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0) aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8) aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1) jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.87.0) aws-sdk-kms (1.88.0)
aws-sdk-core (~> 3, >= 3.199.0) aws-sdk-core (~> 3, >= 3.201.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.155.0) aws-sdk-s3 (1.156.0)
aws-sdk-core (~> 3, >= 3.199.0) aws-sdk-core (~> 3, >= 3.201.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8) aws-sigv4 (~> 1.5)
aws-sigv4 (1.8.0) aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
azure-storage-blob (2.0.3) azure-storage-blob (2.0.3)
@ -208,7 +208,7 @@ GEM
activerecord (>= 4.2, < 8) activerecord (>= 4.2, < 8)
docile (1.4.0) docile (1.4.0)
domain_name (0.6.20240107) domain_name (0.6.20240107)
doorkeeper (5.6.9) doorkeeper (5.7.1)
railties (>= 5) railties (>= 5)
dotenv (3.1.2) dotenv (3.1.2)
drb (2.2.1) drb (2.2.1)
@ -431,7 +431,7 @@ GEM
mime-types-data (3.2024.0604) mime-types-data (3.2024.0604)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.7) mini_portile2 (2.8.7)
minitest (5.23.1) minitest (5.24.1)
msgpack (1.7.2) msgpack (1.7.2)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.4.0) multipart-post (2.4.0)
@ -516,7 +516,7 @@ GEM
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-active_support (~> 0.1) opentelemetry-instrumentation-active_support (~> 0.1)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_job (0.7.1) opentelemetry-instrumentation-active_job (0.7.2)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_model_serializers (0.20.1) opentelemetry-instrumentation-active_model_serializers (0.20.1)
@ -525,7 +525,7 @@ GEM
opentelemetry-instrumentation-active_record (0.7.2) opentelemetry-instrumentation-active_record (0.7.2)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-active_support (0.5.1) opentelemetry-instrumentation-active_support (0.6.0)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-base (0.22.3) opentelemetry-instrumentation-base (0.22.3)
@ -556,19 +556,19 @@ GEM
opentelemetry-instrumentation-rack (0.24.5) opentelemetry-instrumentation-rack (0.24.5)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-rails (0.30.2) opentelemetry-instrumentation-rails (0.31.0)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-action_mailer (~> 0.1.0) opentelemetry-instrumentation-action_mailer (~> 0.1.0)
opentelemetry-instrumentation-action_pack (~> 0.9.0) opentelemetry-instrumentation-action_pack (~> 0.9.0)
opentelemetry-instrumentation-action_view (~> 0.7.0) opentelemetry-instrumentation-action_view (~> 0.7.0)
opentelemetry-instrumentation-active_job (~> 0.7.0) opentelemetry-instrumentation-active_job (~> 0.7.0)
opentelemetry-instrumentation-active_record (~> 0.7.0) opentelemetry-instrumentation-active_record (~> 0.7.0)
opentelemetry-instrumentation-active_support (~> 0.5.0) opentelemetry-instrumentation-active_support (~> 0.6.0)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-redis (0.25.6) opentelemetry-instrumentation-redis (0.25.6)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-instrumentation-sidekiq (0.25.5) opentelemetry-instrumentation-sidekiq (0.25.6)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-base (~> 0.22.1)
opentelemetry-registry (0.3.1) opentelemetry-registry (0.3.1)
@ -756,7 +756,7 @@ GEM
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0) rubocop (>= 1.33.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (3.0.1) rubocop-rspec (3.0.2)
rubocop (~> 1.61) rubocop (~> 1.61)
rubocop-rspec_rails (2.30.0) rubocop-rspec_rails (2.30.0)
rubocop (~> 1.61) rubocop (~> 1.61)
@ -916,7 +916,7 @@ DEPENDENCIES
blurhash (~> 0.1) blurhash (~> 0.1)
bootsnap (~> 1.18.0) bootsnap (~> 1.18.0)
brakeman (~> 6.0) brakeman (~> 6.0)
browser browser (< 6)
bundler-audit (~> 0.9) bundler-audit (~> 0.9)
capybara (~> 3.39) capybara (~> 3.39)
charlock_holmes (~> 0.7.7) charlock_holmes (~> 0.7.7)
@ -994,7 +994,7 @@ DEPENDENCIES
opentelemetry-instrumentation-net_http (~> 0.22.4) opentelemetry-instrumentation-net_http (~> 0.22.4)
opentelemetry-instrumentation-pg (~> 0.27.1) opentelemetry-instrumentation-pg (~> 0.27.1)
opentelemetry-instrumentation-rack (~> 0.24.1) opentelemetry-instrumentation-rack (~> 0.24.1)
opentelemetry-instrumentation-rails (~> 0.30.0) opentelemetry-instrumentation-rails (~> 0.31.0)
opentelemetry-instrumentation-redis (~> 0.25.3) opentelemetry-instrumentation-redis (~> 0.25.3)
opentelemetry-instrumentation-sidekiq (~> 0.25.2) opentelemetry-instrumentation-sidekiq (~> 0.25.2)
opentelemetry-sdk (~> 1.4) opentelemetry-sdk (~> 1.4)

View file

@ -6,6 +6,7 @@ class Api::V1::ScheduledStatusesController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, except: [:update, :destroy] before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, except: [:update, :destroy]
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:update, :destroy] before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:update, :destroy]
before_action :require_user!
before_action :set_statuses, only: :index before_action :set_statuses, only: :index
before_action :set_status, except: :index before_action :set_status, except: :index

View file

@ -2,6 +2,7 @@
class Api::V1::Statuses::TranslationsController < Api::V1::Statuses::BaseController class Api::V1::Statuses::TranslationsController < Api::V1::Statuses::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:statuses' } before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
before_action :require_user!
before_action :set_translation before_action :set_translation
rescue_from TranslationService::NotConfiguredError, with: :not_found rescue_from TranslationService::NotConfiguredError, with: :not_found

View file

@ -3,8 +3,14 @@
class Api::V1::Timelines::BaseController < Api::BaseController class Api::V1::Timelines::BaseController < Api::BaseController
after_action :insert_pagination_headers, unless: -> { @statuses.empty? } after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
before_action :require_user!, if: :require_auth?
private private
def require_auth?
!Setting.timeline_preview
end
def pagination_collection def pagination_collection
@statuses @statuses
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Timelines::LinkController < Api::V1::Timelines::BaseController class Api::V1::Timelines::LinkController < Api::V1::Timelines::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :show, if: :require_auth? before_action -> { authorize_if_got_token! :read, :'read:statuses' }
before_action :set_preview_card before_action :set_preview_card
before_action :set_statuses before_action :set_statuses
@ -17,10 +17,6 @@ class Api::V1::Timelines::LinkController < Api::V1::Timelines::BaseController
private private
def require_auth?
!Setting.timeline_preview
end
def set_preview_card def set_preview_card
@preview_card = PreviewCard.joins(:trend).merge(PreviewCardTrend.allowed).find_by!(url: params[:url]) @preview_card = PreviewCard.joins(:trend).merge(PreviewCardTrend.allowed).find_by!(url: params[:url])
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Timelines::PublicController < Api::V1::Timelines::BaseController class Api::V1::Timelines::PublicController < Api::V1::Timelines::BaseController
before_action :require_user!, only: [:show], if: :require_auth? before_action -> { authorize_if_got_token! :read, :'read:statuses' }
PERMITTED_PARAMS = %i(local remote limit only_media allow_local_only).freeze PERMITTED_PARAMS = %i(local remote limit only_media allow_local_only).freeze
@ -13,10 +13,6 @@ class Api::V1::Timelines::PublicController < Api::V1::Timelines::BaseController
private private
def require_auth?
!Setting.timeline_preview
end
def load_statuses def load_statuses
preloaded_public_statuses_page preloaded_public_statuses_page
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Timelines::TagController < Api::V1::Timelines::BaseController class Api::V1::Timelines::TagController < Api::V1::Timelines::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :show, if: :require_auth? before_action -> { authorize_if_got_token! :read, :'read:statuses' }
before_action :load_tag before_action :load_tag
PERMITTED_PARAMS = %i(local limit only_media).freeze PERMITTED_PARAMS = %i(local limit only_media).freeze

View file

@ -17,6 +17,7 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
def destroy def destroy
Web::PushSubscription.unsubscribe_for(params[:id], current_resource_owner) Web::PushSubscription.unsubscribe_for(params[:id], current_resource_owner)
Doorkeeper::Application.find_by(id: params[:id])&.close_streaming_sessions(current_resource_owner)
super super
end end

View file

@ -35,7 +35,9 @@
"account.follow_back": "Follow back", "account.follow_back": "Follow back",
"account.followers": "Followers", "account.followers": "Followers",
"account.followers.empty": "No one follows this user yet.", "account.followers.empty": "No one follows this user yet.",
"account.followers_counter": "{count, plural, one {{counter} follower} other {{counter} followers}}",
"account.following": "Following", "account.following": "Following",
"account.following_counter": "{count, plural, one {{counter} following} other {{counter} following}}",
"account.follows.empty": "This user doesn't follow anyone yet.", "account.follows.empty": "This user doesn't follow anyone yet.",
"account.go_to_profile": "Go to profile", "account.go_to_profile": "Go to profile",
"account.hide_reblogs": "Hide boosts from @{name}", "account.hide_reblogs": "Hide boosts from @{name}",
@ -61,6 +63,7 @@
"account.requested_follow": "{name} has requested to follow you", "account.requested_follow": "{name} has requested to follow you",
"account.share": "Share @{name}'s profile", "account.share": "Share @{name}'s profile",
"account.show_reblogs": "Show boosts from @{name}", "account.show_reblogs": "Show boosts from @{name}",
"account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} posts}}",
"account.unblock": "Unblock @{name}", "account.unblock": "Unblock @{name}",
"account.unblock_domain": "Unblock domain {domain}", "account.unblock_domain": "Unblock domain {domain}",
"account.unblock_short": "Unblock", "account.unblock_short": "Unblock",
@ -411,6 +414,8 @@
"limited_account_hint.action": "Show profile anyway", "limited_account_hint.action": "Show profile anyway",
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.", "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
"link_preview.author": "By {name}", "link_preview.author": "By {name}",
"link_preview.more_from_author": "More from {name}",
"link_preview.shares": "{count, plural, one {{counter} post} other {{counter} posts}}",
"lists.account.add": "Add to list", "lists.account.add": "Add to list",
"lists.account.remove": "Remove from list", "lists.account.remove": "Remove from list",
"lists.delete": "Delete list", "lists.delete": "Delete list",
@ -691,8 +696,11 @@
"server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)", "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)",
"server_banner.active_users": "active users", "server_banner.active_users": "active users",
"server_banner.administered_by": "Administered by:", "server_banner.administered_by": "Administered by:",
"server_banner.is_one_of_many": "{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.",
"server_banner.server_stats": "Server stats:", "server_banner.server_stats": "Server stats:",
"sign_in_banner.create_account": "Create account", "sign_in_banner.create_account": "Create account",
"sign_in_banner.follow_anyone": "Follow anyone across the fediverse and see it all in chronological order. No algorithms, ads, or clickbait in sight.",
"sign_in_banner.mastodon_is": "Mastodon is the best way to keep up with what's happening.",
"sign_in_banner.sign_in": "Sign in", "sign_in_banner.sign_in": "Sign in",
"sign_in_banner.sso_redirect": "Login or Register", "sign_in_banner.sso_redirect": "Login or Register",
"status.admin_account": "Open moderation interface for @{name}", "status.admin_account": "Open moderation interface for @{name}",

View file

@ -224,7 +224,7 @@
"domain_pill.their_server": "O seu fogar dixital, onde están as súas publicacións.", "domain_pill.their_server": "O seu fogar dixital, onde están as súas publicacións.",
"domain_pill.their_username": "O seu identificador único no seu servidor. É posible atopar usuarias co mesmo nome de usuaria en diferentes servidores.", "domain_pill.their_username": "O seu identificador único no seu servidor. É posible atopar usuarias co mesmo nome de usuaria en diferentes servidores.",
"domain_pill.username": "Nome de usuaria", "domain_pill.username": "Nome de usuaria",
"domain_pill.whats_in_a_handle": "Que é o alcume?", "domain_pill.whats_in_a_handle": "As partes do alcume?",
"domain_pill.who_they_are": "O alcume dinos quen é esa persoa e onde está, para que poidas interactuar con ela en toda a web social de <button>plataformas ActivityPub</button>.", "domain_pill.who_they_are": "O alcume dinos quen é esa persoa e onde está, para que poidas interactuar con ela en toda a web social de <button>plataformas ActivityPub</button>.",
"domain_pill.who_you_are": "Como o teu alcume informa de quen es e onde estás, as persoas poden interactuar contigo desde toda a web social de <button>plataformas ActivityPub</button>.", "domain_pill.who_you_are": "Como o teu alcume informa de quen es e onde estás, as persoas poden interactuar contigo desde toda a web social de <button>plataformas ActivityPub</button>.",
"domain_pill.your_handle": "O teu alcume:", "domain_pill.your_handle": "O teu alcume:",

View file

@ -35,7 +35,9 @@
"account.follow_back": "לעקוב בחזרה", "account.follow_back": "לעקוב בחזרה",
"account.followers": "עוקבים", "account.followers": "עוקבים",
"account.followers.empty": "אף אחד לא עוקב אחר המשתמש הזה עדיין.", "account.followers.empty": "אף אחד לא עוקב אחר המשתמש הזה עדיין.",
"account.followers_counter": "{count, plural,one {עוקב אחד} other {{count} עוקבים}}",
"account.following": "נעקבים", "account.following": "נעקבים",
"account.following_counter": "{count, plural,one {עוקב אחרי {count}}other {עוקב אחרי {count}}}",
"account.follows.empty": "משתמש זה עדיין לא עוקב אחרי אף אחד.", "account.follows.empty": "משתמש זה עדיין לא עוקב אחרי אף אחד.",
"account.go_to_profile": "מעבר לפרופיל", "account.go_to_profile": "מעבר לפרופיל",
"account.hide_reblogs": "להסתיר הידהודים מאת @{name}", "account.hide_reblogs": "להסתיר הידהודים מאת @{name}",
@ -61,6 +63,7 @@
"account.requested_follow": "{name} ביקשו לעקוב אחריך", "account.requested_follow": "{name} ביקשו לעקוב אחריך",
"account.share": "שתף את הפרופיל של @{name}", "account.share": "שתף את הפרופיל של @{name}",
"account.show_reblogs": "הצג הדהודים מאת @{name}", "account.show_reblogs": "הצג הדהודים מאת @{name}",
"account.statuses_counter": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{count} הודעות} other {{count} הודעות}}",
"account.unblock": "להסיר חסימה ל- @{name}", "account.unblock": "להסיר חסימה ל- @{name}",
"account.unblock_domain": "הסירי את החסימה של קהילת {domain}", "account.unblock_domain": "הסירי את החסימה של קהילת {domain}",
"account.unblock_short": "הסר חסימה", "account.unblock_short": "הסר חסימה",
@ -693,8 +696,11 @@
"server_banner.about_active_users": "משתמשים פעילים בשרת ב־30 הימים האחרונים (משתמשים פעילים חודשיים)", "server_banner.about_active_users": "משתמשים פעילים בשרת ב־30 הימים האחרונים (משתמשים פעילים חודשיים)",
"server_banner.active_users": "משתמשים פעילים", "server_banner.active_users": "משתמשים פעילים",
"server_banner.administered_by": "מנוהל ע\"י:", "server_banner.administered_by": "מנוהל ע\"י:",
"server_banner.is_one_of_many": "{domain} הוא שרת אחד משרתי מסטודון עצמאיים רבים שדרגם תוכלו להשתתף בפדיוורס (רשת חברתית מבוזרת).",
"server_banner.server_stats": "סטטיסטיקות שרת:", "server_banner.server_stats": "סטטיסטיקות שרת:",
"sign_in_banner.create_account": "יצירת חשבון", "sign_in_banner.create_account": "יצירת חשבון",
"sign_in_banner.follow_anyone": "תוכלו לעקוב אחרי כל משמתמש בפדיוורס ולקרוא הכל לפי סדר הפרסום בציר הזמן. אין אלגוריתמים, פרסומות, או קליקבייט מטעם בעלי הרשת.",
"sign_in_banner.mastodon_is": "מסטודון הוא הדרך הטובה ביותר לעקוב אחרי מה שקורה.",
"sign_in_banner.sign_in": "התחברות", "sign_in_banner.sign_in": "התחברות",
"sign_in_banner.sso_redirect": "התחברות/הרשמה", "sign_in_banner.sso_redirect": "התחברות/הרשמה",
"status.admin_account": "פתח/י ממשק ניהול עבור @{name}", "status.admin_account": "פתח/י ממשק ניהול עבור @{name}",
@ -771,7 +777,7 @@
"timeline_hint.resources.followers": "עוקבים", "timeline_hint.resources.followers": "עוקבים",
"timeline_hint.resources.follows": "נעקבים", "timeline_hint.resources.follows": "נעקבים",
"timeline_hint.resources.statuses": "הודעות ישנות יותר", "timeline_hint.resources.statuses": "הודעות ישנות יותר",
"trends.counter_by_accounts": "{count, plural, one {אדם {count}} other {{count} א.נשים}} {days, plural, one {מאז אתמול} two {ביומיים האחרונים} other {במשך {days} הימים האחרונים}}", "trends.counter_by_accounts": "{count, plural, one {אדם אחד} other {{count} א.נשים}} {days, plural, one {מאז אתמול} two {ביומיים האחרונים} other {במשך {days} הימים האחרונים}}",
"trends.trending_now": "נושאים חמים", "trends.trending_now": "נושאים חמים",
"ui.beforeunload": "הטיוטא תאבד אם תעזבו את מסטודון.", "ui.beforeunload": "הטיוטא תאבד אם תעזבו את מסטודון.",
"units.short.billion": "{count} מליארד", "units.short.billion": "{count} מליארד",

View file

@ -354,7 +354,7 @@
"home.pending_critical_update.link": "Vider actualisationes", "home.pending_critical_update.link": "Vider actualisationes",
"home.pending_critical_update.title": "Actualisation de securitate critic disponibile!", "home.pending_critical_update.title": "Actualisation de securitate critic disponibile!",
"home.show_announcements": "Monstrar annuncios", "home.show_announcements": "Monstrar annuncios",
"interaction_modal.description.favourite": "Con un conto sur Mastodon, tu pote marcar iste message como favorite pro informar le autor que tu lo apprecia e salveguarda pro plus tarde.", "interaction_modal.description.favourite": "Con un conto sur Mastodon, tu pote marcar iste message como favorite pro informar le autor que tu lo apprecia e lo salva pro plus tarde.",
"interaction_modal.description.follow": "Con un conto sur Mastodon, tu pote sequer {name} e reciper su messages in tu fluxo de initio.", "interaction_modal.description.follow": "Con un conto sur Mastodon, tu pote sequer {name} e reciper su messages in tu fluxo de initio.",
"interaction_modal.description.reblog": "Con un conto sur Mastodon, tu pote impulsar iste message pro condivider lo con tu proprie sequitores.", "interaction_modal.description.reblog": "Con un conto sur Mastodon, tu pote impulsar iste message pro condivider lo con tu proprie sequitores.",
"interaction_modal.description.reply": "Con un conto sur Mastodon, tu pote responder a iste message.", "interaction_modal.description.reply": "Con un conto sur Mastodon, tu pote responder a iste message.",
@ -764,7 +764,7 @@
"status.unmute_conversation": "Non plus silentiar conversation", "status.unmute_conversation": "Non plus silentiar conversation",
"status.unpin": "Disfixar del profilo", "status.unpin": "Disfixar del profilo",
"subscribed_languages.lead": "Solmente le messages in le linguas seligite apparera in tu chronologias de initio e de listas post le cambiamento. Selige necun pro reciper messages in tote le linguas.", "subscribed_languages.lead": "Solmente le messages in le linguas seligite apparera in tu chronologias de initio e de listas post le cambiamento. Selige necun pro reciper messages in tote le linguas.",
"subscribed_languages.save": "Salveguardar le cambiamentos", "subscribed_languages.save": "Salvar le cambiamentos",
"subscribed_languages.target": "Cambiar le linguas subscribite pro {target}", "subscribed_languages.target": "Cambiar le linguas subscribite pro {target}",
"tabs_bar.home": "Initio", "tabs_bar.home": "Initio",
"tabs_bar.notifications": "Notificationes", "tabs_bar.notifications": "Notificationes",

View file

@ -88,7 +88,10 @@
"audio.hide": "Skryť zvuk", "audio.hide": "Skryť zvuk",
"block_modal.show_less": "Zobraziť menej", "block_modal.show_less": "Zobraziť menej",
"block_modal.show_more": "Zobraziť viac", "block_modal.show_more": "Zobraziť viac",
"block_modal.they_cant_mention": "Nemôžu ťa spomenúť, alebo nasledovať.",
"block_modal.they_will_know": "Môžu vidieť, že sú zablokovaní/ý.",
"block_modal.title": "Blokovať užívateľa?", "block_modal.title": "Blokovať užívateľa?",
"block_modal.you_wont_see_mentions": "Neuvidíš príspevky, ktoré ich spomínajú.",
"boost_modal.combo": "Nabudúce môžete preskočiť stlačením {combo}", "boost_modal.combo": "Nabudúce môžete preskočiť stlačením {combo}",
"bundle_column_error.copy_stacktrace": "Kopírovať chybovú hlášku", "bundle_column_error.copy_stacktrace": "Kopírovať chybovú hlášku",
"bundle_column_error.error.body": "Požadovanú stránku nebolo možné vykresliť. Môže to byť spôsobené chybou v našom kóde alebo problémom s kompatibilitou prehliadača.", "bundle_column_error.error.body": "Požadovanú stránku nebolo možné vykresliť. Môže to byť spôsobené chybou v našom kóde alebo problémom s kompatibilitou prehliadača.",

View file

@ -35,7 +35,9 @@
"account.follow_back": "Uzvrati praćenje", "account.follow_back": "Uzvrati praćenje",
"account.followers": "Pratioci", "account.followers": "Pratioci",
"account.followers.empty": "Još uvek niko ne prati ovog korisnika.", "account.followers.empty": "Još uvek niko ne prati ovog korisnika.",
"account.followers_counter": "{count, plural, one {{counter} pratilac} few {{counter} pratioca} other {{counter} pratilaca}}",
"account.following": "Prati", "account.following": "Prati",
"account.following_counter": "{count, plural, one {{counter} prati} few {{counter} prati} other {{counter} prati}}",
"account.follows.empty": "Ovaj korisnik još uvek nikog ne prati.", "account.follows.empty": "Ovaj korisnik još uvek nikog ne prati.",
"account.go_to_profile": "Idi na profil", "account.go_to_profile": "Idi na profil",
"account.hide_reblogs": "Sakrij podržavanja @{name}", "account.hide_reblogs": "Sakrij podržavanja @{name}",
@ -61,6 +63,7 @@
"account.requested_follow": "{name} je zatražio da vas prati", "account.requested_follow": "{name} je zatražio da vas prati",
"account.share": "Podeli profil korisnika @{name}", "account.share": "Podeli profil korisnika @{name}",
"account.show_reblogs": "Prikaži podržavanja od korisnika @{name}", "account.show_reblogs": "Prikaži podržavanja od korisnika @{name}",
"account.statuses_counter": "{count, plural, one {{counter} objava} few {{counter} objave} other {{counter} objava}}",
"account.unblock": "Odblokiraj korisnika @{name}", "account.unblock": "Odblokiraj korisnika @{name}",
"account.unblock_domain": "Odblokiraj domen {domain}", "account.unblock_domain": "Odblokiraj domen {domain}",
"account.unblock_short": "Odblokiraj", "account.unblock_short": "Odblokiraj",

View file

@ -35,7 +35,9 @@
"account.follow_back": "Узврати праћење", "account.follow_back": "Узврати праћење",
"account.followers": "Пратиоци", "account.followers": "Пратиоци",
"account.followers.empty": "Још увек нико не прати овог корисника.", "account.followers.empty": "Још увек нико не прати овог корисника.",
"account.followers_counter": "{count, plural, one {{counter} пратилац} few {{counter} пратиоца} other {{counter} пратилаца}}",
"account.following": "Прати", "account.following": "Прати",
"account.following_counter": "{count, plural, one {{counter} прати} few {{counter} прати} other {{counter} прати}}",
"account.follows.empty": "Овај корисник још увек никог не прати.", "account.follows.empty": "Овај корисник још увек никог не прати.",
"account.go_to_profile": "Иди на профил", "account.go_to_profile": "Иди на профил",
"account.hide_reblogs": "Сакриј подржавања од @{name}", "account.hide_reblogs": "Сакриј подржавања од @{name}",
@ -61,6 +63,7 @@
"account.requested_follow": "{name} је затражио да вас прати", "account.requested_follow": "{name} је затражио да вас прати",
"account.share": "Подели профил корисника @{name}", "account.share": "Подели профил корисника @{name}",
"account.show_reblogs": "Прикажи подржавања од корисника @{name}", "account.show_reblogs": "Прикажи подржавања од корисника @{name}",
"account.statuses_counter": "{count, plural, one {{counter} објава} few {{counter} објаве} other {{counter} објава}}",
"account.unblock": "Одблокирај корисника @{name}", "account.unblock": "Одблокирај корисника @{name}",
"account.unblock_domain": "Одблокирај домен {domain}", "account.unblock_domain": "Одблокирај домен {domain}",
"account.unblock_short": "Одблокирај", "account.unblock_short": "Одблокирај",

View file

@ -35,7 +35,9 @@
"account.follow_back": "Підписатися взаємно", "account.follow_back": "Підписатися взаємно",
"account.followers": "Підписники", "account.followers": "Підписники",
"account.followers.empty": "Ніхто ще не підписаний на цього користувача.", "account.followers.empty": "Ніхто ще не підписаний на цього користувача.",
"account.followers_counter": "{count, plural, one {{counter} підписник} few {{counter} підписники} many {{counter} підписників} other {{counter} підписники}}",
"account.following": "Ви стежите", "account.following": "Ви стежите",
"account.following_counter": "{count, plural, one {{counter} підписка} few {{counter} підписки} many {{counter} підписок} other {{counter} підписки}}",
"account.follows.empty": "Цей користувач ще ні на кого не підписався.", "account.follows.empty": "Цей користувач ще ні на кого не підписався.",
"account.go_to_profile": "Перейти до профілю", "account.go_to_profile": "Перейти до профілю",
"account.hide_reblogs": "Сховати поширення від @{name}", "account.hide_reblogs": "Сховати поширення від @{name}",
@ -61,6 +63,7 @@
"account.requested_follow": "{name} надсилає запит на стеження", "account.requested_follow": "{name} надсилає запит на стеження",
"account.share": "Поділитися профілем @{name}", "account.share": "Поділитися профілем @{name}",
"account.show_reblogs": "Показати поширення від @{name}", "account.show_reblogs": "Показати поширення від @{name}",
"account.statuses_counter": "{count, plural, one {{counter} допис} few {{counter} дописи} many {{counter} дописів} other {{counter} допис}}",
"account.unblock": "Розблокувати @{name}", "account.unblock": "Розблокувати @{name}",
"account.unblock_domain": "Розблокувати {domain}", "account.unblock_domain": "Розблокувати {domain}",
"account.unblock_short": "Розблокувати", "account.unblock_short": "Розблокувати",
@ -412,6 +415,7 @@
"limited_account_hint.title": "Цей профіль сховали модератори {domain}.", "limited_account_hint.title": "Цей профіль сховали модератори {domain}.",
"link_preview.author": "Від {name}", "link_preview.author": "Від {name}",
"link_preview.more_from_author": "Більше від {name}", "link_preview.more_from_author": "Більше від {name}",
"link_preview.shares": "{count, plural, one {{counter} допис} few {{counter} дописи} many {{counter} дописів} other {{counter} допис}}",
"lists.account.add": "Додати до списку", "lists.account.add": "Додати до списку",
"lists.account.remove": "Вилучити зі списку", "lists.account.remove": "Вилучити зі списку",
"lists.delete": "Видалити список", "lists.delete": "Видалити список",
@ -695,6 +699,7 @@
"server_banner.is_one_of_many": "{domain} - один з багатьох незалежних серверів Mastodon, які ви можете використати, щоб брати участь у федівері.", "server_banner.is_one_of_many": "{domain} - один з багатьох незалежних серверів Mastodon, які ви можете використати, щоб брати участь у федівері.",
"server_banner.server_stats": "Статистика сервера:", "server_banner.server_stats": "Статистика сервера:",
"sign_in_banner.create_account": "Створити обліковий запис", "sign_in_banner.create_account": "Створити обліковий запис",
"sign_in_banner.follow_anyone": "Слідкуйте за ким завгодно у всьому fediverse і дивіться все це в хронологічному порядку. Немає алгоритмів, реклами чи наживок для натискань при перегляді.",
"sign_in_banner.mastodon_is": "Мастодон - найкращий спосіб продовжувати свою справу.", "sign_in_banner.mastodon_is": "Мастодон - найкращий спосіб продовжувати свою справу.",
"sign_in_banner.sign_in": "Увійти", "sign_in_banner.sign_in": "Увійти",
"sign_in_banner.sso_redirect": "Увійдіть або зареєструйтесь", "sign_in_banner.sso_redirect": "Увійдіть або зареєструйтесь",

View file

@ -116,7 +116,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
def find_existing_status def find_existing_status
status = status_from_uri(object_uri) status = status_from_uri(object_uri)
status ||= Status.find_by(uri: @object['atomUri']) if @object['atomUri'].present? status ||= Status.find_by(uri: @object['atomUri']) if @object['atomUri'].present?
status status if status&.account_id == @account.id
end end
def process_status_params def process_status_params

View file

@ -16,7 +16,7 @@ module ApplicationExtension
# dependent: delete_all, which means the ActiveRecord callback in # dependent: delete_all, which means the ActiveRecord callback in
# AccessTokenExtension is not run, so instead we manually announce to # AccessTokenExtension is not run, so instead we manually announce to
# streaming that these tokens are being deleted. # streaming that these tokens are being deleted.
before_destroy :push_to_streaming_api, prepend: true before_destroy :close_streaming_sessions, prepend: true
end end
def confirmation_redirect_uri def confirmation_redirect_uri
@ -29,10 +29,12 @@ module ApplicationExtension
redirect_uri.split redirect_uri.split
end end
def push_to_streaming_api def close_streaming_sessions(resource_owner = nil)
# TODO: #28793 Combine into a single topic # TODO: #28793 Combine into a single topic
payload = Oj.dump(event: :kill) payload = Oj.dump(event: :kill)
access_tokens.in_batches do |tokens| scope = access_tokens
scope = scope.where(resource_owner_id: resource_owner.id) unless resource_owner.nil?
scope.in_batches do |tokens|
redis.pipelined do |pipeline| redis.pipelined do |pipeline|
tokens.ids.each do |id| tokens.ids.each do |id|
pipeline.publish("timeline:access_token:#{id}", payload) pipeline.publish("timeline:access_token:#{id}", payload)

View file

@ -81,7 +81,7 @@ cs:
invite_request_text: Důvody založení invite_request_text: Důvody založení
invited_by: Pozván uživatelem invited_by: Pozván uživatelem
ip: IP adresa ip: IP adresa
joined: Uživatel založen joined: Uživatelem od
location: location:
all: Všechny all: Všechny
local: Místní local: Místní

View file

@ -135,6 +135,7 @@ en-GB:
media: Media attachments media: Media attachments
mutes: Mutes mutes: Mutes
notifications: Notifications notifications: Notifications
profile: Your Mastodon profile
push: Push notifications push: Push notifications
reports: Reports reports: Reports
search: Search search: Search
@ -165,6 +166,7 @@ en-GB:
admin:write:reports: perform moderation actions on reports admin:write:reports: perform moderation actions on reports
crypto: use end-to-end encryption crypto: use end-to-end encryption
follow: modify account relationships follow: modify account relationships
profile: read only your account's profile information
push: receive your push notifications push: receive your push notifications
read: read all your account's data read: read all your account's data
read:accounts: see accounts information read:accounts: see accounts information

View file

@ -285,6 +285,7 @@ en-GB:
update_custom_emoji_html: "%{name} updated emoji %{target}" update_custom_emoji_html: "%{name} updated emoji %{target}"
update_domain_block_html: "%{name} updated domain block for %{target}" update_domain_block_html: "%{name} updated domain block for %{target}"
update_ip_block_html: "%{name} changed rule for IP %{target}" update_ip_block_html: "%{name} changed rule for IP %{target}"
update_report_html: "%{name} updated report %{target}"
update_status_html: "%{name} updated post by %{target}" update_status_html: "%{name} updated post by %{target}"
update_user_role_html: "%{name} changed %{target} role" update_user_role_html: "%{name} changed %{target} role"
deleted_account: deleted account deleted_account: deleted account
@ -292,6 +293,7 @@ en-GB:
filter_by_action: Filter by action filter_by_action: Filter by action
filter_by_user: Filter by user filter_by_user: Filter by user
title: Audit log title: Audit log
unavailable_instance: "(domain name unavailable)"
announcements: announcements:
destroyed_msg: Announcement successfully deleted! destroyed_msg: Announcement successfully deleted!
edit: edit:
@ -950,6 +952,7 @@ en-GB:
delete: Delete delete: Delete
edit_preset: Edit warning preset edit_preset: Edit warning preset
empty: You haven't defined any warning presets yet. empty: You haven't defined any warning presets yet.
title: Warning presets
webhooks: webhooks:
add_new: Add endpoint add_new: Add endpoint
delete: Delete delete: Delete

View file

@ -574,7 +574,7 @@ ia:
enabled: Activate enabled: Activate
inbox_url: URL del repetitor inbox_url: URL del repetitor
pending: Attende le approbation del repetitor pending: Attende le approbation del repetitor
save_and_enable: Salveguardar e activar save_and_enable: Salvar e activar
setup: Crear un connexion con un repetitor setup: Crear un connexion con un repetitor
signatures_not_enabled: Le repetitores pote non functionar correctemente durante que le modo secur o le modo de federation limitate es activate signatures_not_enabled: Le repetitores pote non functionar correctemente durante que le modo secur o le modo de federation limitate es activate
status: Stato status: Stato
@ -1276,7 +1276,7 @@ ia:
other: "%{count} messages individual celate" other: "%{count} messages individual celate"
title: Filtros title: Filtros
new: new:
save: Salveguardar nove filtro save: Salvar nove filtro
title: Adder nove filtro title: Adder nove filtro
statuses: statuses:
back_to_filter: Retro al filtro back_to_filter: Retro al filtro
@ -1294,14 +1294,14 @@ ia:
one: "<strong>%{count}</strong> elemento correspondente al recerca es seligite." one: "<strong>%{count}</strong> elemento correspondente al recerca es seligite."
other: Tote le <strong>%{count}</strong> elementos correspondente al recerca es seligite. other: Tote le <strong>%{count}</strong> elementos correspondente al recerca es seligite.
cancel: Cancellar cancel: Cancellar
changes_saved_msg: Cambios salveguardate con successo! changes_saved_msg: Le cambiamentos ha essite salvate!
confirm: Confirmar confirm: Confirmar
copy: Copiar copy: Copiar
delete: Deler delete: Deler
deselect: Deseliger toto deselect: Deseliger toto
none: Necun none: Necun
order_by: Ordinar per order_by: Ordinar per
save_changes: Salvar le cambios save_changes: Salvar le cambiamentos
select_all_matching_items: select_all_matching_items:
one: Selige %{count} elemento correspondente a tu recerca. one: Selige %{count} elemento correspondente a tu recerca.
other: Selige %{count} elementos correspondente a tu recerca. other: Selige %{count} elementos correspondente a tu recerca.

View file

@ -59,7 +59,7 @@ cs:
setting_display_media_default: Skrývat média označená jako citlivá setting_display_media_default: Skrývat média označená jako citlivá
setting_display_media_hide_all: Vždy skrývat média setting_display_media_hide_all: Vždy skrývat média
setting_display_media_show_all: Vždy zobrazovat média setting_display_media_show_all: Vždy zobrazovat média
setting_use_blurhash: Gradienty jsou založeny na barvách skryté grafiky, ale zakrývají jakékoliv detaily setting_use_blurhash: Gradienty jsou vytvořeny na základě barvev skrytých médií, ale zakrývají veškeré detaily
setting_use_pending_items: Aktualizovat časovou osu až po kliknutí namísto automatického rolování kanálu setting_use_pending_items: Aktualizovat časovou osu až po kliknutí namísto automatického rolování kanálu
username: Pouze písmena, číslice a podtržítka username: Pouze písmena, číslice a podtržítka
whole_word: Je-li klíčové slovo či fráze pouze alfanumerická, bude aplikován pouze, pokud se shoduje s celým slovem whole_word: Je-li klíčové slovo či fráze pouze alfanumerická, bude aplikován pouze, pokud se shoduje s celým slovem

View file

@ -81,7 +81,7 @@ ja:
backups_retention_period: ユーザーには、後でダウンロードするために投稿のアーカイブを生成する機能があります。正の値に設定すると、これらのアーカイブは指定された日数後に自動的にストレージから削除されます。 backups_retention_period: ユーザーには、後でダウンロードするために投稿のアーカイブを生成する機能があります。正の値に設定すると、これらのアーカイブは指定された日数後に自動的にストレージから削除されます。
bootstrap_timeline_accounts: これらのアカウントは、新しいユーザー向けのおすすめユーザーの一番上にピン留めされます。 bootstrap_timeline_accounts: これらのアカウントは、新しいユーザー向けのおすすめユーザーの一番上にピン留めされます。
closed_registrations_message: アカウント作成を停止している時に表示されます closed_registrations_message: アカウント作成を停止している時に表示されます
content_cache_retention_period: 他のサーバーからのすべての投稿(ブーストや返信を含む)は、指定された日数が経過すると、ローカルユーザーとのやりとりに関係なく削除されます。これには、ローカルユーザーがブックマークやお気に入りとして登録した投稿も含まれます。異なるサーバーのユーザー間の非公開な変身も失われ、復元することは不可能です。この設定の使用は特別な目的のインスタンスのためのものであり、一般的な目的のサーバーで使用するした場合、多くのユーザーの期待を裏切ることになります。 content_cache_retention_period: 他のサーバーからのすべての投稿(ブーストや返信を含む)は、指定された日数が経過すると、ローカルユーザーとのやりとりに関係なく削除されます。これには、ローカルユーザーがブックマークやお気に入りとして登録した投稿も含まれます。異なるサーバーのユーザー間の非公開な返信も失われ、復元することは不可能です。この設定の使用は特別な目的のインスタンスのためのものであり、一般的な目的のサーバーで使用した場合、多くのユーザーの期待を裏切ることになります。
custom_css: ウェブ版のMastodonでカスタムスタイルを適用できます。 custom_css: ウェブ版のMastodonでカスタムスタイルを適用できます。
favicon: デフォルトのMastodonのブックマークアイコンを独自のアイコンで上書きします。WEBP、PNG、GIF、JPGが利用可能です。 favicon: デフォルトのMastodonのブックマークアイコンを独自のアイコンで上書きします。WEBP、PNG、GIF、JPGが利用可能です。
mascot: 上級者向けWebインターフェースのイラストを上書きします。 mascot: 上級者向けWebインターフェースのイラストを上書きします。

View file

@ -58,7 +58,7 @@ services:
web: web:
build: . build: .
image: ghcr.io/mastodon/mastodon:v4.2.9 image: ghcr.io/mastodon/mastodon:v4.2.10
restart: always restart: always
env_file: .env.production env_file: .env.production
command: bundle exec puma -C config/puma.rb command: bundle exec puma -C config/puma.rb
@ -79,7 +79,7 @@ services:
streaming: streaming:
build: . build: .
image: ghcr.io/mastodon/mastodon:v4.2.9 image: ghcr.io/mastodon/mastodon:v4.2.10
restart: always restart: always
env_file: .env.production env_file: .env.production
command: node ./streaming command: node ./streaming
@ -97,7 +97,7 @@ services:
sidekiq: sidekiq:
build: . build: .
image: ghcr.io/mastodon/mastodon:v4.2.9 image: ghcr.io/mastodon/mastodon:v4.2.10
restart: always restart: always
env_file: .env.production env_file: .env.production
command: bundle exec sidekiq command: bundle exec sidekiq

View file

@ -75,7 +75,7 @@ class Sanitize
end end
MASTODON_STRICT = freeze_config( MASTODON_STRICT = freeze_config(
elements: %w(p br span a abbr del pre blockquote code b strong u sub sup i em h1 h2 h3 h4 h5 ul ol li), elements: %w(p br span a abbr del pre blockquote code b strong u sub sup i em h1 h2 h3 h4 h5 ul ol li ruby rt rp),
attributes: { attributes: {
'a' => %w(href rel class title translate), 'a' => %w(href rel class title translate),

View file

@ -130,7 +130,7 @@
"webpack-assets-manifest": "^4.0.6", "webpack-assets-manifest": "^4.0.6",
"webpack-bundle-analyzer": "^4.8.0", "webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^3.3.12", "webpack-cli": "^3.3.12",
"webpack-merge": "^5.9.0", "webpack-merge": "^6.0.0",
"wicg-inert": "^3.1.2", "wicg-inert": "^3.1.2",
"workbox-expiration": "^7.0.0", "workbox-expiration": "^7.0.0",
"workbox-precaching": "^7.0.0", "workbox-precaching": "^7.0.0",

View file

@ -50,9 +50,11 @@ describe Oauth::AuthorizedApplicationsController do
let!(:application) { Fabricate(:application) } let!(:application) { Fabricate(:application) }
let!(:access_token) { Fabricate(:accessible_access_token, application: application, resource_owner_id: user.id) } let!(:access_token) { Fabricate(:accessible_access_token, application: application, resource_owner_id: user.id) }
let!(:web_push_subscription) { Fabricate(:web_push_subscription, user: user, access_token: access_token) } let!(:web_push_subscription) { Fabricate(:web_push_subscription, user: user, access_token: access_token) }
let(:redis_pipeline_stub) { instance_double(Redis::Namespace, publish: nil) }
before do before do
sign_in user, scope: :user sign_in user, scope: :user
allow(redis).to receive(:pipelined).and_yield(redis_pipeline_stub)
post :destroy, params: { id: application.id } post :destroy, params: { id: application.id }
end end
@ -67,5 +69,9 @@ describe Oauth::AuthorizedApplicationsController do
it 'removes the web_push_subscription' do it 'removes the web_push_subscription' do
expect { web_push_subscription.reload }.to raise_error(ActiveRecord::RecordNotFound) expect { web_push_subscription.reload }.to raise_error(ActiveRecord::RecordNotFound)
end end
it 'sends a session kill payload to the streaming server' do
expect(redis_pipeline_stub).to have_received(:publish).with("timeline:access_token:#{access_token.id}", '{"event":"kill"}')
end
end end
end end

View file

@ -147,14 +147,22 @@ describe Settings::ApplicationsController do
end end
describe 'destroy' do describe 'destroy' do
let(:redis_pipeline_stub) { instance_double(Redis::Namespace, publish: nil) }
let!(:access_token) { Fabricate(:accessible_access_token, application: app) }
before do before do
allow(redis).to receive(:pipelined).and_yield(redis_pipeline_stub)
post :destroy, params: { id: app.id } post :destroy, params: { id: app.id }
end end
it 'redirects back to applications page and removes the app' do it 'redirects back to applications page removes the app' do
expect(response).to redirect_to(settings_applications_path) expect(response).to redirect_to(settings_applications_path)
expect(Doorkeeper::Application.find_by(id: app.id)).to be_nil expect(Doorkeeper::Application.find_by(id: app.id)).to be_nil
end end
it 'sends a session kill payload to the streaming server' do
expect(redis_pipeline_stub).to have_received(:publish).with("timeline:access_token:#{access_token.id}", '{"event":"kill"}')
end
end end
describe 'regenerate' do describe 'regenerate' do

View file

@ -41,6 +41,14 @@ RSpec.describe HtmlAwareFormatter do
expect(subject).to_not include 'status__content__spoiler-link' expect(subject).to_not include 'status__content__spoiler-link'
end end
end end
context 'when given text containing ruby tags for east-asian languages' do
let(:text) { '<ruby>明日 <rp>(</rp><rt>Ashita</rt><rp>)</rp></ruby>' }
it 'keeps the ruby tags' do
expect(subject).to eq '<ruby>明日 <rp>(</rp><rt>Ashita</rt><rp>)</rp></ruby>'
end
end
end end
end end
end end

View file

@ -72,6 +72,14 @@ RSpec.describe PlainTextFormatter do
expect(subject).to eq 'Lorem ipsum' expect(subject).to eq 'Lorem ipsum'
end end
end end
context 'when text contains HTML ruby tags' do
let(:status) { Fabricate(:status, account: remote_account, text: '<p>Lorem <ruby>明日 <rp>(</rp><rt>Ashita</rt><rp>)</rp></ruby> ipsum</p>') }
it 'strips the comment' do
expect(subject).to eq 'Lorem 明日 (Ashita) ipsum'
end
end
end end
end end
end end

View file

@ -16,6 +16,10 @@ describe Sanitize::Config do
expect(Sanitize.fragment('<p>Check out:</p><ol start="3" reversed=""><li>Foo</li><li>Bar</li></ol>', subject)).to eq '<p>Check out:</p><ol start="3" reversed=""><li>Foo</li><li>Bar</li></ol>' expect(Sanitize.fragment('<p>Check out:</p><ol start="3" reversed=""><li>Foo</li><li>Bar</li></ol>', subject)).to eq '<p>Check out:</p><ol start="3" reversed=""><li>Foo</li><li>Bar</li></ol>'
end end
it 'keeps ruby tags' do
expect(Sanitize.fragment('<p><ruby>明日 <rp>(</rp><rt>Ashita</rt><rp>)</rp></ruby></p>', subject)).to eq '<p><ruby>明日 <rp>(</rp><rt>Ashita</rt><rp>)</rp></ruby></p>'
end
it 'removes a without href' do it 'removes a without href' do
expect(Sanitize.fragment('<a>Test</a>', subject)).to eq 'Test' expect(Sanitize.fragment('<a>Test</a>', subject)).to eq 'Test'
end end

View file

@ -25,6 +25,17 @@ describe 'Scheduled Statuses' do
it_behaves_like 'forbidden for wrong scope', 'write write:statuses' it_behaves_like 'forbidden for wrong scope', 'write write:statuses'
end end
context 'with an application token' do
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: 'read:statuses') }
it 'returns http unprocessable entity' do
get api_v1_scheduled_statuses_path, headers: headers
expect(response)
.to have_http_status(422)
end
end
context 'with correct scope' do context 'with correct scope' do
let(:scopes) { 'read:statuses' } let(:scopes) { 'read:statuses' }

View file

@ -8,6 +8,22 @@ describe 'API V1 Statuses Translations' do
let(:scopes) { 'read:statuses' } let(:scopes) { 'read:statuses' }
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
context 'with an application token' do
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: scopes) }
describe 'POST /api/v1/statuses/:status_id/translate' do
let(:status) { Fabricate(:status, account: user.account, text: 'Hola', language: 'es') }
before do
post "/api/v1/statuses/#{status.id}/translate", headers: headers
end
it 'returns http unprocessable entity' do
expect(response).to have_http_status(422)
end
end
end
context 'with an oauth token' do context 'with an oauth token' do
describe 'POST /api/v1/statuses/:status_id/translate' do describe 'POST /api/v1/statuses/:status_id/translate' do
let(:status) { Fabricate(:status, account: user.account, text: 'Hola', language: 'es') } let(:status) { Fabricate(:status, account: user.account, text: 'Hola', language: 'es') }

View file

@ -41,6 +41,8 @@ describe 'Link' do
end end
end end
it_behaves_like 'forbidden for wrong scope', 'profile'
context 'when there is no preview card' do context 'when there is no preview card' do
let(:preview_card) { nil } let(:preview_card) { nil }
@ -80,13 +82,25 @@ describe 'Link' do
Form::AdminSettings.new(timeline_preview: false).save Form::AdminSettings.new(timeline_preview: false).save
end end
context 'when the user is not authenticated' do it_behaves_like 'forbidden for wrong scope', 'profile'
context 'without an authentication token' do
let(:headers) { {} } let(:headers) { {} }
it 'returns http unauthorized' do it 'returns http unprocessable entity' do
subject subject
expect(response).to have_http_status(401) expect(response).to have_http_status(422)
end
end
context 'with an application access token, not bound to a user' do
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: scopes) }
it 'returns http unprocessable entity' do
subject
expect(response).to have_http_status(422)
end end
end end

View file

@ -38,6 +38,8 @@ describe 'Public' do
Setting.timeline_preview = true Setting.timeline_preview = true
end end
it_behaves_like 'forbidden for wrong scope', 'profile'
context 'with an authorized user' do context 'with an authorized user' do
it_behaves_like 'a successful request to the public timeline' it_behaves_like 'a successful request to the public timeline'
end end
@ -103,13 +105,9 @@ describe 'Public' do
Form::AdminSettings.new(timeline_preview: false).save Form::AdminSettings.new(timeline_preview: false).save
end end
context 'with an authenticated user' do it_behaves_like 'forbidden for wrong scope', 'profile'
let(:expected_statuses) { [local_status, remote_status, media_status] }
it_behaves_like 'a successful request to the public timeline' context 'without an authentication token' do
end
context 'with an unauthenticated user' do
let(:headers) { {} } let(:headers) { {} }
it 'returns http unprocessable entity' do it 'returns http unprocessable entity' do
@ -118,6 +116,22 @@ describe 'Public' do
expect(response).to have_http_status(422) expect(response).to have_http_status(422)
end end
end end
context 'with an application access token, not bound to a user' do
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: nil, scopes: scopes) }
it 'returns http unprocessable entity' do
subject
expect(response).to have_http_status(422)
end
end
context 'with an authenticated user' do
let(:expected_statuses) { [local_status, remote_status, media_status] }
it_behaves_like 'a successful request to the public timeline'
end
end end
end end
end end

View file

@ -34,6 +34,8 @@ RSpec.describe 'Tag' do
let(:params) { {} } let(:params) { {} }
let(:hashtag) { 'life' } let(:hashtag) { 'life' }
it_behaves_like 'forbidden for wrong scope', 'profile'
context 'when given only one hashtag' do context 'when given only one hashtag' do
let(:expected_statuses) { [life_status] } let(:expected_statuses) { [life_status] }
@ -97,13 +99,15 @@ RSpec.describe 'Tag' do
Form::AdminSettings.new(timeline_preview: false).save Form::AdminSettings.new(timeline_preview: false).save
end end
context 'when the user is not authenticated' do it_behaves_like 'forbidden for wrong scope', 'profile'
context 'without an authentication token' do
let(:headers) { {} } let(:headers) { {} }
it 'returns http unauthorized' do it 'returns http unprocessable entity' do
subject subject
expect(response).to have_http_status(401) expect(response).to have_http_status(422)
end end
end end

View file

@ -2904,7 +2904,7 @@ __metadata:
webpack-bundle-analyzer: "npm:^4.8.0" webpack-bundle-analyzer: "npm:^4.8.0"
webpack-cli: "npm:^3.3.12" webpack-cli: "npm:^3.3.12"
webpack-dev-server: "npm:^3.11.3" webpack-dev-server: "npm:^3.11.3"
webpack-merge: "npm:^5.9.0" webpack-merge: "npm:^6.0.0"
wicg-inert: "npm:^3.1.2" wicg-inert: "npm:^3.1.2"
workbox-expiration: "npm:^7.0.0" workbox-expiration: "npm:^7.0.0"
workbox-precaching: "npm:^7.0.0" workbox-precaching: "npm:^7.0.0"
@ -13163,14 +13163,14 @@ __metadata:
linkType: hard linkType: hard
"pino-http@npm:^10.0.0": "pino-http@npm:^10.0.0":
version: 10.1.0 version: 10.2.0
resolution: "pino-http@npm:10.1.0" resolution: "pino-http@npm:10.2.0"
dependencies: dependencies:
get-caller-file: "npm:^2.0.5" get-caller-file: "npm:^2.0.5"
pino: "npm:^9.0.0" pino: "npm:^9.0.0"
pino-std-serializers: "npm:^7.0.0" pino-std-serializers: "npm:^7.0.0"
process-warning: "npm:^3.0.0" process-warning: "npm:^3.0.0"
checksum: 10c0/d97691f2ee248b0aca0e49169d0c7ca0d4c604ee57b63ae264a6f9914fc7277cace74686d5088a876f8152a8d5b8211af904b2d24a516728a662de0e9cc79e9f checksum: 10c0/0b79cd3602531ee5043693e2a3ccf9d955bd93759e80c0b3a458b95b241f36ca8ebc72c8050b395e9d8fcb9581ebc18ecd6b7dc136526bebe924bc5c5079374d
languageName: node languageName: node
linkType: hard linkType: hard
@ -17952,14 +17952,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"webpack-merge@npm:^5.9.0": "webpack-merge@npm:^6.0.0":
version: 5.10.0 version: 6.0.1
resolution: "webpack-merge@npm:5.10.0" resolution: "webpack-merge@npm:6.0.1"
dependencies: dependencies:
clone-deep: "npm:^4.0.1" clone-deep: "npm:^4.0.1"
flat: "npm:^5.0.2" flat: "npm:^5.0.2"
wildcard: "npm:^2.0.0" wildcard: "npm:^2.0.1"
checksum: 10c0/b607c84cabaf74689f965420051a55a08722d897bdd6c29cb0b2263b451c090f962d41ecf8c9bf56b0ab3de56e65476ace0a8ecda4f4a4663684243d90e0512b checksum: 10c0/bf1429567858b353641801b8a2696ca0aac270fc8c55d4de8a7b586fe07d27fdcfc83099a98ab47e6162383db8dd63bb8cc25b1beb2ec82150422eec843b0dc0
languageName: node languageName: node
linkType: hard linkType: hard
@ -18207,7 +18207,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"wildcard@npm:^2.0.0": "wildcard@npm:^2.0.1":
version: 2.0.1 version: 2.0.1
resolution: "wildcard@npm:2.0.1" resolution: "wildcard@npm:2.0.1"
checksum: 10c0/08f70cd97dd9a20aea280847a1fe8148e17cae7d231640e41eb26d2388697cbe65b67fd9e68715251c39b080c5ae4f76d71a9a69fa101d897273efdfb1b58bf7 checksum: 10c0/08f70cd97dd9a20aea280847a1fe8148e17cae7d231640e41eb26d2388697cbe65b67fd9e68715251c39b080c5ae4f76d71a9a69fa101d897273efdfb1b58bf7
@ -18515,8 +18515,8 @@ __metadata:
linkType: hard linkType: hard
"ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.17.0": "ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.17.0":
version: 8.17.1 version: 8.18.0
resolution: "ws@npm:8.17.1" resolution: "ws@npm:8.18.0"
peerDependencies: peerDependencies:
bufferutil: ^4.0.1 bufferutil: ^4.0.1
utf-8-validate: ">=5.0.2" utf-8-validate: ">=5.0.2"
@ -18525,7 +18525,7 @@ __metadata:
optional: true optional: true
utf-8-validate: utf-8-validate:
optional: true optional: true
checksum: 10c0/f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe checksum: 10c0/25eb33aff17edcb90721ed6b0eb250976328533ad3cd1a28a274bd263682e7296a6591ff1436d6cbc50fa67463158b062f9d1122013b361cec99a05f84680e06
languageName: node languageName: node
linkType: hard linkType: hard