From ab93e9fc8a6c878bba7d73a31005984a1f10c204 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Oct 2025 11:13:17 +0200 Subject: [PATCH 1/6] Update dependency `rack` (#36443) --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 38e189a21b..5a88ac2eec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -620,7 +620,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (3.2.2) + rack (3.2.3) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-cors (3.0.0) From 8b78c033e89c2814cb9955b5d0daffe12c58a70d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 11:25:52 +0200 Subject: [PATCH 2/6] New Crowdin Translations (automated) (#36433) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/da.json | 6 +-- app/javascript/mastodon/locales/de.json | 4 +- app/javascript/mastodon/locales/ku.json | 1 + app/javascript/mastodon/locales/nan.json | 1 + app/javascript/mastodon/locales/sk.json | 3 ++ app/javascript/mastodon/locales/zh-TW.json | 2 +- config/locales/ast.yml | 3 ++ config/locales/be.yml | 10 +++++ config/locales/da.yml | 10 +++++ config/locales/de.yml | 10 +++++ config/locales/el.yml | 10 +++++ config/locales/es-AR.yml | 10 +++++ config/locales/es-MX.yml | 10 +++++ config/locales/es.yml | 10 +++++ config/locales/fi.yml | 10 +++++ config/locales/fo.yml | 7 ++++ config/locales/ga.yml | 10 +++++ config/locales/he.yml | 10 +++++ config/locales/is.yml | 10 +++++ config/locales/nan.yml | 44 ++++++++++++++++++++++ config/locales/nl.yml | 16 ++++++-- config/locales/simple_form.nl.yml | 4 ++ config/locales/simple_form.sq.yml | 4 ++ config/locales/sq.yml | 10 +++++ config/locales/tr.yml | 3 ++ config/locales/vi.yml | 10 +++++ config/locales/zh-CN.yml | 10 +++++ config/locales/zh-TW.yml | 10 +++++ 28 files changed, 239 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 255b41e871..92dd5014db 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -172,7 +172,7 @@ "column.domain_blocks": "Blokerede domæner", "column.edit_list": "Redigér liste", "column.favourites": "Favoritter", - "column.firehose": "Live feeds", + "column.firehose": "Aktuelt", "column.follow_requests": "Følgeanmodninger", "column.home": "Hjem", "column.list_members": "Håndtér listemedlemmer", @@ -574,8 +574,8 @@ "navigation_bar.follows_and_followers": "Følges og følgere", "navigation_bar.import_export": "Import og eksport", "navigation_bar.lists": "Lister", - "navigation_bar.live_feed_local": "Live feed (lokalt)", - "navigation_bar.live_feed_public": "Live feed (offentligt)", + "navigation_bar.live_feed_local": "Aktuelt (lokalt)", + "navigation_bar.live_feed_public": "Aktuelt (offentligt)", "navigation_bar.logout": "Log af", "navigation_bar.moderation": "Moderering", "navigation_bar.more": "Mere", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 0cc8b5b2f4..c1d848ee07 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -257,8 +257,8 @@ "confirmations.revoke_quote.confirm": "Beitrag entfernen", "confirmations.revoke_quote.message": "Diese Aktion kann nicht rückgängig gemacht werden.", "confirmations.revoke_quote.title": "Beitrag entfernen?", - "confirmations.unblock.confirm": "Nicht mehr blockieren", - "confirmations.unblock.title": "{name} nicht mehr blockieren?", + "confirmations.unblock.confirm": "Entsperren", + "confirmations.unblock.title": "{name} entsperren?", "confirmations.unfollow.confirm": "Entfolgen", "confirmations.unfollow.title": "{name} entfolgen?", "confirmations.withdraw_request.confirm": "Anfrage zurückziehen", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index 092e0f6526..cf8d3e2bec 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -27,6 +27,7 @@ "account.direct": "Bi taybetî qale @{name} bike", "account.disable_notifications": "Êdî min agahdar neke gava @{name} diweşîne", "account.edit_profile": "Profîlê serrast bike", + "account.edit_profile_short": "Serrast bike", "account.enable_notifications": "Min agahdar bike gava @{name} diweşîne", "account.endorse": "Taybetiyên li ser profîl", "account.featured.accounts": "Profîl", diff --git a/app/javascript/mastodon/locales/nan.json b/app/javascript/mastodon/locales/nan.json index d2bf7ed8b8..5d864eeddf 100644 --- a/app/javascript/mastodon/locales/nan.json +++ b/app/javascript/mastodon/locales/nan.json @@ -922,6 +922,7 @@ "status.quotes": "{count, plural, other {# 篇引用ê PO文}}", "status.quotes.empty": "Iáu無lâng引用tsit篇PO文。Nā是有lâng引用,ē佇tsia顯示。.", "status.quotes.local_other_disclaimer": "Hōo作者拒絕引用ê引文bē當顯示。", + "status.quotes.remote_other_disclaimer": "Kan-ta tuì {domain} 來ê引文tsiah保證佇tsia顯示。Hōo作者拒絕ê引文buē顯示。", "status.read_more": "讀詳細", "status.reblog": "轉送", "status.reblog_or_quote": "轉送á是引用", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index f3cb42fb97..c11df5d0d2 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -243,6 +243,9 @@ "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.revoke_quote.title": "Vymazať príspevok?", + "confirmations.unblock.confirm": "Odblokovať", + "confirmations.unblock.title": "Odblokovať {name}?", "confirmations.unfollow.confirm": "Zrušiť sledovanie", "content_warning.hide": "Skryť príspevok", "content_warning.show": "Aj tak zobraziť", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index f5e285fbeb..35e7250f0e 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -42,7 +42,7 @@ "account.follow": "跟隨", "account.follow_back": "跟隨回去", "account.follow_back_short": "跟隨回去", - "account.follow_request": "要求跟隨您", + "account.follow_request": "要求跟隨", "account.follow_request_cancel": "取消跟隨請求", "account.follow_request_cancel_short": "取消", "account.follow_request_short": "跟隨請求", diff --git a/config/locales/ast.yml b/config/locales/ast.yml index 81806695b5..e2bca6e8cb 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -326,6 +326,9 @@ ast: all: A tol mundu disabled: A naide users: A los perfiles llocales + feed_access: + modes: + public: Tol mundu registrations: preamble: Controla quién pue crear una cuenta nel sirvidor. title: Rexistros diff --git a/config/locales/be.yml b/config/locales/be.yml index a120dcefb5..ebbfb8bf6d 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -1669,6 +1669,13 @@ be: expires_at: Дзее да uses: Выкарыстанні title: Запрасіць людзей + link_preview: + author_html: Ад %{name} + potentially_sensitive_content: + action: Націсніце, каб паказаць + confirm_visit: Вы ўпэўненыя, што хочаце адкрыць гэту спасылку? + hide_button: Схаваць + label: Патэнцыйна далікатны кантэнт lists: errors: limit: Вы дасягнулі макс. колькасці спісаў @@ -1985,6 +1992,9 @@ be: other: "%{count} відэафайла" boosted_from_html: Пашырыў уліковы запіс %{acct_link} content_warning: 'Папярэджанне аб змесціве: %{warning}' + content_warnings: + hide: Схаваць допіс + show: Паказаць усё роўна default_language: Такая, што і мова інтэрфэйсу disallowed_hashtags: few: 'змяшчае недазволеныя хэштэгі: %{tags}' diff --git a/config/locales/da.yml b/config/locales/da.yml index 377ac4952d..0f8bb88cd3 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1591,6 +1591,13 @@ da: expires_at: Udløber uses: Benyttelser title: Invitér personer + link_preview: + author_html: Af %{name} + potentially_sensitive_content: + action: Klik for at vise + confirm_visit: Er du sikker på, at du vil åbne dette link? + hide_button: Skjul + label: Potentielt følsomt indhold lists: errors: limit: Maks. listeantal nået @@ -1901,6 +1908,9 @@ da: other: "%{count} videoer" boosted_from_html: Fremhævet fra %{acct_link} content_warning: 'Indholdsadvarsel: %{warning}' + content_warnings: + hide: Skjul indlæg + show: Vis mere default_language: Samme som UI-sproget disallowed_hashtags: one: 'indeholdte et ikke tilladt hashtag: %{tags}' diff --git a/config/locales/de.yml b/config/locales/de.yml index 90b97335db..3f16ac94d9 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1591,6 +1591,13 @@ de: expires_at: Läuft ab uses: Verwendungen title: Einladungen + link_preview: + author_html: Von %{name} + potentially_sensitive_content: + action: Zum Anzeigen anklicken + confirm_visit: Möchtest du diesen Link wirklich öffnen? + hide_button: Ausblenden + label: Inhaltswarnung lists: errors: limit: Du hast die maximale Anzahl an Listen erreicht @@ -1901,6 +1908,9 @@ de: other: "%{count} Videos" boosted_from_html: Geteilt von %{acct_link} content_warning: 'Inhaltswarnung: %{warning}' + content_warnings: + hide: Beitrag ausblenden + show: Beitrag anzeigen default_language: Wie die Sprache des Webinterface disallowed_hashtags: one: 'enthält einen nicht-erlaubten Hashtag: %{tags}' diff --git a/config/locales/el.yml b/config/locales/el.yml index 35f5fe2ff2..f5a72625f7 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1591,6 +1591,13 @@ el: expires_at: Λήγει uses: Χρήσεις title: Προσκάλεσε κόσμο + link_preview: + author_html: Από %{name} + potentially_sensitive_content: + action: Κάνε κλικ για εμφάνιση + confirm_visit: Σίγουρα θες να ανοίξεις αυτόν τον σύνδεσμο; + hide_button: Απόκρυψη + label: Δυνητικά ευαίσθητο περιεχόμενο lists: errors: limit: Έχεις φτάσει το μέγιστο αριθμό λιστών @@ -1901,6 +1908,9 @@ el: other: "%{count} βίντεο" boosted_from_html: Ενισχύθηκε από %{acct_link} content_warning: 'Προειδοποίηση περιεχομένου: %{warning}' + content_warnings: + hide: Απόκρυψη ανάρτησης + show: Εμφάνιση περισσότερων default_language: Ίδια με γλώσσα διεπαφής disallowed_hashtags: one: 'περιέχει μη επιτρεπτή ετικέτα: %{tags}' diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 8b58313c03..feded782ba 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1591,6 +1591,13 @@ es-AR: expires_at: Vence uses: Usos title: Invitar a gente + link_preview: + author_html: Por %{name} + potentially_sensitive_content: + action: Clic para mostrar + confirm_visit: "¿Está seguro de que querés abrir este enlace?" + hide_button: Ocultar + label: Contenido potencialmente sensible lists: errors: limit: Alcanzaste el número máximo de listas @@ -1901,6 +1908,9 @@ es-AR: other: "%{count} videos" boosted_from_html: Adherido desde %{acct_link} content_warning: 'Advertencia de contenido: %{warning}' + content_warnings: + hide: Ocultar mensaje + show: Mostrar más default_language: Igual que el idioma de la interface disallowed_hashtags: one: 'contenía una etiqueta no permitida: %{tags}' diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 1dde5faf22..0672b21bc4 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -1591,6 +1591,13 @@ es-MX: expires_at: Expira uses: Usos title: Invitar a gente + link_preview: + author_html: Por %{name} + potentially_sensitive_content: + action: Pulsa para mostrar + confirm_visit: "¿Seguro que quieres abrir este enlace?" + hide_button: Ocultar + label: Contenido potencialmente sensible lists: errors: limit: Has alcanzado la cantidad máxima de listas @@ -1901,6 +1908,9 @@ es-MX: other: "%{count} vídeos" boosted_from_html: Impulsado desde %{acct_link} content_warning: 'Alerta de contenido: %{warning}' + content_warnings: + hide: Ocultar publicación + show: Mostrar más default_language: Igual que el idioma de la interfaz disallowed_hashtags: one: 'contenía una etiqueta no permitida: %{tags}' diff --git a/config/locales/es.yml b/config/locales/es.yml index b5c4eef3d1..15fd191ea4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1591,6 +1591,13 @@ es: expires_at: Expira uses: Usos title: Invitar a gente + link_preview: + author_html: Por %{name} + potentially_sensitive_content: + action: Pulsa para mostrar + confirm_visit: "¿Seguro que quieres abrir este enlace?" + hide_button: Ocultar + label: Contenido potencialmente sensible lists: errors: limit: Has alcanzado la cantidad máxima de listas @@ -1901,6 +1908,9 @@ es: other: "%{count} vídeos" boosted_from_html: Impulsado desde %{acct_link} content_warning: 'Alerta de contenido: %{warning}' + content_warnings: + hide: Ocultar publicación + show: Mostrar más default_language: Igual que el idioma de la interfaz disallowed_hashtags: one: 'contenía una etiqueta no permitida: %{tags}' diff --git a/config/locales/fi.yml b/config/locales/fi.yml index eb6b143a91..7b19a0d820 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1591,6 +1591,13 @@ fi: expires_at: Vanhenee uses: Käyttökertoja title: Kutsu käyttäjiä + link_preview: + author_html: Tehnyt %{name} + potentially_sensitive_content: + action: Näytä napsauttamalla + confirm_visit: Haluatko varmasti avata tämän linkin? + hide_button: Piilota + label: Mahdollisesti arkaluonteista sisältöä lists: errors: limit: Sinulla on enimmäismäärä listoja @@ -1901,6 +1908,9 @@ fi: other: "%{count} videota" boosted_from_html: Tehosti lähteestä %{acct_link} content_warning: 'Sisältövaroitus: %{warning}' + content_warnings: + hide: Piilota julkaisu + show: Näytä lisää default_language: Sama kuin käyttöliittymän kieli disallowed_hashtags: one: 'sisälsi kielletyn aihetunnisteen: %{tags}' diff --git a/config/locales/fo.yml b/config/locales/fo.yml index dcddd66899..22ec7bbf25 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1591,6 +1591,13 @@ fo: expires_at: Rennir út uses: Brúk title: Bjóða fólki + link_preview: + author_html: Av %{name} + potentially_sensitive_content: + action: Klikka fyri at vísa + confirm_visit: Er tú vís/ur í, at tú vil lata hetta leinkið upp? + hide_button: Fjal + label: Tilfar, sum møguliga er viðkvæmt lists: errors: limit: Tú hevur rokkið mesta talið av listum diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 5790b4c58c..901a3a3940 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -1708,6 +1708,13 @@ ga: expires_at: In éag uses: Úsáidí title: Tabhair cuireadh do dhaoine + link_preview: + author_html: Le %{name} + potentially_sensitive_content: + action: Cliceáil chun a thaispeáint + confirm_visit: An bhfuil tú cinnte gur mian leat an nasc seo a oscailt? + hide_button: Folaigh + label: Ábhar a d'fhéadfadh a bheith íogair lists: errors: limit: Tá uaslíon na liostaí sroichte agat @@ -2027,6 +2034,9 @@ ga: two: "%{count} físeáin" boosted_from_html: Molta ó %{acct_link} content_warning: 'Rabhadh ábhair: %{warning}' + content_warnings: + hide: Folaigh an post + show: Taispeáin níos mó default_language: Mar an gcéanna le teanga an chomhéadain disallowed_hashtags: few: 'bhí na Haischlib dícheadaithe: %{tags}' diff --git a/config/locales/he.yml b/config/locales/he.yml index f577d64366..3ea929f76c 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1669,6 +1669,13 @@ he: expires_at: פג תוקף ב- uses: שימושים title: הזמנת אנשים + link_preview: + author_html: מאת %{name} + potentially_sensitive_content: + action: לחץ להצגה + confirm_visit: האם להמשיך ליעד הקישור? + hide_button: להסתיר + label: תוכן שעלול להיות רגיש lists: errors: limit: הגעת למספר הרשימות המירבי @@ -1985,6 +1992,9 @@ he: two: "%{count} סרטונים" boosted_from_html: הודהד מ-%{acct_link} content_warning: 'אזהרת תוכן: %{warning}' + content_warnings: + hide: להסתיר הודעה + show: הצג עוד default_language: זהה לשפת ממשק disallowed_hashtags: many: 'מכיל את התגיות האסורות: %{tags}' diff --git a/config/locales/is.yml b/config/locales/is.yml index ba9a7680ac..39a2150fb5 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1595,6 +1595,13 @@ is: expires_at: Rennur út uses: Afnot title: Bjóða fólki + link_preview: + author_html: Frá %{name} + potentially_sensitive_content: + action: Smelltu til að birta + confirm_visit: Ertu viss um að þú viljir opna þennan tengil? + hide_button: Fela + label: Mögulega viðkvæmt efni lists: errors: limit: Þú hefur náð hámarksfjölda lista @@ -1905,6 +1912,9 @@ is: other: "%{count} myndskeið" boosted_from_html: Endurbirt frá %{acct_link} content_warning: 'Aðvörun vegna efnis (CW): %{warning}' + content_warnings: + hide: Fela færslu + show: Sýna meira default_language: Sama og tungumál viðmóts disallowed_hashtags: one: 'innihélt óleyfilegt myllumerki: %{tags}' diff --git a/config/locales/nan.yml b/config/locales/nan.yml index 5dbbcdac02..74d4fd813f 100644 --- a/config/locales/nan.yml +++ b/config/locales/nan.yml @@ -834,6 +834,10 @@ nan: all: Kàu ta̍k ê lâng disabled: 無kàu tó tsi̍t ê users: Kàu ta̍k位登入ê用者 + feed_access: + modes: + authenticated: Kan-ta hōo登入ê用者 + public: Ta̍k lâng registrations: moderation_recommandation: 佇開放hōo ta̍k ê lâng註冊進前,請確認lí有夠額koh主動反應ê管理團隊! preamble: 控制ē當佇lí ê服侍器註冊ê人。 @@ -992,6 +996,7 @@ nan: notified_on_html: 佇 %{date} 通知ê用者 notify_users: 通知用者 preview: + explanation_html: Tsit封email ē送hōo tī %{date} 進前註冊 ê %{display_count} ê用者。Email ē包括下跤ê文字: send_preview: Kā tāi先看ê內容寄kàu %{email} send_to_all: other: 寄出 %{display_count} 張電子phue @@ -1014,6 +1019,7 @@ nan: confirm_allow_provider: Lí kám確定beh允准所揀ê提供者? confirm_disallow: Lí kám確定無愛允准所揀ê連結? confirm_disallow_provider: Lí kám確定無愛允准所揀ê提供者? + description_html: Tsia是連結,現tsú時lí ê服侍器hōo通見ê用者大量分享ê。tse通幫tsān lí ê用者tshuē著tsit-má世間有siánn tāi誌。直kàu lí允准公開者,連結bē公開展示。lí通允准á是拒絕單ê連結。 disallow: 無愛允准連結 disallow_provider: 無愛允准提供者 no_link_selected: 因為無揀任何連結,所以lóng無改變 @@ -1028,6 +1034,7 @@ nan: pending_review: Teh等審核 preview_card_providers: allowed: Tsit ê提供者ê連結通刊tī趨勢 + description_html: Tsiah ê域名來自定定受lí ê服侍器分享ê連結。連結bē變做公開趨勢,除非連結ê域名受允准。Lí ê允准(á是拒絕)擴展kàu kiánn域名。 rejected: Tsit ê提供者ê連結bē刊tī趨勢 title: 發布者 rejected: 拒絕ê @@ -1038,6 +1045,7 @@ nan: confirm_allow_account: Lí kám確定beh允准所揀ê口座? confirm_disallow: Lí kám確定無愛允准所揀ê狀態? confirm_disallow_account: Lí kám確定無愛允准所揀ê口座? + description_html: Tsiah ê是lí ê服侍器所知ê,tsit-má teh受tsē-tsē分享kap收藏ê PO文。PO文bē公開顯示,除非lí允准作者,而且作者允准in ê口座hőng推薦hōo別lâng。Lí通允准á是拒絕個別PO文。 disallow: 無允准PO文 disallow_account: 無允准作者 no_status_selected: 因為無揀任何趨勢PO文,所以lóng無改變 @@ -1050,6 +1058,42 @@ nan: dashboard: tag_accounts_measure: 無重複用 tag_languages_dimension: Tsia̍p用ê語言 + tag_servers_dimension: 人氣服侍器 + tag_servers_measure: 無kâng ê服侍器 + tag_uses_measure: Lóng總使用 + description_html: Tsiah ê是hashtag,tsit-má佇lí ê服侍器看見ê tsē-tsē PO文中出現。Tse通tsān lí ê用者tshuē著ta̍k家上tsē討論ê內容。除非lí核准,hashtag bē公開顯示。 + listable: 通受建議 + no_tag_selected: 因為無揀任何標簽,所以lóng無改變 + not_listable: Bē當受建議 + not_trendable: Bē刊tī趨勢 + not_usable: Bē當用 + peaked_on_and_decaying: 佇 %{date} 日上烘,tsit-má teh退火 + title: 趨勢ê hashtag + trendable: 通刊tī趨勢 + trending_rank: '趨勢 #%{rank}' + usable: Ē當用 + usage_comparison: Tī kin-á日hōo %{today} ê lâng用,比較tsa-hng有 %{yesterday} ê + used_by_over_week: + other: 頂禮拜hōo %{count} 位用者用 + title: 推薦kap趨勢 + trending: 趨勢 + username_blocks: + add_new: 加新ê + block_registrations: 封鎖註冊 + comparison: + contains: 包含 + equals: 等於 + contains_html: 包含 %{string} + created_msg: 成功加添用者名規則 + delete: Thâi掉 + edit: + title: 編輯使用者號名規則 + matches_exactly_html: 等於 %{string} + new: + create: 建立規則 + title: 創造使用者號名規則 + no_username_block_selected: 因為無揀任何使用者號名規則,所以lóng無改變 + not_permitted: 無允准 scheduled_statuses: too_soon: Tio̍h用未來ê日期。 statuses: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index fad7cf91aa..2a814367cf 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -850,7 +850,7 @@ nl: users: Aan ingelogde lokale gebruikers feed_access: modes: - authenticated: Alleen geverifieerde gebruikers + authenticated: Alleen ingelogde gebruikers public: Iedereen registrations: moderation_recommandation: Zorg ervoor dat je een adequaat en responsief moderatieteam hebt voordat je registraties voor iedereen openstelt! @@ -911,7 +911,7 @@ nl: status_title: Bericht van @%{name} title: Accountberichten - @%{name} trending: Trending - view_publicly: In het openbaar bekijken + view_publicly: Openbaar bericht bekijken visibility: Zichtbaarheid with_media: Met media strikes: @@ -984,7 +984,7 @@ nl: name: Naam newest: Nieuwste oldest: Oudste - open: In het openbaar bekijken + open: Oorspronkelijk bericht bekijken reset: Opnieuw review: Status beoordelen search: Zoeken @@ -1591,6 +1591,13 @@ nl: expires_at: Verloopt op uses: Aantal keer te gebruiken title: Mensen uitnodigen + link_preview: + author_html: Door %{name} + potentially_sensitive_content: + action: Klik om te tonen + confirm_visit: Ben je zeker dat je deze link wilt openen? + hide_button: Verberg + label: Mogelijk gevoelige inhoud lists: errors: limit: Je hebt het maximum aantal lijsten bereikt @@ -1901,6 +1908,9 @@ nl: other: "%{count} video's" boosted_from_html: Geboost van %{acct_link} content_warning: 'Inhoudswaarschuwing: %{warning}' + content_warnings: + hide: Bericht verbergen + show: Meer tonen default_language: Hetzelfde als de taal van de gebruikersomgeving disallowed_hashtags: one: 'bevatte een niet toegestane hashtag: %{tags}' diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index e6c10a9c22..22e0f3fa70 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -283,12 +283,16 @@ nl: content_cache_retention_period: Bewaartermijn voor externe inhoud custom_css: Aangepaste CSS favicon: Favicon + local_live_feed_access: Toegang tot openbare lokale berichten + local_topic_feed_access: Toegang tot overzicht met lokale hashtags en links mascot: Aangepaste mascotte (legacy) media_cache_retention_period: Bewaartermijn mediacache min_age: Vereiste minimumleeftijd peers_api_enabled: Lijst van bekende servers via de API publiceren profile_directory: Gebruikersgids inschakelen registrations_mode: Wie kan zich registreren + remote_live_feed_access: Toegang tot openbare berichten van andere servers + remote_topic_feed_access: Toegang tot overzicht met hashtags en links van andere servers require_invite_text: Opgeven van een reden is verplicht show_domain_blocks: Domeinblokkades tonen show_domain_blocks_rationale: Redenen voor domeinblokkades tonen diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index 15d9e09e29..a942a2d030 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -158,6 +158,10 @@ sq: name: Emër publik për rolin, nëse roli është ujdisur të shfaqet si një stemë permissions_as_keys: Përdoruesit me këtë rol do të mund të… position: Role më të lartë vendosin zgjidhje përplasje në disa raste. Disa veprime mund të kryhen vetëm mbi role të një shkalle më të ulët + username_block: + allow_with_approval: Në vend të pengimit aty për aty të regjistrimit, regjistrime me përkim do të duan miratimin tuaj + comparison: Ju lutemi, mbani parasysh Problemin Scunthorpe, kur bllokohen përkime të pjesshme + username: Do të merret si përkim, pavarësisht shkrimit me të mëdha apo të vogla dhe pavarësisht homoglifesh të tilla si "4" për "a", ose "3" për "e" webhook: events: Përzgjidhni akte për dërgim template: Hartoni ngarkesë tuajën JSON, duke përdorur ndërkëmbim ndryshoresh. Lëreni të zbrazët, për JSON-in parazgjedhje. diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 3f1978f7c8..5a978ed666 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1578,6 +1578,13 @@ sq: expires_at: Skadon më uses: Përdorime title: Ftoni njerëz + link_preview: + author_html: Nga %{name} + potentially_sensitive_content: + action: Klikoni për shfaqje + confirm_visit: Jeni i sigurt se doni të hapet kjo lidhje? + hide_button: Fshihe + label: Lëndë potencalisht me spec lists: errors: limit: Keni mbërritur në numrin maksimum të listave @@ -1888,6 +1895,9 @@ sq: other: "%{count} video" boosted_from_html: Përforcuar nga %{acct_link} content_warning: 'Sinjalizim lënde: %{warning}' + content_warnings: + hide: Fshihe postimin + show: Shfaq më tepër default_language: Njësoj me gjuhën e ndërfaqes disallowed_hashtags: one: 'përmbante një hashtag të palejuar: %{tags}' diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 0c470b29d1..f07a66d327 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1901,6 +1901,9 @@ tr: other: "%{count} videolar" boosted_from_html: "%{acct_link} kişisinden yeniden paylaştı" content_warning: 'İçerik uyarısı: %{warning}' + content_warnings: + hide: Gönderiyi gizle + show: Daha fazlasını göster default_language: Arayüz diliyle aynı disallowed_hashtags: one: 'izin verilmeyen bir etiket içeriyordu: %{tags}' diff --git a/config/locales/vi.yml b/config/locales/vi.yml index d460f44468..b38035ab07 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1552,6 +1552,13 @@ vi: expires_at: Hết hạn uses: Sử dụng title: Mời bạn bè + link_preview: + author_html: Bởi %{name} + potentially_sensitive_content: + action: Nhấn để xem + confirm_visit: Bạn có chắc muốn mở liên kết này? + hide_button: Ẩn + label: Có khả năng là nội dung nhạy cảm lists: errors: limit: Bạn đã đạt đến số lượng danh sách tối đa @@ -1859,6 +1866,9 @@ vi: other: "%{count} video" boosted_from_html: Đã đăng lại từ %{acct_link} content_warning: 'Cảnh báo nội dung: %{warning}' + content_warnings: + hide: Ẩn tút + show: Mở rộng default_language: Giống giao diện disallowed_hashtags: other: 'chứa các hashtag bị cấm: %{tags}' diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 724f7287f5..60ab656e7d 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1552,6 +1552,13 @@ zh-CN: expires_at: 失效时间 uses: 已使用次数 title: 邀请用户 + link_preview: + author_html: 来自 %{name} + potentially_sensitive_content: + action: 点击查看 + confirm_visit: 您确定要打开此链接吗? + hide_button: 隐藏 + label: 可能为敏感内容 lists: errors: limit: 你已达到列表数量的上限 @@ -1859,6 +1866,9 @@ zh-CN: other: "%{count} 段视频" boosted_from_html: 转嘟自 %{acct_link} content_warning: 内容警告:%{warning} + content_warnings: + hide: 隐藏嘟文 + show: 显示更多 default_language: 与界面显示语言相同 disallowed_hashtags: other: 包含以下被禁止的话题:%{tags} diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index c5478d8a64..0a0c3a1ee5 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1554,6 +1554,13 @@ zh-TW: expires_at: 失效時間 uses: 已使用次數 title: 邀請使用者 + link_preview: + author_html: 來自 %{name} + potentially_sensitive_content: + action: 點擊以顯示 + confirm_visit: 您確定要開啟此連結嗎? + hide_button: 隱藏 + label: 可能為敏感內容 lists: errors: limit: 您所建立之列表數量已達上限 @@ -1861,6 +1868,9 @@ zh-TW: other: "%{count} 段影片" boosted_from_html: 轉嘟自 %{acct_link} content_warning: 內容警告: %{warning} + content_warnings: + hide: 隱藏嘟文 + show: 顯示更多 default_language: 與介面語言相同 disallowed_hashtags: other: 含有不得使用的標籤: %{tags} From 692cfe27fa13d155ccaed929494e5a89a0c50d75 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 12:01:00 +0200 Subject: [PATCH 3/6] Update dependency opentelemetry-instrumentation-excon to v0.25.2 (#36436) 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 5a88ac2eec..ee5f481e34 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -537,7 +537,7 @@ GEM opentelemetry-registry (~> 0.1) opentelemetry-instrumentation-concurrent_ruby (0.23.1) opentelemetry-instrumentation-base (~> 0.24) - opentelemetry-instrumentation-excon (0.25.1) + opentelemetry-instrumentation-excon (0.25.2) opentelemetry-instrumentation-base (~> 0.24) opentelemetry-instrumentation-faraday (0.29.1) opentelemetry-instrumentation-base (~> 0.24) From 8d09e4ef235a0767dcecfe9758a6d4ec1b796196 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Mon, 13 Oct 2025 14:19:14 +0200 Subject: [PATCH 4/6] Merge commit from fork * Streaming: Ensure disabled users cannot connect to streaming * Streaming: Disconnect when the user is disabled --- app/models/user.rb | 4 ++++ spec/models/user_spec.rb | 11 +++++++---- spec/system/streaming/streaming_spec.rb | 24 ++++++++++++++++++++++++ streaming/index.js | 2 +- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 8e0785e7fd..fb6baec5e9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -180,6 +180,10 @@ class User < ApplicationRecord def disable! update!(disabled: true) + + # This terminates all connections for the given account with the streaming + # server: + redis.publish("timeline:system:#{account.id}", Oj.dump(event: :kill)) end def enable! diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a9ab15a956..7088266b34 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -382,12 +382,15 @@ RSpec.describe User do let(:current_sign_in_at) { Time.zone.now } - before do - user.disable! - end - it 'disables user' do + allow(redis).to receive(:publish) + + user.disable! + expect(user).to have_attributes(disabled: true) + + expect(redis) + .to have_received(:publish).with("timeline:system:#{user.account.id}", Oj.dump(event: :kill)).once end end diff --git a/spec/system/streaming/streaming_spec.rb b/spec/system/streaming/streaming_spec.rb index c12bd1b18f..7370033890 100644 --- a/spec/system/streaming/streaming_spec.rb +++ b/spec/system/streaming/streaming_spec.rb @@ -74,4 +74,28 @@ RSpec.describe 'Streaming', :inline_jobs, :streaming do expect(streaming_client.open?).to be(false) end end + + context 'with a disabled user account' do + before do + user.disable! + end + + it 'receives an 401 unauthorized error when trying to connect' do + streaming_client.connect + + expect(streaming_client.status).to eq(401) + expect(streaming_client.open?).to be(false) + end + end + + context 'when the user account is disabled whilst connected' do + it 'terminates the connection for the user' do + streaming_client.connect + + user.disable! + + expect(streaming_client.wait_for(:closed).code).to be(1000) + expect(streaming_client.open?).to be(false) + end + end end diff --git a/streaming/index.js b/streaming/index.js index da8aa657e8..84806acd11 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -355,7 +355,7 @@ const startServer = async () => { * @returns {Promise} */ const accountFromToken = async (token, req) => { - const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token]); + const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL AND users.disabled IS FALSE LIMIT 1', [token]); if (result.rows.length === 0) { throw new AuthenticationError('Invalid access token'); From 24dcb18013dfc94d751e002a0a3fe047a7eb4270 Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Mon, 13 Oct 2025 14:20:23 +0200 Subject: [PATCH 5/6] Merge commit from fork * Ensure tootctl revokes sessions, access tokens and web push subscriptions * Fix test coverage --- app/models/user.rb | 13 +++++++++---- lib/mastodon/cli/accounts.rb | 7 +++++-- spec/lib/mastodon/cli/accounts_spec.rb | 13 +++++++++++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index fb6baec5e9..ccd96bdc92 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -361,17 +361,22 @@ class User < ApplicationRecord end def reset_password! + # First, change password to something random, this revokes sessions and on-going access: + change_password!(SecureRandom.hex) + + # Finally, send a reset password prompt to the user + send_reset_password_instructions + end + + def change_password!(new_password) # First, change password to something random and deactivate all sessions transaction do - update(password: SecureRandom.hex) + update(password: new_password) session_activations.destroy_all end # Then, remove all authorized applications and connected push subscriptions revoke_access! - - # Finally, send a reset password prompt to the user - send_reset_password_instructions end protected diff --git a/lib/mastodon/cli/accounts.rb b/lib/mastodon/cli/accounts.rb index 1b33f56055..25e966bd8e 100644 --- a/lib/mastodon/cli/accounts.rb +++ b/lib/mastodon/cli/accounts.rb @@ -165,14 +165,17 @@ module Mastodon::CLI user.role_id = nil end - password = SecureRandom.hex if options[:reset_password] - user.password = password if options[:reset_password] user.email = options[:email] if options[:email] user.disabled = false if options[:enable] user.disabled = true if options[:disable] user.approved = true if options[:approve] user.disable_two_factor! if options[:disable_2fa] + # Password changes are a little different, as we also need to ensure + # sessions, subscriptions, and access tokens are revoked after changing: + password = SecureRandom.hex if options[:reset_password] + user.change_password!(password) if options[:reset_password] + if user.save user.confirm if options[:confirm] diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb index 111703a18b..927c6ca8de 100644 --- a/spec/lib/mastodon/cli/accounts_spec.rb +++ b/spec/lib/mastodon/cli/accounts_spec.rb @@ -361,11 +361,20 @@ RSpec.describe Mastodon::CLI::Accounts do context 'with --reset-password option' do let(:options) { { reset_password: true } } + let(:user) { Fabricate(:user, password: original_password) } + let(:original_password) { 'foobar12345' } + let(:new_password) { 'new_password12345' } + it 'returns a new password for the user' do - allow(SecureRandom).to receive(:hex).and_return('new_password') + allow(SecureRandom).to receive(:hex).and_return(new_password) + allow(Account).to receive(:find_local).and_return(user.account) + allow(user).to receive(:change_password!).and_call_original expect { subject } - .to output_results('new_password') + .to output_results(new_password) + + expect(user).to have_received(:change_password!).with(new_password) + expect(user.reload).to_not be_external_or_valid_password(original_password) end end From 7e98fa9b476fdaed235519f1d527eb956004ba0c Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Mon, 13 Oct 2025 14:20:57 +0200 Subject: [PATCH 6/6] Merge commit from fork * Require read, read:statuses or read:notifications scope to access streaming APIs * Add additional tests for scope-based channel access We were missing tests in the affirmative for subscribing to the user:notification channel, this adds them --- .../streaming/channel_subscriptions_spec.rb | 86 ++++++++++++++++++- streaming/index.js | 26 ++---- 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/spec/system/streaming/channel_subscriptions_spec.rb b/spec/system/streaming/channel_subscriptions_spec.rb index 54e125c293..447ea64f22 100644 --- a/spec/system/streaming/channel_subscriptions_spec.rb +++ b/spec/system/streaming/channel_subscriptions_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'rails_helper' -require 'debug' RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do let(:application) { Fabricate(:application, confidential: false) } @@ -15,6 +14,25 @@ RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do streaming_client.close end + context 'when the access token has insufficient scope to read statuses' do + let(:scopes) { 'profile' } + + it 'cannot subscribe to the public:local channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('public:local') + + # Receive the error back from the subscription attempt: + message = streaming_client.wait_for_message + + expect(message).to include( + error: 'Access token does not have the required scopes', + status: 401 + ) + end + end + context 'when the access token has read scope' do let(:scopes) { 'read' } @@ -39,11 +57,52 @@ RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do ) ) end + + it 'can subscribing to the user:notifications channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('user:notification') + + # We need to perform an action that triggers a notification as there is + # no positive acknowledgement of subscriptions: + first_status = PostStatusService.new.call(user_account, text: 'Test') + ReblogService.new.call(bob_account, first_status) + + message = streaming_client.wait_for_message + + expect(message).to include( + event: 'notification', + stream: ['user:notification'] + ) + end end - context 'when the access token cannot read notifications' do + context 'when the access token has read:statuses scope' do let(:scopes) { 'read:statuses' } + it 'can subscribing to the public:local channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('public:local') + + # We need to publish a status as there is no positive acknowledgement of + # subscriptions: + status = PostStatusService.new.call(bob_account, text: 'Hello @alice') + + # And then we want to receive that status: + message = streaming_client.wait_for_message + + expect(message).to include( + stream: be_an(Array).and(contain_exactly('public:local')), + event: 'update', + payload: include( + id: status.id.to_s + ) + ) + end + it 'cannot subscribing to the user:notifications channel' do streaming_client.authenticate(access_token.token) @@ -59,4 +118,27 @@ RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do ) end end + + context 'when the access token has read:notifications scope' do + let(:scopes) { 'read:notifications' } + + it 'can subscribing to the user:notifications channel' do + streaming_client.authenticate(access_token.token) + + streaming_client.connect + streaming_client.subscribe('user:notification') + + # We need to perform an action that triggers a notification as there is + # no positive acknowledgement of subscriptions: + first_status = PostStatusService.new.call(user_account, text: 'Test') + ReblogService.new.call(bob_account, first_status) + + message = streaming_client.wait_for_message + + expect(message).to include( + event: 'notification', + stream: ['user:notification'] + ) + end + end end diff --git a/streaming/index.js b/streaming/index.js index 84806acd11..e618e3e530 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -78,17 +78,6 @@ const parseJSON = (json, req) => { } }; -const PUBLIC_CHANNELS = [ - 'public', - 'public:media', - 'public:local', - 'public:local:media', - 'public:remote', - 'public:remote:media', - 'hashtag', - 'hashtag:local', -]; - // Used for priming the counters/gauges for the various metrics that are // per-channel const CHANNEL_NAMES = [ @@ -97,7 +86,14 @@ const CHANNEL_NAMES = [ 'user:notification', 'list', 'direct', - ...PUBLIC_CHANNELS + 'public', + 'public:media', + 'public:local', + 'public:local:media', + 'public:remote', + 'public:remote:media', + 'hashtag', + 'hashtag:local', ]; const startServer = async () => { @@ -434,12 +430,6 @@ const startServer = async () => { const checkScopes = (req, logger, channelName) => new Promise((resolve, reject) => { logger.debug(`Checking OAuth scopes for ${channelName}`); - // When accessing public channels, no scopes are needed - if (channelName && PUBLIC_CHANNELS.includes(channelName)) { - resolve(); - return; - } - // The `read` scope has the highest priority, if the token has it // then it can access all streams const requiredScopes = ['read'];