From 03a0f7caf99201711ade091e1d570bde04478782 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 09:55:34 +0200 Subject: [PATCH 1/9] chore(deps): update dependency selenium-webdriver to v4.32.0 (#34604) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8f5d3b021c..4ed32b68e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -800,7 +800,7 @@ GEM activerecord (>= 4.0.0) railties (>= 4.0.0) securerandom (0.4.1) - selenium-webdriver (4.31.0) + selenium-webdriver (4.32.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) From d41a741e00fb32ae3e571ee8bc79e078f3b0ec4f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 09:55:52 +0200 Subject: [PATCH 2/9] fix(deps): update dependency ws to v8.18.2 (#34603) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 530c93fcb1..371d7339ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18945,8 +18945,8 @@ __metadata: linkType: hard "ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.18.0": - version: 8.18.1 - resolution: "ws@npm:8.18.1" + version: 8.18.2 + resolution: "ws@npm:8.18.2" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -18955,7 +18955,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10c0/e498965d6938c63058c4310ffb6967f07d4fa06789d3364829028af380d299fe05762961742971c764973dce3d1f6a2633fe8b2d9410c9b52e534b4b882a99fa + checksum: 10c0/4b50f67931b8c6943c893f59c524f0e4905bbd183016cfb0f2b8653aa7f28dad4e456b9d99d285bbb67cca4fedd9ce90dfdfaa82b898a11414ebd66ee99141e4 languageName: node linkType: hard From cbaba54e9d398de16dab265485bc0fedb7390500 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 5 May 2025 10:01:16 +0200 Subject: [PATCH 3/9] Add support for importing embedded self-quotes (#34584) --- app/helpers/json_ld_helper.rb | 12 +++++++ app/lib/activitypub/activity/create.rb | 4 ++- app/lib/activitypub/parser/status_parser.rb | 5 +++ .../process_status_update_service.rb | 19 ++++++----- .../activitypub/verify_quote_service.rb | 10 +++--- .../activitypub/verify_quote_service_spec.rb | 33 ++++++++++++++++++- 6 files changed, 67 insertions(+), 16 deletions(-) diff --git a/app/helpers/json_ld_helper.rb b/app/helpers/json_ld_helper.rb index 65daaa5302..212894d0cd 100644 --- a/app/helpers/json_ld_helper.rb +++ b/app/helpers/json_ld_helper.rb @@ -72,6 +72,18 @@ module JsonLdHelper !haystack.casecmp(needle).zero? end + def safe_prefetched_embed(account, object, context) + return unless object.is_a?(Hash) + + # NOTE: Replacing the object's context by that of the parent activity is + # not sound, but it's consistent with the rest of the codebase + object = object.merge({ '@context' => context }) + + return if value_or_id(first_of_value(object['attributedTo'])) != account.uri || non_matching_uri_hosts?(account.uri, object['id']) + + object + end + def canonicalize(json) graph = RDF::Graph.new << JSON::LD::API.toRdf(json, documentLoader: method(:load_jsonld_context)) graph.dump(:normalize) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 1710fc80b4..06bc940949 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -204,7 +204,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity @quote.status = status @quote.save - ActivityPub::VerifyQuoteService.new.call(@quote, fetchable_quoted_uri: @quote_uri, request_id: @options[:request_id]) + + embedded_quote = safe_prefetched_embed(@account, @status_parser.quoted_object, @json['context']) + ActivityPub::VerifyQuoteService.new.call(@quote, fetchable_quoted_uri: @quote_uri, prefetched_quoted_object: embedded_quote, request_id: @options[:request_id]) rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS ActivityPub::RefetchAndVerifyQuoteWorker.perform_in(rand(30..600).seconds, @quote.id, @quote_uri, { 'request_id' => @options[:request_id] }) end diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index cc2a6e0ca5..db64461fa9 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -120,6 +120,11 @@ class ActivityPub::Parser::StatusParser end.first end + # The inlined quote; out of the attributes we support, only `https://w3id.org/fep/044f#quote` explicitly supports inlined objects + def quoted_object + as_array(@object['quote']).first + end + def quote_approval_uri as_array(@object['quoteAuthorization']).first end diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index e02cc0914b..aceb17f2d1 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -273,7 +273,6 @@ class ActivityPub::ProcessStatusUpdateService < BaseService def update_quote! return unless Mastodon::Feature.inbound_quotes_enabled? - quote = nil quote_uri = @status_parser.quote_uri if quote_uri.present? @@ -294,21 +293,23 @@ class ActivityPub::ProcessStatusUpdateService < BaseService quote = Quote.create(status: @status, approval_uri: approval_uri) @quote_changed = true end - end - if quote.present? - begin - quote.save - ActivityPub::VerifyQuoteService.new.call(quote, fetchable_quoted_uri: quote_uri, request_id: @request_id) - rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS - ActivityPub::RefetchAndVerifyQuoteWorker.perform_in(rand(30..600).seconds, quote.id, quote_uri, { 'request_id' => @request_id }) - end + quote.save + + fetch_and_verify_quote!(quote, quote_uri) elsif @status.quote.present? @status.quote.destroy! @quote_changed = true end end + def fetch_and_verify_quote!(quote, quote_uri) + embedded_quote = safe_prefetched_embed(@account, @status_parser.quoted_object, @activity_json['context']) + ActivityPub::VerifyQuoteService.new.call(quote, fetchable_quoted_uri: quote_uri, prefetched_quoted_object: embedded_quote, request_id: @request_id) + rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS + ActivityPub::RefetchAndVerifyQuoteWorker.perform_in(rand(30..600).seconds, quote.id, quote_uri, { 'request_id' => @request_id }) + end + def update_counts! likes = @status_parser.favourites_count shares = @status_parser.reblogs_count diff --git a/app/services/activitypub/verify_quote_service.rb b/app/services/activitypub/verify_quote_service.rb index 0803d62d3a..ad4dfbe310 100644 --- a/app/services/activitypub/verify_quote_service.rb +++ b/app/services/activitypub/verify_quote_service.rb @@ -4,15 +4,15 @@ class ActivityPub::VerifyQuoteService < BaseService include JsonLdHelper # Optionally fetch quoted post, and verify the quote is authorized - def call(quote, fetchable_quoted_uri: nil, prefetched_body: nil, request_id: nil) + def call(quote, fetchable_quoted_uri: nil, prefetched_quoted_object: nil, prefetched_approval: nil, request_id: nil) @request_id = request_id @quote = quote @fetching_error = nil - fetch_quoted_post_if_needed!(fetchable_quoted_uri) + fetch_quoted_post_if_needed!(fetchable_quoted_uri, prefetched_body: prefetched_quoted_object) return if fast_track_approval! || quote.approval_uri.blank? - @json = fetch_approval_object(quote.approval_uri, prefetched_body:) + @json = fetch_approval_object(quote.approval_uri, prefetched_body: prefetched_approval) return quote.reject! if @json.nil? return if non_matching_uri_hosts?(quote.approval_uri, value_or_id(@json['attributedTo'])) @@ -68,11 +68,11 @@ class ActivityPub::VerifyQuoteService < BaseService ActivityPub::TagManager.instance.uri_for(@quote.status) == value_or_id(@json['interactingObject']) end - def fetch_quoted_post_if_needed!(uri) + def fetch_quoted_post_if_needed!(uri, prefetched_body: nil) return if uri.nil? || @quote.quoted_status.present? status = ActivityPub::TagManager.instance.uri_to_resource(uri, Status) - status ||= ActivityPub::FetchRemoteStatusService.new.call(uri, on_behalf_of: @quote.account.followers.local.first, request_id: @request_id) + status ||= ActivityPub::FetchRemoteStatusService.new.call(uri, on_behalf_of: @quote.account.followers.local.first, prefetched_body:, request_id: @request_id) @quote.update(quoted_status: status) if status.present? rescue Mastodon::UnexpectedResponseError, *Mastodon::HTTP_CONNECTION_ERRORS => e diff --git a/spec/services/activitypub/verify_quote_service_spec.rb b/spec/services/activitypub/verify_quote_service_spec.rb index 0e5069a46b..ae4ffae9bb 100644 --- a/spec/services/activitypub/verify_quote_service_spec.rb +++ b/spec/services/activitypub/verify_quote_service_spec.rb @@ -89,6 +89,37 @@ RSpec.describe ActivityPub::VerifyQuoteService do end end + context 'with a valid activity for a post that cannot be fetched but is passed as fetched_quoted_object' do + let(:quoted_status) { nil } + + let(:approval_interaction_target) { 'https://b.example.com/unknown-quoted' } + let(:prefetched_object) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + type: 'Note', + id: 'https://b.example.com/unknown-quoted', + to: 'https://www.w3.org/ns/activitystreams#Public', + attributedTo: ActivityPub::TagManager.instance.uri_for(quoted_account), + content: 'previously unknown post', + }.with_indifferent_access + end + + before do + stub_request(:get, 'https://b.example.com/unknown-quoted') + .to_return(status: 404) + end + + it 'updates the status' do + expect { subject.call(quote, fetchable_quoted_uri: 'https://b.example.com/unknown-quoted', prefetched_quoted_object: prefetched_object) } + .to change(quote, :state).to('accepted') + + expect(a_request(:get, approval_uri)) + .to have_been_made.once + + expect(quote.reload.quoted_status.content).to eq 'previously unknown post' + end + end + context 'with a valid activity for a post that cannot be fetched but is inlined' do let(:quoted_status) { nil } @@ -148,7 +179,7 @@ RSpec.describe ActivityPub::VerifyQuoteService do context 'with a valid activity for already-fetched posts, with a pre-fetched approval' do it 'updates the status without fetching the activity' do - expect { subject.call(quote, prefetched_body: Oj.dump(json)) } + expect { subject.call(quote, prefetched_approval: Oj.dump(json)) } .to change(quote, :state).to('accepted') expect(a_request(:get, approval_uri)) From 84bca6fd5409c27ebfee0dcc1376dd9497ca5702 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 10:23:21 +0200 Subject: [PATCH 4/9] chore(deps): update dependency public_suffix to v6.0.2 (#34590) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4ed32b68e2..573ad8e355 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -620,7 +620,7 @@ GEM psych (5.2.3) date stringio - public_suffix (6.0.1) + public_suffix (6.0.2) puma (6.6.0) nio4r (~> 2.0) pundit (2.5.0) From eacf6f2342154a935604fbb420c6ae3c6ecae1eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 10:23:27 +0200 Subject: [PATCH 5/9] New Crowdin Translations (automated) (#34596) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/lt.json | 8 +++ app/javascript/mastodon/locales/sk.json | 4 ++ config/locales/nan.yml | 65 +++++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 3bacf65765..387fd99be6 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -19,14 +19,17 @@ "account.block_domain": "Blokuoti serverį {domain}", "account.block_short": "Blokuoti", "account.blocked": "Užblokuota", + "account.blocking": "Blokavimas", "account.cancel_follow_request": "Atšaukti sekimą", "account.copy": "Kopijuoti nuorodą į profilį", "account.direct": "Privačiai paminėti @{name}", "account.disable_notifications": "Nustoti man pranešti, kai @{name} paskelbia", + "account.domain_blocking": "Blokuoti domeną", "account.edit_profile": "Redaguoti profilį", "account.enable_notifications": "Pranešti man, kai @{name} paskelbia", "account.endorse": "Rodyti profilyje", "account.featured": "Rodomi", + "account.featured.accounts": "Profiliai", "account.featured.hashtags": "Saitažodžiai", "account.featured.posts": "Įrašai", "account.featured_tags.last_status_at": "Paskutinis įrašas {date}", @@ -39,6 +42,7 @@ "account.following": "Sekama", "account.following_counter": "{count, plural, one {{counter} sekimas} few {{counter} sekimai} many {{counter} sekimo} other {{counter} sekimų}}", "account.follows.empty": "Šis naudotojas dar nieko neseka.", + "account.follows_you": "Seka tave", "account.go_to_profile": "Eiti į profilį", "account.hide_reblogs": "Slėpti pasidalinimus iš @{name}", "account.in_memoriam": "Atminimui.", @@ -53,6 +57,8 @@ "account.mute_notifications_short": "Nutildyti pranešimus", "account.mute_short": "Nutildyti", "account.muted": "Nutildytas", + "account.muting": "Užtildymas", + "account.mutual": "Jūs sekate vienas kitą", "account.no_bio": "Nėra pateikto aprašymo.", "account.open_original_page": "Atidaryti originalų puslapį", "account.posts": "Įrašai", @@ -61,6 +67,7 @@ "account.report": "Pranešti apie @{name}", "account.requested": "Laukiama patvirtinimo. Spustelėk, kad atšauktum sekimo prašymą", "account.requested_follow": "{name} paprašė tave sekti", + "account.requests_to_follow_you": "Prašymai sekti jus", "account.share": "Bendrinti @{name} profilį", "account.show_reblogs": "Rodyti pasidalinimus iš @{name}", "account.statuses_counter": "{count, plural, one {{counter} įrašas} few {{counter} įrašai} many {{counter} įrašo} other {{counter} įrašų}}", @@ -255,6 +262,7 @@ "disabled_account_banner.text": "Tavo paskyra {disabledAccount} šiuo metu išjungta.", "dismissable_banner.community_timeline": "Tai – naujausi vieši įrašai iš žmonių, kurių paskyros talpinamos {domain}.", "dismissable_banner.dismiss": "Atmesti", + "dismissable_banner.explore_links": "Šiomis naujienų istorijomis šiandien \"Fediverse\" dalijamasi dažniausiai. Naujesnės istorijos, kurias paskelbė daugiau skirtingų žmonių, užima aukštesnę vietą.", "domain_block_modal.block": "Blokuoti serverį", "domain_block_modal.block_account_instead": "Blokuoti @{name} vietoj to", "domain_block_modal.they_can_interact_with_old_posts": "Žmonės iš šio serverio gali bendrauti su tavo senomis įrašomis.", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 354b2da9bd..846b51667d 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -26,6 +26,8 @@ "account.edit_profile": "Upraviť profil", "account.enable_notifications": "Zapnúť upozornenia na príspevky od @{name}", "account.endorse": "Zobraziť na vlastnom profile", + "account.featured.accounts": "Profily", + "account.featured.hashtags": "Hashtagy", "account.featured.posts": "Príspevky", "account.featured_tags.last_status_at": "Posledný príspevok dňa {date}", "account.featured_tags.last_status_never": "Žiadne príspevky", @@ -37,6 +39,7 @@ "account.following": "Sledovaný účet", "account.following_counter": "{count, plural, one {{counter} sledovaných} other {{counter} sledovaných}}", "account.follows.empty": "Tento účet ešte nikoho nesleduje.", + "account.follows_you": "Nasleduje ťa", "account.go_to_profile": "Prejsť na profil", "account.hide_reblogs": "Skryť zdieľania od @{name}", "account.in_memoriam": "In memoriam.", @@ -208,6 +211,7 @@ "confirmations.redraft.confirm": "Vymazať a prepísať", "confirmations.redraft.message": "Určite chcete tento príspevok vymazať a prepísať? Prídete o jeho zdieľania a ohviezdičkovania a odpovede na pôvodný príspevok budú odlúčené.", "confirmations.redraft.title": "Vymazať a prepísať príspevok?", + "confirmations.remove_from_followers.confirm": "Odstrániť nasledovateľa", "confirmations.reply.confirm": "Odpovedať", "confirmations.reply.message": "Odpovedaním akurát teraz prepíšeš správu, ktorú máš práve rozpísanú. Si si istý/á, že chceš pokračovať?", "confirmations.reply.title": "Prepísať príspevok?", diff --git a/config/locales/nan.yml b/config/locales/nan.yml index 5ffc7b649b..674e3c90da 100644 --- a/config/locales/nan.yml +++ b/config/locales/nan.yml @@ -36,6 +36,25 @@ nan: approved_msg: 成功審核 %{username} ê註冊申請ah are_you_sure: Lí kám確定? avatar: 標頭 + by_domain: 域名 + change_email: + changed_msg: Email改成功ah! + current_email: 現在ê email + label: 改email + new_email: 新ê email + submit: 改email + title: 替 %{username} 改email + change_role: + changed_msg: 角色改成功ah! + edit_roles: 管理用者ê角色 + label: 改角色 + no_role: 無角色 + title: 替 %{username} 改角色 + confirm: 確認 + confirmed: 確認ah + confirming: Teh確認 + custom: 自訂 + delete: Thâi資料 deleted: Thâi掉ah demote: 降級 destroyed_msg: Teh-beh thâi掉 %{username} ê資料 @@ -49,15 +68,61 @@ nan: email: 電子phue箱 email_status: 電子phue ê狀態 enable: 取消冷凍 + enable_sign_in_token_auth: 啟用電子phue ê token認證 + enabled: 啟用ah + enabled_msg: 成功kā %{username} ê口座退冰 + followers: 跟tuè lí ê + follows: Lí跟tuè ê + header: 封面ê圖 + inbox_url: 收件kheh-á ê URL + invite_request_text: 加入ê理由 + invited_by: 邀請ê lâng + ip: IP + joined: 加入ê時 location: all: Kui ê local: 本地 remote: 別ê站 title: 位置 + login_status: 登入ê狀態 + media_attachments: 媒體ê附件 + memorialize: 變做故人ê口座 + memorialized: 變做故人ê口座ah + memorialized_msg: 成功kā %{username} 變做故人ê口座ah + moderation: + active: 活ê + all: 全部 + disabled: 停止使用ah + pending: Teh審核 + silenced: 受限制 + suspended: 權限中止ah + title: 管理 + moderation_notes: 管理ê註釋 + most_recent_activity: 最近ê活動時間 + most_recent_ip: 最近ê IP + no_account_selected: 因為無揀任何口座,所以lóng無改變 + no_limits_imposed: 無受著限制 + no_role_assigned: 無分著角色 + not_subscribed: 無訂 + pending: Teh等審核 + perform_full_suspension: 中止權限 + previous_strikes: Khah早ê處份 remove_avatar: Thâi掉標頭 removed_avatar_msg: 成功thâi掉 %{username} ê 標頭影像 + username: 用者ê名 + view_domain: 看域名ê摘要 + warn: 警告 + web: 網頁 + whitelisted: 允准佇聯邦傳資料 action_logs: action_types: + approve_appeal: 批准投訴 + approve_user: 批准用者 + assigned_to_self_report: 分配檢舉 + change_email_user: 替用者改email + change_role_user: 改用者ê角色 + confirm_user: 確認用者 + create_account_warning: 建立警告 remove_avatar_user: Thâi掉標頭 actions: remove_avatar_user_html: "%{name} thâi掉 %{target} ê標頭" From 833ea0725db3075005feaf4f9a1d22b2c70ba075 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 08:26:07 +0000 Subject: [PATCH 6/9] chore(deps): update dependency rubocop to v1.75.5 (#34608) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 573ad8e355..1df8c3ed3d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -743,7 +743,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 9) rspec-support (3.13.3) - rubocop (1.75.4) + rubocop (1.75.5) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) From 2133f2b47e407dab3305a3c645751eecd9e141ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 10:26:12 +0200 Subject: [PATCH 7/9] fix(deps): update dependency babel-plugin-formatjs to v10.5.38 (#34609) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 371d7339ef..2aa8bd3ca5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5487,8 +5487,8 @@ __metadata: linkType: hard "babel-plugin-formatjs@npm:^10.5.37": - version: 10.5.37 - resolution: "babel-plugin-formatjs@npm:10.5.37" + version: 10.5.38 + resolution: "babel-plugin-formatjs@npm:10.5.38" dependencies: "@babel/core": "npm:^7.26.10" "@babel/helper-plugin-utils": "npm:^7.26.5" @@ -5501,7 +5501,7 @@ __metadata: "@types/babel__helper-plugin-utils": "npm:^7.10.3" "@types/babel__traverse": "npm:^7.20.6" tslib: "npm:^2.8.0" - checksum: 10c0/e206ff1a8ad3cbcb3db2d2735d8821701df9d54c8aeb5e8b2861c945af91d4662b9cd37b1ff9d7e17954cdd31aec81788a3d044a1cd9f3e7e8e4f93177097b83 + checksum: 10c0/5aeb9839ee5be198b82c9ab6c85160e7edcc07f6184efe296560d229d1cc680d9c1e507bde47da74234d612a3e49c919b3e11c855b7fd4e6d256ec23f8b8b1e0 languageName: node linkType: hard From 89cafb01b47bee18db62da36a372a49d93b4a909 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 5 May 2025 14:33:31 +0200 Subject: [PATCH 8/9] Remove double-query for signed query strings (#34610) --- app/lib/http_signature_draft.rb | 5 ++--- app/lib/request.rb | 3 +-- app/services/activitypub/fetch_replies_service.rb | 15 +-------------- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/app/lib/http_signature_draft.rb b/app/lib/http_signature_draft.rb index fc0d498b29..cb794b223a 100644 --- a/app/lib/http_signature_draft.rb +++ b/app/lib/http_signature_draft.rb @@ -6,14 +6,13 @@ class HttpSignatureDraft REQUEST_TARGET = '(request-target)' - def initialize(keypair, key_id, full_path: true) + def initialize(keypair, key_id) @keypair = keypair @key_id = key_id - @full_path = full_path end def request_target(verb, url) - if url.query.nil? || !@full_path + if url.query.nil? "#{verb} #{url.path}" else "#{verb} #{url.path}?#{url.query}" diff --git a/app/lib/request.rb b/app/lib/request.rb index ad39f928db..212acf64d0 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -75,7 +75,6 @@ class Request @url = Addressable::URI.parse(url).normalize @http_client = options.delete(:http_client) @allow_local = options.delete(:allow_local) - @full_path = !options.delete(:omit_query_string) @options = { follow: { max_hops: 3, @@ -102,7 +101,7 @@ class Request key_id = ActivityPub::TagManager.instance.key_uri_for(actor) keypair = sign_with.present? ? OpenSSL::PKey::RSA.new(sign_with) : actor.keypair - @signing = HttpSignatureDraft.new(keypair, key_id, full_path: @full_path) + @signing = HttpSignatureDraft.new(keypair, key_id) self end diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb index f2e4f45104..6a6d9e391a 100644 --- a/app/services/activitypub/fetch_replies_service.rb +++ b/app/services/activitypub/fetch_replies_service.rb @@ -57,20 +57,7 @@ class ActivityPub::FetchRepliesService < BaseService return unless @allow_synchronous_requests return if non_matching_uri_hosts?(@reference_uri, collection_or_uri) - # NOTE: For backward compatibility reasons, Mastodon signs outgoing - # queries incorrectly by default. - # - # While this is relevant for all URLs with query strings, this is - # the only code path where this happens in practice. - # - # Therefore, retry with correct signatures if this fails. - begin - fetch_resource_without_id_validation(collection_or_uri, nil, raise_on_error: :temporary) - rescue Mastodon::UnexpectedResponseError => e - raise unless e.response && e.response.code == 401 && Addressable::URI.parse(collection_or_uri).query.present? - - fetch_resource_without_id_validation(collection_or_uri, nil, raise_on_error: :temporary, request_options: { omit_query_string: false }) - end + fetch_resource_without_id_validation(collection_or_uri, nil, raise_on_error: :temporary) end def filter_replies(items) From aedc5f692144aa36245fe47c277bb5ad4766a335 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 5 May 2025 15:01:16 +0200 Subject: [PATCH 9/9] Add warning for REDIS_NAMESPACE deprecation at startup (#34581) --- config/initializers/deprecations.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 config/initializers/deprecations.rb diff --git a/config/initializers/deprecations.rb b/config/initializers/deprecations.rb new file mode 100644 index 0000000000..e0ad54d8c3 --- /dev/null +++ b/config/initializers/deprecations.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +if ENV['REDIS_NAMESPACE'] + es_configured = ENV['ES_ENABLED'] == 'true' || ENV.fetch('ES_HOST', 'localhost') != 'localhost' || ENV.fetch('ES_PORT', '9200') != '9200' || ENV.fetch('ES_PASS', 'password') != 'password' + + warn <<~MESSAGE + WARNING: the REDIS_NAMESPACE environment variable is deprecated and will be removed in Mastodon 4.4.0. + + Please see documentation at https://github.com/mastodon/redis_namespace_migration + MESSAGE + + warn <<~MESSAGE if es_configured && !ENV['ES_PREFIX'] + + In addition, as REDIS_NAMESPACE is being used as a prefix for Elasticsearch, please do not forget to set ES_PREFIX to "#{ENV.fetch('REDIS_NAMESPACE')}". + MESSAGE +end