From ccf3ed0ddf8811d212dd3f94f177eb54471ed609 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:02:07 +0100 Subject: [PATCH 1/9] Update Node.js to 24.13 (#37473) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index b0195acf78..12fd1fc277 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.12 +24.13 From 2f91d9755d77fbe5902593ac49da1a3665e7b3a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:02:11 +0100 Subject: [PATCH 2/9] New Crowdin Translations (automated) (#37482) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/gd.json | 51 ++++++++++++++++++++++++- config/locales/activerecord.gd.yml | 6 +++ config/locales/gd.yml | 22 +++++++++++ config/locales/simple_form.gd.yml | 7 ++++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 2f4cb44de8..e48c60ff2c 100644 --- a/app/javascript/mastodon/locales/gd.json +++ b/app/javascript/mastodon/locales/gd.json @@ -113,11 +113,52 @@ "alt_text_modal.describe_for_people_with_visual_impairments": "Mìnich seo dhan fheadhainn air a bheil cion-lèirsinne…", "alt_text_modal.done": "Deiseil", "announcement.announcement": "Brath-fios", + "annual_report.announcement.action_build": "Cruthaich Wrapstodon dhomh", + "annual_report.announcement.action_dismiss": "Na cruthaich", + "annual_report.announcement.action_view": "Seall an Wrapstodon agam", + "annual_report.announcement.description": "Fidir mar a chaidh leat air Mastodon am bliadhna.", + "annual_report.announcement.title": "Tha Wrapstodon {year} air a thighinn", + "annual_report.nav_item.badge": "Ùr", + "annual_report.shared_page.donate": "Thoir tabhartas", + "annual_report.shared_page.footer": "Chaidh a ghintinn le {heart} le sgioba Mhastodon", + "annual_report.shared_page.footer_server_info": "Tha {username} a’ cleachdadh {domain}, sin fear de dh’iomadh coimhearsnachd le cumhachd Mastodon.", + "annual_report.summary.archetype.booster.desc_public": "Bhiodh {name} an toir air postaichean rim brosnachadh, a’ toirt taic do chruthadairean gu sgiobalta.", + "annual_report.summary.archetype.booster.desc_self": "Bhiodh tu an toir air postaichean rim brosnachadh, a’ toirt taic do chruthadairean gu sgiobalta.", + "annual_report.summary.archetype.booster.name": "Am Boghadair", + "annual_report.summary.archetype.die_drei_fragezeichen": "???", + "annual_report.summary.archetype.lurker.desc_public": "Tha fios againn gun robh {name} ann am badeigin, a’ gabhail tlachd à Mastodon air an dòigh fhèin.", + "annual_report.summary.archetype.lurker.desc_self": "Tha fios againn gun robh thu ann am badeigin, a’ gabhail tlachd à Mastodon air do dhòigh fhèin.", + "annual_report.summary.archetype.lurker.name": "An Socaireach", + "annual_report.summary.archetype.oracle.desc_public": "Chruthaich {name} barrachd phostaichean ùra na freagairtean, a’ cumail Mastodon ùr ’s beòthail.", + "annual_report.summary.archetype.oracle.desc_self": "Chruthaich thu barrachd phostaichean ùra na freagairtean, a’ cumail Mastodon ùr ’s beòthail.", + "annual_report.summary.archetype.oracle.name": "Coinneach Odhar", + "annual_report.summary.archetype.pollster.desc_public": "Chruthaich {name} barrachd chunntasan-beachd na seòrsaichean eile de phost, a’ cur ris an iongantas air Mastodon.", + "annual_report.summary.archetype.pollster.desc_self": "Chruthaich thu barrachd chunntasan-beachd na seòrsaichean eile de phost, a’ cur ris an iongantas air Mastodon.", + "annual_report.summary.archetype.pollster.name": "An Culaidh-iongantais", + "annual_report.summary.archetype.replier.desc_public": "Fhreagradh {name} gu tric air postaichean càich, a’ cur deasbadan ùra gu dol air Mastodon.", + "annual_report.summary.archetype.replier.desc_self": "Fhreagradh tu gu tric air postaichean càich, a’ cur deasbadan ùra gu dol air Mastodon.", + "annual_report.summary.archetype.replier.name": "An Dealan-dè", + "annual_report.summary.archetype.reveal": "Nochd am prìomh-choltas a th’ orm", + "annual_report.summary.archetype.reveal_description": "Mòran taing airson conaltradh air Mastodon! Thàinig an t-àm a gheibheadh tu a-mach dè am prìomh-choltas a bh’ ort {year}.", + "annual_report.summary.archetype.title_public": "Am prìomh-choltas air {name}", + "annual_report.summary.archetype.title_self": "Am prìomh-choltas a th’ ort", + "annual_report.summary.close": "Dùin", + "annual_report.summary.copy_link": "Dèan lethbhreac dhen cheangal", + "annual_report.summary.followers.new_followers": "{count, plural, one {neach-leantainn ùr} two {neach-leantainn ùra} few {luchd-leantainn ùra} other {luchd-leantainn ùra}}", + "annual_report.summary.highlighted_post.boost_count": "Chaidh am post seo a bhrosnachadh {count, plural, one {# turas} two {# thuras} few {# tursan} other {# turas}}.", + "annual_report.summary.highlighted_post.favourite_count": "Chaidh am post seo a chur ris na h-annsachdan {count, plural, one {# turas} two {# thuras} few {# tursan} other {# turas}}.", + "annual_report.summary.highlighted_post.reply_count": "Fhuair am post seo {count, plural, one {# fhreagairt} two {# fhreagairt} few {# freagairtean} other {# freagairt}}.", + "annual_report.summary.highlighted_post.title": "Am post air an robh fèill as motha", "annual_report.summary.most_used_app.most_used_app": "an aplacaid a chaidh a cleachdadh as trice", "annual_report.summary.most_used_hashtag.most_used_hashtag": "an taga hais a chaidh a cleachdadh as trice", + "annual_report.summary.most_used_hashtag.used_count": "Ghabh thu a-staigh an taga hais seo ann an {count, plural, one {# phost} two {# phost} few {# postaichean} other {# post}}.", + "annual_report.summary.most_used_hashtag.used_count_public": "Ghabh {name} a-staigh an taga hais seo ann an {count, plural, one {# phost} two {# phost} few {# postaichean} other {# post}}.", "annual_report.summary.new_posts.new_posts": "postaichean ùra", "annual_report.summary.percentile.text": "Tha thu am measgdhen luchd-cleachdaidh as cliùitiche air {domain}.", "annual_report.summary.percentile.we_wont_tell_bernie": "Ainmeil ’nad latha ’s ’nad linn.", + "annual_report.summary.share_elsewhere": "Co-roinn am badeigin eile", + "annual_report.summary.share_message": "’S e {archetype} am prìomh-choltas a th’ orm!", + "annual_report.summary.share_on_mastodon": "Co-roinn air Mastodon", "attachments_list.unprocessed": "(gun phròiseasadh)", "audio.hide": "Falaich an fhuaim", "block_modal.remote_users_caveat": "Iarraidh sinn air an fhrithealaiche {domain} gun gèill iad ri do cho-dhùnadh. Gidheadh, chan eil barantas gun gèill iad on a làimhsicheas cuid a fhrithealaichean bacaidhean air dòigh eadar-dhealaichte. Dh’fhaoidte gum faic daoine gun chlàradh a-steach na postaichean poblach agad fhathast.", @@ -162,7 +203,7 @@ "column.favourites": "Annsachdan", "column.firehose": "An saoghal beò", "column.firehose_local": "Loidhne-ama bheò an fhrithealaiche seo", - "column.firehose_singular": "Loidhne-ama bheò beò", + "column.firehose_singular": "Loidhne-ama bheò", "column.follow_requests": "Iarrtasan leantainn", "column.home": "Dachaigh", "column.list_members": "Stiùir buill na liosta", @@ -343,6 +384,7 @@ "empty_column.notification_requests": "Glan! Chan eil dad an-seo. Nuair a gheibh thu brathan ùra, nochdaidh iad an-seo a-rèir nan roghainnean agad.", "empty_column.notifications": "Cha d’ fhuair thu brath sam bith fhathast. Nuair a nì càch conaltradh leat, chì thu an-seo e.", "empty_column.public": "Chan eil dad an-seo! Sgrìobh rudeigin gu poblach no lean càch o fhrithealaichean eile a làimh airson seo a lìonadh", + "error.no_hashtag_feed_access": "Cruthaich cunntas no clàraich a-steach airson an taga hais seo a shealltainn is leantainn.", "error.unexpected_crash.explanation": "Air sàilleibh buga sa chòd againn no duilgheadas co-chòrdalachd leis a’ bhrabhsair, chan urrainn dhuinn an duilleag seo a shealltainn mar bu chòir.", "error.unexpected_crash.explanation_addons": "Cha b’ urrainn dhuinn an duilleag seo a shealltainn mar bu chòir. Tha sinn an dùil gu do dh’adhbharaich tuilleadan a’ bhrabhsair no inneal eadar-theangachaidh fèin-obrachail a’ mhearachd.", "error.unexpected_crash.next_steps": "Feuch an ath-nuadhaich thu an duilleag seo. Mura cuidich sin, dh’fhaoidte gur urrainn dhut Mastodon a chleachdadh fhathast le brabhsair eile no le aplacaid thùsail.", @@ -399,6 +441,8 @@ "follow_suggestions.who_to_follow": "Molaidhean leantainn", "followed_tags": "Tagaichean hais ’gan leantainn", "footer.about": "Mu dhèidhinn", + "footer.about_mastodon": "Mu Mhastodon", + "footer.about_server": "Mu {domain}", "footer.about_this_server": "Mu dhèidhinn", "footer.directory": "Eòlaire nam pròifil", "footer.get_app": "Faigh an aplacaid", @@ -473,6 +517,7 @@ "keyboard_shortcuts.column": "Cuir am fòcas air colbh", "keyboard_shortcuts.compose": "Cuir am fòcas air raon teacsa an sgrìobhaidh", "keyboard_shortcuts.description": "Tuairisgeul", + "keyboard_shortcuts.direct": "Fosgail colbh nan iomraidhean prìobhaideach", "keyboard_shortcuts.down": "Gluais sìos air an liosta", "keyboard_shortcuts.enter": "Fosgail post", "keyboard_shortcuts.favourite": "Cuir am post ris na h-annsachdan", @@ -500,6 +545,7 @@ "keyboard_shortcuts.toggle_hidden": "Seall/Falaich an teacsa fo rabhadh susbainte", "keyboard_shortcuts.toggle_sensitivity": "Seall/Falaich na meadhanan", "keyboard_shortcuts.toot": "Tòisich air post ùr", + "keyboard_shortcuts.top": "Gluais gu bàrr na liosta", "keyboard_shortcuts.translate": "airson post eadar-theangachadh", "keyboard_shortcuts.unfocus": "Thoir am fòcas far raon teacsa an sgrìobhaidh/an luirg", "keyboard_shortcuts.up": "Gluais suas air an liosta", @@ -888,6 +934,7 @@ "status.edited_x_times": "Chaidh a dheasachadh {count, plural, one {{count} turas} two {{count} thuras} few {{count} tursan} other {{count} turas}}", "status.embed": "Faigh còd leabachaidh", "status.favourite": "Cuir ris na h-annsachdan", + "status.favourites_count": "{count, plural, one {{counter} annsachd} two {{counter} annsachd} few {{counter} annsachdan} other {{counter} annsachd}}", "status.filter": "Criathraich am post seo", "status.history.created": "Chruthaich {name} {date} e", "status.history.edited": "Dheasaich {name} {date} e", @@ -922,12 +969,14 @@ "status.quotes.empty": "Chan deach am post seo a luaidh le duine sam bith fhathast. Nuair a luaidheas cuideigin e, nochdaidh iad an-seo.", "status.quotes.local_other_disclaimer": "Cha tèid luaidhean a dhiùilt an ùghdar a shealltainn.", "status.quotes.remote_other_disclaimer": "Cha dèid ach luaidhean o {domain} a shealltainn an-seo le cinnt. Cha dèid luaidhean a dhiùilt an ùghdar a shealltainn.", + "status.quotes_count": "{count, plural, one {{counter} luaidh} two {{counter} luaidh} few {{counter} luaidhean} other {{counter} luaidh}}", "status.read_more": "Leugh an còrr", "status.reblog": "Brosnaich", "status.reblog_or_quote": "Brosnaich no luaidh", "status.reblog_private": "Co-roinn leis an luchd-leantainn agad a-rithist", "status.reblogged_by": "’Ga bhrosnachadh le {name}", "status.reblogs.empty": "Chan deach am post seo a bhrosnachadh le duine sam bith fhathast. Nuair a bhrosnaicheas cuideigin e, nochdaidh iad an-seo.", + "status.reblogs_count": "{count, plural, one {{counter} bhrosnachadh} two {{counter} bhrosnachadh} few {{counter} brosnachaidhean} other {{counter} brosnachadh}}", "status.redraft": "Sguab às ⁊ dèan dreachd ùr", "status.remove_bookmark": "Thoir an comharra-lìn air falbh", "status.remove_favourite": "Thoir air falbh o na h-annsachdan", diff --git a/config/locales/activerecord.gd.yml b/config/locales/activerecord.gd.yml index 6b068d04dc..572fcc83df 100644 --- a/config/locales/activerecord.gd.yml +++ b/config/locales/activerecord.gd.yml @@ -32,6 +32,12 @@ gd: attributes: url: invalid: "– chan eil seo ’na URL dligheach" + collection: + attributes: + collection_items: + too_many: "– tha cus dhiubh ann, chan eil còrr is %{count} ceadaichte" + tag: + unusable: "– chan fhaodar seo a chleachdadh" doorkeeper/application: attributes: website: diff --git a/config/locales/gd.yml b/config/locales/gd.yml index b637a9eb71..8f64ee1984 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -7,6 +7,8 @@ gd: hosted_on: Mastodon ’ga òstadh air %{domain} title: Mu dhèidhinn accounts: + errors: + cannot_be_added_to_collections: Cha ghabh an cunntas seo a chur ri cruinneachadh. followers: few: Luchd-leantainn one: Neach-leantainn @@ -874,6 +876,7 @@ gd: publish_statistics: Foillsich an stadastaireachd title: Rùrachadh trends: Treandaichean + wrapstodon: Wrapstodon domain_blocks: all: Dhan a h-uile duine disabled: Na seall idir @@ -1354,6 +1357,13 @@ gd: hint_html: "Gliocas: Chan iarr sinn am facal-faire agad ort a-rithist fad uair a thìde." invalid_password: Facal-faire mì-dhligheach prompt: Dearbh am facal-faire airson leantainn air adhart + color_scheme: + auto: Fèin-obrachail + dark: Dorcha + light: Soilleir + contrast: + auto: Fèin-obrachail + high: Àrd crypto: errors: invalid_key: "– chan e iuchair Ed25519 no Curve25519 dhligheach a th’ ann" @@ -1784,16 +1794,22 @@ gd: body: 'Thug %{name} iomradh ort an-seo:' subject: Thug %{name} iomradh ort title: Iomradh ùr + moderation_warning: + subject: Fhuair thu rabhadh on mhaorsainneachd poll: subject: Thàinig cunntas-bheachd le %{name} gu crìoch quote: body: 'Chaidh post a luaidh le %{name}:' subject: Luaidh %{name} am post agad title: Luaidh ùr + quoted_update: + subject: Dheasaich %{name} post a luaidh thu reblog: body: 'Chaidh am post agad a bhrosnachadh le %{name}:' subject: Bhrosnaich %{name} am post agad title: Brosnachadh ùr + severed_relationships: + subject: Chaill thu dàimhean ri linn co-dhùnadh na maorsainneachd status: subject: Tha %{name} air post a sgrìobhadh update: @@ -2043,9 +2059,11 @@ gd: enabled: Sguab às seann-phostaichean gu fèin-obrachail enabled_hint: Sguabaidh seo às na seann-phostaichean agad gu fèin-obrachail nuair a ruigeas iad stairsneach aoise sònraichte ach ma fhreagras iad ri gin dhe na h-eisgeachdan gu h-ìosal exceptions: Eisgeachdan + explanation: Tha prìomhachas ìosal air an sguabadh às fhèin-obrachail. Dh’fhaoidte gum bi dàil eadar ruigsinn stairsneach na h-aoise agus an toirt air falbh. ignore_favs: Leig seachad na h-annsachdan ignore_reblogs: Leig seachad na brosnachaidhean interaction_exceptions: Eisgeachdan stèidhichte air eadar-ghnìomhan + interaction_exceptions_explanation: Faodaidh postaichean mairsinn ma thèid iad thar stairsneach nan annsachdan no brosnachaidhean rè seal fiù ma bhios an cunntas as ìsle an uairsin. keep_direct: Cùm na teachdaireachdan dìreach keep_direct_hint: Cha dèid gin dhe na teachdaireachdan dìreach agad a sguabadh às keep_media: Cùm postaichean le ceanglachan meadhain @@ -2260,8 +2278,12 @@ gd: error: Bha duilgheadas ann le bhith a’ sguabadh às an iuchair tèarainteachd agad. Feuch ris a-rithist. success: Chaidh an iuchair tèarainteachd agad a sguabadh às. invalid_credential: Iuchair tèarainteachd mì-dhligheach + nickname: Far-ainm nickname_hint: Cuir a-steach far-ainm na h-iuchrach tèarainteachd ùir agad not_enabled: Cha do chuir thu WebAuthn an comas fhathast not_supported: Cha chuir am brabhsair seo taic ri iuchraichean tèarainteachd otp_required: Mus cleachd thu iuchraichean tèarainteachd, feumaidh tu an dearbhadh dà-cheumnach a chur an comas. registered_on: Air a chlàradh %{date} + wrapstodon: + description: Seall mar a chleachd %{name} Mastodon am bliadhna! + title: Wrapstodon %{year} dha %{name} diff --git a/config/locales/simple_form.gd.yml b/config/locales/simple_form.gd.yml index e11b300b33..2673988df1 100644 --- a/config/locales/simple_form.gd.yml +++ b/config/locales/simple_form.gd.yml @@ -88,6 +88,7 @@ gd: activity_api_enabled: Cunntasan nam postaichean a chaidh fhoillseachadh gu h-ionadail, nan cleachdaichean gnìomhach ’s nan clàraidhean ùra an am bucaidean seachdaineil app_icon: WEBP, PNG, GIF no JPG. Tar-àithnidh seo ìomhaigheag bhunaiteach na h-aplacaid air uidheaman mobile le ìomhaigheag ghnàthaichte. backups_retention_period: "’S urrainn do chleachdaichean tasg-lannan dhe na postaichean aca a gintinn airson an luchdadh a-nuas an uairsin. Nuair a bhios luach dearbh air, thèid na tasg-lannan a sguabadh às on stòras agad gu fèin-obrachail às dèidh an àireamh de làithean a shònraich thu." + bootstrap_timeline_accounts: Thèid na cunntasan seo a phrìneachadh air bàrr nam molaidhean leantainn dhan luchd-cleachdaidh ùr. Solar liosta de chunntasan sgaraichte le cromagan. closed_registrations_message: Thèid seo a shealltainn nuair a bhios an clàradh dùinte content_cache_retention_period: Thèid a h-uile post o fhrithealaiche sam bith eile (a’ gabhail a-staigh brosnachaidhean is freagairtean) a sguabadh às às dèidh na h-àireimh de làithean a shònraich thu ’s gun diù a chon air eadar-ghabhail ionadail air na postaichean ud. Gabhaidh seo a-steach na postaichean a chuir cleachdaiche ionadail ris na h-annsachdan aca no comharran-lìn riutha. Thèid iomraidhean prìobhaideach eadar cleachdaichean o ionstansan diofraichte air chall cuideachd agus cha ghabh an aiseag idir. Tha an roghainn seo do dh’ionstansan sònraichte a-mhàin agus briseadh e dùilean an luchd-cleachdaidh nuair a rachadh a chleachdadh gu coitcheann. custom_css: "’S urrainn dhut stoidhlean gnàthaichte a chur an sàs air an tionndadh-lìn de Mhastodon." @@ -110,6 +111,7 @@ gd: thumbnail: Dealbh mu 2:1 a thèid a shealltainn ri taobh fiosrachadh an fhrithealaiche agad. trendable_by_default: Geàrr leum thar lèirmheas a làimh na susbainte a’ treandadh. Gabhaidh nithean fa leth a thoirt far nan treandaichean fhathast an uairsin. trends: Seallaidh na treandaichean na postaichean, tagaichean hais is naidheachdan a tha fèill mhòr orra air an fhrithealaiche agad. + wrapstodon: Tairg gintinn geàrr-chunntais àbhaich air mar a chleachd iad Mastodon rè a’ bhliadhna dhan luchd-cleachdaidh ionadail. Bidh an gleus seo ri fhaighinn eadar an 10mh is 31mh dhen Dùbhlachd gach bliadhna ’s thèid a thairgsinn dhan luchd-cleachdaidh a rinn co-dhiù aon post poblach no sàmhach ’s a chleachd co-dhiù aon taga hais rè a’ bhliadhna. form_challenge: current_password: Tha thu a’ tighinn a-steach gu raon tèarainte imports: @@ -239,6 +241,8 @@ gd: setting_always_send_emails: Cuir brathan puist-d an-còmhnaidh setting_auto_play_gif: Cluich GIFs beòthaichte gu fèin-obrachail setting_boost_modal: Smachd air faicsinneachd nam brosnachaidhean + setting_color_scheme: Modh + setting_contrast: Iomsgaradh setting_default_language: Cànan postaidh setting_default_privacy: Faicsinneachd nam post setting_default_quote_policy: Cò dh’fhaodas luaidh @@ -313,6 +317,7 @@ gd: thumbnail: Dealbhag an fhrithealaiche trendable_by_default: Ceadaich treandaichean gun lèirmheas ro làimh trends: Cuir na treandaichean an comas + wrapstodon: Cuir Wrapstodon an comas interactions: must_be_follower: Bac na brathan nach eil o luchd-leantainn must_be_following: Bac na brathan o dhaoine nach lean thu @@ -373,7 +378,9 @@ gd: jurisdiction: Uachdranas laghail min_age: An aois as lugha user: + date_of_birth_1i: Bliadhna date_of_birth_2i: Mìos + date_of_birth_3i: Latha role: Dreuchd time_zone: Roinn-tìde user_role: From c21884920409cbc691735bc55807507649479275 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Wed, 14 Jan 2026 11:08:29 +0100 Subject: [PATCH 3/9] Add collection endpoint (#37468) --- .../activitypub/collections_controller.rb | 2 + app/controllers/collections_controller.rb | 46 ++++++ app/lib/activitypub/tag_manager.rb | 4 +- app/policies/collection_policy.rb | 20 ++- config/routes.rb | 4 +- spec/lib/activitypub/tag_manager_spec.rb | 2 +- spec/policies/collection_policy_spec.rb | 14 +- spec/requests/activitypub/collections_spec.rb | 13 +- spec/requests/collections_spec.rb | 138 ++++++++++++++++++ 9 files changed, 223 insertions(+), 20 deletions(-) create mode 100644 app/controllers/collections_controller.rb create mode 100644 spec/requests/collections_spec.rb diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb index c80db3500d..a03f424e0f 100644 --- a/app/controllers/activitypub/collections_controller.rb +++ b/app/controllers/activitypub/collections_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class ActivityPub::CollectionsController < ActivityPub::BaseController + SUPPORTED_COLLECTIONS = %w(featured tags).freeze + vary_by -> { 'Signature' if authorized_fetch_mode? } before_action :require_account_signature!, if: :authorized_fetch_mode? diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb new file mode 100644 index 0000000000..3e2ba71470 --- /dev/null +++ b/app/controllers/collections_controller.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +class CollectionsController < ApplicationController + include WebAppControllerConcern + include SignatureAuthentication + include Authorization + include AccountOwnedConcern + + vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' } + + before_action :check_feature_enabled + before_action :require_account_signature!, only: :show, if: -> { request.format == :json && authorized_fetch_mode? } + before_action :set_collection + + skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional!, only: :show, unless: :limited_federation_mode? + + def show + respond_to do |format| + # TODO: format.html + + format.json do + expires_in expiration_duration, public: true if public_fetch_mode? + render_with_cache json: @collection, content_type: 'application/activity+json', serializer: ActivityPub::FeaturedCollectionSerializer, adapter: ActivityPub::Adapter + end + end + end + + private + + def set_collection + @collection = @account.collections.find(params[:id]) + authorize @collection, :show? + rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError + not_found + end + + def expiration_duration + recently_updated = @collection.updated_at > 15.minutes.ago + recently_updated ? 30.seconds : 5.minutes + end + + def check_feature_enabled + raise ActionController::RoutingError unless Mastodon::Feature.collections_enabled? + end +end diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index 9f01b00578..e6714c51ab 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -63,7 +63,7 @@ class ActivityPub::TagManager when :flag target.uri when :featured_collection - ap_account_featured_collection_url(target.account.id, target) + ap_account_collection_url(target.account.id, target) end end @@ -135,7 +135,7 @@ class ActivityPub::TagManager def collection_uri_for(target, ...) raise ArgumentError, 'target must be a local account' unless target.local? - target.numeric_ap_id? ? ap_account_collection_url(target.id, ...) : account_collection_url(target, ...) + target.numeric_ap_id? ? ap_account_actor_collection_url(target.id, ...) : account_actor_collection_url(target, ...) end def inbox_uri_for(target) diff --git a/app/policies/collection_policy.rb b/app/policies/collection_policy.rb index 12adfbcad1..70a869d16a 100644 --- a/app/policies/collection_policy.rb +++ b/app/policies/collection_policy.rb @@ -6,7 +6,7 @@ class CollectionPolicy < ApplicationPolicy end def show? - true + current_account.nil? || (!owner_blocking? && !owner_blocking_domain?) end def create? @@ -24,6 +24,22 @@ class CollectionPolicy < ApplicationPolicy private def owner? - current_account == record.account + current_account == owner + end + + def owner_blocking_domain? + return false if current_account.nil? || current_account.domain.nil? + + owner.domain_blocking?(current_account.domain) + end + + def owner_blocking? + return false if current_account.nil? + + current_account.blocked_by?(owner) + end + + def owner + record.account end end diff --git a/config/routes.rb b/config/routes.rb index ff79c758fb..b3338a725e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -96,14 +96,14 @@ Rails.application.routes.draw do get '/authorize_follow', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" } concern :account_resources do - resources :featured_collections, only: [:show] + resources :collections, only: [:show], constraints: { id: /\d+/ } resources :followers, only: [:index], controller: :follower_accounts resources :following, only: [:index], controller: :following_accounts scope module: :activitypub do resource :outbox, only: [:show] resource :inbox, only: [:create] - resources :collections, only: [:show] + resources :collections, only: [:show], as: :actor_collections, constraints: { id: Regexp.union(ActivityPub::CollectionsController::SUPPORTED_COLLECTIONS) } resource :followers_synchronization, only: [:show] resources :quote_authorizations, only: [:show] end diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb index bacbb3251c..55e54ede5e 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -198,7 +198,7 @@ RSpec.describe ActivityPub::TagManager do it 'returns a string starting with web domain and with the expected path' do expect(subject.uri_for(collection)) - .to eq("#{host_prefix}/ap/users/#{collection.account.id}/featured_collections/#{collection.id}") + .to eq("#{host_prefix}/ap/users/#{collection.account.id}/collections/#{collection.id}") end end diff --git a/spec/policies/collection_policy_spec.rb b/spec/policies/collection_policy_spec.rb index 156e1a7657..ecef6e899d 100644 --- a/spec/policies/collection_policy_spec.rb +++ b/spec/policies/collection_policy_spec.rb @@ -16,11 +16,23 @@ RSpec.describe CollectionPolicy do end permissions :show? do - it 'permits everyone to show' do + it 'permits when no user is given' do expect(policy).to permit(nil, collection) + end + + it 'permits unblocked users' do expect(policy).to permit(owner, collection) expect(policy).to permit(other_user, collection) end + + it 'denies blocked users' do + domain_blocked_user = Fabricate(:remote_account) + owner.block_domain!(domain_blocked_user.domain) + owner.block!(other_user) + + expect(policy).to_not permit(domain_blocked_user, collection) + expect(policy).to_not permit(other_user, collection) + end end permissions :create? do diff --git a/spec/requests/activitypub/collections_spec.rb b/spec/requests/activitypub/collections_spec.rb index d2761f98ea..39bd2252e7 100644 --- a/spec/requests/activitypub/collections_spec.rb +++ b/spec/requests/activitypub/collections_spec.rb @@ -14,7 +14,7 @@ RSpec.describe 'ActivityPub Collections' do end describe 'GET #show' do - subject { get account_collection_path(id: id, account_username: account.username), headers: nil, sign_with: remote_account } + subject { get account_actor_collection_path(id: id, account_username: account.username), headers: nil, sign_with: remote_account } context 'when id is "featured"' do let(:id) { 'featured' } @@ -131,16 +131,5 @@ RSpec.describe 'ActivityPub Collections' do end end end - - context 'when id is not "featured"' do - let(:id) { 'hoge' } - - it 'returns http not found' do - subject - - expect(response) - .to have_http_status(404) - end - end end end diff --git a/spec/requests/collections_spec.rb b/spec/requests/collections_spec.rb new file mode 100644 index 0000000000..fece4b62b8 --- /dev/null +++ b/spec/requests/collections_spec.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Collections' do + describe 'GET /@:account_username/collections/:id', feature: :collections do + subject { get account_collection_path(account, collection, format: :json) } + + let(:collection) { Fabricate(:collection) } + let(:account) { collection.account } + + context 'when signed out' do + context 'when account is permanently suspended' do + before do + account.suspend! + account.deletion_request.destroy + end + + it 'returns http gone' do + subject + + expect(response) + .to have_http_status(410) + end + end + + context 'when account is temporarily suspended' do + before { account.suspend! } + + it 'returns http forbidden' do + subject + + expect(response) + .to have_http_status(403) + end + end + + context 'when account is accessible' do + context 'with JSON' do + subject { get ap_account_collection_path(account.id, collection, format: :json) } + + it 'renders ActivityPub FeaturedCollection object successfully', :aggregate_failures do + subject + + expect(response) + .to have_http_status(200) + .and have_cacheable_headers.with_vary('Accept, Accept-Language, Cookie') + + expect(response.headers).to include( + 'Content-Type' => include('application/activity+json') + ) + expect(response.parsed_body) + .to include({ + 'type' => 'FeaturedCollection', + 'name' => collection.name, + }) + end + end + end + end + + context 'when signed in' do + let(:user) { Fabricate(:user) } + + before do + post user_session_path, params: { user: { email: user.email, password: user.password } } + end + + context 'when account blocks user' do + before { account.block!(user.account) } + + it 'returns http not found' do + subject + + expect(response) + .to have_http_status(404) + end + end + end + + context 'with "HTTP Signature" access signed by a remote account' do + subject do + get account_collection_path(account, collection, format: :json), + headers: nil, + sign_with: remote_account + end + + let(:remote_account) { Fabricate(:account, domain: 'host.example') } + + context 'when account blocks the remote account' do + before { account.block!(remote_account) } + + it 'returns http not found' do + subject + + expect(response) + .to have_http_status(404) + end + end + + context 'when account domain blocks the domain of the remote account' do + before { account.block_domain!(remote_account.domain) } + + it 'returns http not found' do + subject + + expect(response) + .to have_http_status(404) + end + end + + context 'with JSON' do + subject do + get ap_account_collection_path(account.id, collection, format: :json), + headers: nil, + sign_with: remote_account + end + + it 'renders ActivityPub FeaturedCollection object successfully', :aggregate_failures do + subject + + expect(response) + .to have_http_status(200) + .and have_cacheable_headers.with_vary('Accept, Accept-Language, Cookie') + + expect(response.headers).to include( + 'Content-Type' => include('application/activity+json') + ) + expect(response.parsed_body) + .to include({ + 'type' => 'FeaturedCollection', + 'name' => collection.name, + }) + end + end + end + end +end From 8390f0dbbf5e809ad67a0d41cb2e84e4bb2c4754 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:10:52 +0100 Subject: [PATCH 4/9] Update dependency rqrcode to v3.2.0 (#37431) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e7519ea90b..d2feffceaf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -720,10 +720,10 @@ GEM rotp (6.3.0) rouge (4.7.0) rpam2 (4.0.2) - rqrcode (3.1.1) + rqrcode (3.2.0) chunky_png (~> 1.0) rqrcode_core (~> 2.0) - rqrcode_core (2.0.1) + rqrcode_core (2.1.0) rspec (3.13.2) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) From d612119b3ec564e0d6c3547d0b2cf07ab08560ea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:17:40 +0100 Subject: [PATCH 5/9] Update dependency thor to v1.5.0 (#37406) 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 d2feffceaf..a54c979764 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -860,7 +860,7 @@ GEM terrapin (1.1.1) climate_control test-prof (1.5.0) - thor (1.4.0) + thor (1.5.0) tilt (2.6.1) timeout (0.6.0) tpm-key_attestation (0.14.1) From 6fdef1191a9e88591dec786e767f800b28df8d02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 11:35:40 +0100 Subject: [PATCH 6/9] Update dependency globals to v17 (#37360) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- streaming/package.json | 2 +- yarn.lock | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 8a1ecc7737..73eb15b74e 100644 --- a/package.json +++ b/package.json @@ -175,7 +175,7 @@ "eslint-plugin-react-hooks": "^7.0.1", "eslint-plugin-storybook": "^10.0.2", "fake-indexeddb": "^6.0.1", - "globals": "^16.0.0", + "globals": "^17.0.0", "husky": "^9.0.11", "lint-staged": "^16.2.6", "msw": "^2.12.1", diff --git a/streaming/package.json b/streaming/package.json index 0f6651b741..7684ed7cc8 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -36,7 +36,7 @@ "@types/express": "^5.0.5", "@types/pg": "^8.6.6", "@types/ws": "^8.5.9", - "globals": "^16.0.0", + "globals": "^17.0.0", "pino-pretty": "^13.0.0", "typescript": "~5.9.0", "typescript-eslint": "^8.28.0" diff --git a/yarn.lock b/yarn.lock index 424b0d623f..9ae3614dee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3039,7 +3039,7 @@ __metadata: fake-indexeddb: "npm:^6.0.1" fast-glob: "npm:^3.3.3" fuzzysort: "npm:^3.0.0" - globals: "npm:^16.0.0" + globals: "npm:^17.0.0" history: "npm:^4.10.1" hoist-non-react-statics: "npm:^3.3.2" http-link-header: "npm:^1.1.1" @@ -3131,7 +3131,7 @@ __metadata: cors: "npm:^2.8.5" dotenv: "npm:^16.0.3" express: "npm:^5.1.0" - globals: "npm:^16.0.0" + globals: "npm:^17.0.0" ioredis: "npm:^5.3.2" jsdom: "npm:^27.0.0" pg: "npm:^8.5.0" @@ -8275,10 +8275,10 @@ __metadata: languageName: node linkType: hard -"globals@npm:^16.0.0": - version: 16.5.0 - resolution: "globals@npm:16.5.0" - checksum: 10c0/615241dae7851c8012f5aa0223005b1ed6607713d6813de0741768bd4ddc39353117648f1a7086b4b0fa45eae733f1c0a0fe369aa4e543bb63f8de8990178ea9 +"globals@npm:^17.0.0": + version: 17.0.0 + resolution: "globals@npm:17.0.0" + checksum: 10c0/e3c169fdcb0fc6755707b697afb367bea483eb29992cfc0de1637382eb893146e17f8f96db6d7453e3696b478a7863ae2000e6c71cd2f4061410285106d3847a languageName: node linkType: hard From 5d03d5d15c1bf91845241dbe77c8b71d4c1eb2c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:37:05 +0000 Subject: [PATCH 7/9] Update dependency libvips to v8.18.0 (#37282) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 865d14402c..b9dcbe59fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -183,7 +183,7 @@ FROM build AS libvips # libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"] # renovate: datasource=github-releases depName=libvips packageName=libvips/libvips -ARG VIPS_VERSION=8.17.3 +ARG VIPS_VERSION=8.18.0 # libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"] ARG VIPS_URL=https://github.com/libvips/libvips/releases/download From 4bdc9d5e1e4af9299867c4c3d700371349181a94 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 10:37:43 +0000 Subject: [PATCH 8/9] Update dependency vite to v7.3.1 (#37248) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 271 +----------------------------------------------------- 1 file changed, 5 insertions(+), 266 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9ae3614dee..4a8e1fa07f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2095,13 +2095,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/aix-ppc64@npm:0.25.5" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/aix-ppc64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/aix-ppc64@npm:0.27.2" @@ -2109,13 +2102,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/android-arm64@npm:0.25.5" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/android-arm64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/android-arm64@npm:0.27.2" @@ -2123,13 +2109,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/android-arm@npm:0.25.5" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@esbuild/android-arm@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/android-arm@npm:0.27.2" @@ -2137,13 +2116,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/android-x64@npm:0.25.5" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - "@esbuild/android-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/android-x64@npm:0.27.2" @@ -2151,13 +2123,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/darwin-arm64@npm:0.25.5" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/darwin-arm64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/darwin-arm64@npm:0.27.2" @@ -2165,13 +2130,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/darwin-x64@npm:0.25.5" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@esbuild/darwin-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/darwin-x64@npm:0.27.2" @@ -2179,13 +2137,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/freebsd-arm64@npm:0.25.5" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/freebsd-arm64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/freebsd-arm64@npm:0.27.2" @@ -2193,13 +2144,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/freebsd-x64@npm:0.25.5" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/freebsd-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/freebsd-x64@npm:0.27.2" @@ -2207,13 +2151,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-arm64@npm:0.25.5" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/linux-arm64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-arm64@npm:0.27.2" @@ -2221,13 +2158,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-arm@npm:0.25.5" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "@esbuild/linux-arm@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-arm@npm:0.27.2" @@ -2235,13 +2165,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-ia32@npm:0.25.5" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/linux-ia32@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-ia32@npm:0.27.2" @@ -2249,13 +2172,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-loong64@npm:0.25.5" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - "@esbuild/linux-loong64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-loong64@npm:0.27.2" @@ -2263,13 +2179,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-mips64el@npm:0.25.5" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - "@esbuild/linux-mips64el@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-mips64el@npm:0.27.2" @@ -2277,13 +2186,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-ppc64@npm:0.25.5" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/linux-ppc64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-ppc64@npm:0.27.2" @@ -2291,13 +2193,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-riscv64@npm:0.25.5" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "@esbuild/linux-riscv64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-riscv64@npm:0.27.2" @@ -2305,13 +2200,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-s390x@npm:0.25.5" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - "@esbuild/linux-s390x@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-s390x@npm:0.27.2" @@ -2319,13 +2207,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/linux-x64@npm:0.25.5" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "@esbuild/linux-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/linux-x64@npm:0.27.2" @@ -2333,13 +2214,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/netbsd-arm64@npm:0.25.5" - conditions: os=netbsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/netbsd-arm64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/netbsd-arm64@npm:0.27.2" @@ -2347,13 +2221,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/netbsd-x64@npm:0.25.5" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/netbsd-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/netbsd-x64@npm:0.27.2" @@ -2361,13 +2228,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/openbsd-arm64@npm:0.25.5" - conditions: os=openbsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/openbsd-arm64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/openbsd-arm64@npm:0.27.2" @@ -2375,13 +2235,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/openbsd-x64@npm:0.25.5" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/openbsd-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/openbsd-x64@npm:0.27.2" @@ -2396,13 +2249,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/sunos-x64@npm:0.25.5" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - "@esbuild/sunos-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/sunos-x64@npm:0.27.2" @@ -2410,13 +2256,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/win32-arm64@npm:0.25.5" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/win32-arm64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/win32-arm64@npm:0.27.2" @@ -2424,13 +2263,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/win32-ia32@npm:0.25.5" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/win32-ia32@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/win32-ia32@npm:0.27.2" @@ -2438,13 +2270,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.5": - version: 0.25.5 - resolution: "@esbuild/win32-x64@npm:0.25.5" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@esbuild/win32-x64@npm:0.27.2": version: 0.27.2 resolution: "@esbuild/win32-x64@npm:0.27.2" @@ -7118,7 +6943,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0": +"esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0, esbuild@npm:^0.27.0": version: 0.27.2 resolution: "esbuild@npm:0.27.2" dependencies: @@ -7207,92 +7032,6 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.25.0": - version: 0.25.5 - resolution: "esbuild@npm:0.25.5" - dependencies: - "@esbuild/aix-ppc64": "npm:0.25.5" - "@esbuild/android-arm": "npm:0.25.5" - "@esbuild/android-arm64": "npm:0.25.5" - "@esbuild/android-x64": "npm:0.25.5" - "@esbuild/darwin-arm64": "npm:0.25.5" - "@esbuild/darwin-x64": "npm:0.25.5" - "@esbuild/freebsd-arm64": "npm:0.25.5" - "@esbuild/freebsd-x64": "npm:0.25.5" - "@esbuild/linux-arm": "npm:0.25.5" - "@esbuild/linux-arm64": "npm:0.25.5" - "@esbuild/linux-ia32": "npm:0.25.5" - "@esbuild/linux-loong64": "npm:0.25.5" - "@esbuild/linux-mips64el": "npm:0.25.5" - "@esbuild/linux-ppc64": "npm:0.25.5" - "@esbuild/linux-riscv64": "npm:0.25.5" - "@esbuild/linux-s390x": "npm:0.25.5" - "@esbuild/linux-x64": "npm:0.25.5" - "@esbuild/netbsd-arm64": "npm:0.25.5" - "@esbuild/netbsd-x64": "npm:0.25.5" - "@esbuild/openbsd-arm64": "npm:0.25.5" - "@esbuild/openbsd-x64": "npm:0.25.5" - "@esbuild/sunos-x64": "npm:0.25.5" - "@esbuild/win32-arm64": "npm:0.25.5" - "@esbuild/win32-ia32": "npm:0.25.5" - "@esbuild/win32-x64": "npm:0.25.5" - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-arm64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-arm64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 10c0/aba8cbc11927fa77562722ed5e95541ce2853f67ad7bdc40382b558abc2e0ec57d92ffb820f082ba2047b4ef9f3bc3da068cdebe30dfd3850cfa3827a78d604e - languageName: node - linkType: hard - "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -14449,10 +14188,10 @@ __metadata: linkType: hard "vite@npm:^6.0.0 || ^7.0.0, vite@npm:^7.1.1": - version: 7.2.7 - resolution: "vite@npm:7.2.7" + version: 7.3.1 + resolution: "vite@npm:7.3.1" dependencies: - esbuild: "npm:^0.25.0" + esbuild: "npm:^0.27.0" fdir: "npm:^6.5.0" fsevents: "npm:~2.3.3" picomatch: "npm:^4.0.3" @@ -14499,7 +14238,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/0c502d9eb898d9c05061dbd8fd199f280b524bbb4c12ab5f88c7b12779947386684a269e4dd0aa424aa35bcd857f1aa44aadb9ea764702a5043af433052455b5 + checksum: 10c0/5c7548f5f43a23533e53324304db4ad85f1896b1bfd3ee32ae9b866bac2933782c77b350eb2b52a02c625c8ad1ddd4c000df077419410650c982cd97fde8d014 languageName: node linkType: hard From 10de65e41c3b01bd938f97fdb60fc96c26673966 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 14 Jan 2026 11:51:23 +0100 Subject: [PATCH 9/9] Fix `FeedManager#filter_from_home` error when handling a reblog of a deleted status (#37486) --- app/lib/feed_manager.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 9c5c306e96..ab5ee106c7 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -450,6 +450,7 @@ class FeedManager return :filter if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?) return :skip_home if timeline_type != :list && crutches[:exclusive_list_users][status.account_id].present? return :filter if crutches[:languages][status.account_id].present? && status.language.present? && !crutches[:languages][status.account_id].include?(status.language) + return :filter if status.reblog? && status.reblog.blank? check_for_blocks = crutches[:active_mentions][status.id] || [] check_for_blocks.push(status.account_id)