mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-14 16:28:59 +00:00
Merge commit '7e98fa9b476fdaed235519f1d527eb956004ba0c' into glitch-soc/merge-upstream
This commit is contained in:
@@ -537,7 +537,7 @@ GEM
|
|||||||
opentelemetry-registry (~> 0.1)
|
opentelemetry-registry (~> 0.1)
|
||||||
opentelemetry-instrumentation-concurrent_ruby (0.23.1)
|
opentelemetry-instrumentation-concurrent_ruby (0.23.1)
|
||||||
opentelemetry-instrumentation-base (~> 0.24)
|
opentelemetry-instrumentation-base (~> 0.24)
|
||||||
opentelemetry-instrumentation-excon (0.25.1)
|
opentelemetry-instrumentation-excon (0.25.2)
|
||||||
opentelemetry-instrumentation-base (~> 0.24)
|
opentelemetry-instrumentation-base (~> 0.24)
|
||||||
opentelemetry-instrumentation-faraday (0.29.1)
|
opentelemetry-instrumentation-faraday (0.29.1)
|
||||||
opentelemetry-instrumentation-base (~> 0.24)
|
opentelemetry-instrumentation-base (~> 0.24)
|
||||||
@@ -620,7 +620,7 @@ GEM
|
|||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
raabro (1.4.0)
|
raabro (1.4.0)
|
||||||
racc (1.8.1)
|
racc (1.8.1)
|
||||||
rack (3.2.2)
|
rack (3.2.3)
|
||||||
rack-attack (6.7.0)
|
rack-attack (6.7.0)
|
||||||
rack (>= 1.0, < 4)
|
rack (>= 1.0, < 4)
|
||||||
rack-cors (3.0.0)
|
rack-cors (3.0.0)
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
"column.domain_blocks": "Blokerede domæner",
|
"column.domain_blocks": "Blokerede domæner",
|
||||||
"column.edit_list": "Redigér liste",
|
"column.edit_list": "Redigér liste",
|
||||||
"column.favourites": "Favoritter",
|
"column.favourites": "Favoritter",
|
||||||
"column.firehose": "Live feeds",
|
"column.firehose": "Aktuelt",
|
||||||
"column.follow_requests": "Følgeanmodninger",
|
"column.follow_requests": "Følgeanmodninger",
|
||||||
"column.home": "Hjem",
|
"column.home": "Hjem",
|
||||||
"column.list_members": "Håndtér listemedlemmer",
|
"column.list_members": "Håndtér listemedlemmer",
|
||||||
@@ -574,8 +574,8 @@
|
|||||||
"navigation_bar.follows_and_followers": "Følges og følgere",
|
"navigation_bar.follows_and_followers": "Følges og følgere",
|
||||||
"navigation_bar.import_export": "Import og eksport",
|
"navigation_bar.import_export": "Import og eksport",
|
||||||
"navigation_bar.lists": "Lister",
|
"navigation_bar.lists": "Lister",
|
||||||
"navigation_bar.live_feed_local": "Live feed (lokalt)",
|
"navigation_bar.live_feed_local": "Aktuelt (lokalt)",
|
||||||
"navigation_bar.live_feed_public": "Live feed (offentligt)",
|
"navigation_bar.live_feed_public": "Aktuelt (offentligt)",
|
||||||
"navigation_bar.logout": "Log af",
|
"navigation_bar.logout": "Log af",
|
||||||
"navigation_bar.moderation": "Moderering",
|
"navigation_bar.moderation": "Moderering",
|
||||||
"navigation_bar.more": "Mere",
|
"navigation_bar.more": "Mere",
|
||||||
|
|||||||
@@ -257,8 +257,8 @@
|
|||||||
"confirmations.revoke_quote.confirm": "Beitrag entfernen",
|
"confirmations.revoke_quote.confirm": "Beitrag entfernen",
|
||||||
"confirmations.revoke_quote.message": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
"confirmations.revoke_quote.message": "Diese Aktion kann nicht rückgängig gemacht werden.",
|
||||||
"confirmations.revoke_quote.title": "Beitrag entfernen?",
|
"confirmations.revoke_quote.title": "Beitrag entfernen?",
|
||||||
"confirmations.unblock.confirm": "Nicht mehr blockieren",
|
"confirmations.unblock.confirm": "Entsperren",
|
||||||
"confirmations.unblock.title": "{name} nicht mehr blockieren?",
|
"confirmations.unblock.title": "{name} entsperren?",
|
||||||
"confirmations.unfollow.confirm": "Entfolgen",
|
"confirmations.unfollow.confirm": "Entfolgen",
|
||||||
"confirmations.unfollow.title": "{name} entfolgen?",
|
"confirmations.unfollow.title": "{name} entfolgen?",
|
||||||
"confirmations.withdraw_request.confirm": "Anfrage zurückziehen",
|
"confirmations.withdraw_request.confirm": "Anfrage zurückziehen",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
"account.direct": "Bi taybetî qale @{name} bike",
|
"account.direct": "Bi taybetî qale @{name} bike",
|
||||||
"account.disable_notifications": "Êdî min agahdar neke gava @{name} diweşîne",
|
"account.disable_notifications": "Êdî min agahdar neke gava @{name} diweşîne",
|
||||||
"account.edit_profile": "Profîlê serrast bike",
|
"account.edit_profile": "Profîlê serrast bike",
|
||||||
|
"account.edit_profile_short": "Serrast bike",
|
||||||
"account.enable_notifications": "Min agahdar bike gava @{name} diweşîne",
|
"account.enable_notifications": "Min agahdar bike gava @{name} diweşîne",
|
||||||
"account.endorse": "Taybetiyên li ser profîl",
|
"account.endorse": "Taybetiyên li ser profîl",
|
||||||
"account.featured.accounts": "Profîl",
|
"account.featured.accounts": "Profîl",
|
||||||
|
|||||||
@@ -922,6 +922,7 @@
|
|||||||
"status.quotes": "{count, plural, other {# 篇引用ê PO文}}",
|
"status.quotes": "{count, plural, other {# 篇引用ê PO文}}",
|
||||||
"status.quotes.empty": "Iáu無lâng引用tsit篇PO文。Nā是有lâng引用,ē佇tsia顯示。.",
|
"status.quotes.empty": "Iáu無lâng引用tsit篇PO文。Nā是有lâng引用,ē佇tsia顯示。.",
|
||||||
"status.quotes.local_other_disclaimer": "Hōo作者拒絕引用ê引文bē當顯示。",
|
"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.read_more": "讀詳細",
|
||||||
"status.reblog": "轉送",
|
"status.reblog": "轉送",
|
||||||
"status.reblog_or_quote": "轉送á是引用",
|
"status.reblog_or_quote": "轉送á是引用",
|
||||||
|
|||||||
@@ -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.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.redraft.title": "Vymazať a prepísať príspevok?",
|
||||||
"confirmations.remove_from_followers.confirm": "Odstrániť nasledovateľa",
|
"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",
|
"confirmations.unfollow.confirm": "Zrušiť sledovanie",
|
||||||
"content_warning.hide": "Skryť príspevok",
|
"content_warning.hide": "Skryť príspevok",
|
||||||
"content_warning.show": "Aj tak zobraziť",
|
"content_warning.show": "Aj tak zobraziť",
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
"account.follow": "跟隨",
|
"account.follow": "跟隨",
|
||||||
"account.follow_back": "跟隨回去",
|
"account.follow_back": "跟隨回去",
|
||||||
"account.follow_back_short": "跟隨回去",
|
"account.follow_back_short": "跟隨回去",
|
||||||
"account.follow_request": "要求跟隨您",
|
"account.follow_request": "要求跟隨",
|
||||||
"account.follow_request_cancel": "取消跟隨請求",
|
"account.follow_request_cancel": "取消跟隨請求",
|
||||||
"account.follow_request_cancel_short": "取消",
|
"account.follow_request_cancel_short": "取消",
|
||||||
"account.follow_request_short": "跟隨請求",
|
"account.follow_request_short": "跟隨請求",
|
||||||
|
|||||||
@@ -180,6 +180,10 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
def disable!
|
def disable!
|
||||||
update!(disabled: true)
|
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
|
end
|
||||||
|
|
||||||
def enable!
|
def enable!
|
||||||
@@ -357,17 +361,22 @@ class User < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def reset_password!
|
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
|
# First, change password to something random and deactivate all sessions
|
||||||
transaction do
|
transaction do
|
||||||
update(password: SecureRandom.hex)
|
update(password: new_password)
|
||||||
session_activations.destroy_all
|
session_activations.destroy_all
|
||||||
end
|
end
|
||||||
|
|
||||||
# Then, remove all authorized applications and connected push subscriptions
|
# Then, remove all authorized applications and connected push subscriptions
|
||||||
revoke_access!
|
revoke_access!
|
||||||
|
|
||||||
# Finally, send a reset password prompt to the user
|
|
||||||
send_reset_password_instructions
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|||||||
@@ -326,6 +326,9 @@ ast:
|
|||||||
all: A tol mundu
|
all: A tol mundu
|
||||||
disabled: A naide
|
disabled: A naide
|
||||||
users: A los perfiles llocales
|
users: A los perfiles llocales
|
||||||
|
feed_access:
|
||||||
|
modes:
|
||||||
|
public: Tol mundu
|
||||||
registrations:
|
registrations:
|
||||||
preamble: Controla quién pue crear una cuenta nel sirvidor.
|
preamble: Controla quién pue crear una cuenta nel sirvidor.
|
||||||
title: Rexistros
|
title: Rexistros
|
||||||
|
|||||||
@@ -1669,6 +1669,13 @@ be:
|
|||||||
expires_at: Дзее да
|
expires_at: Дзее да
|
||||||
uses: Выкарыстанні
|
uses: Выкарыстанні
|
||||||
title: Запрасіць людзей
|
title: Запрасіць людзей
|
||||||
|
link_preview:
|
||||||
|
author_html: Ад %{name}
|
||||||
|
potentially_sensitive_content:
|
||||||
|
action: Націсніце, каб паказаць
|
||||||
|
confirm_visit: Вы ўпэўненыя, што хочаце адкрыць гэту спасылку?
|
||||||
|
hide_button: Схаваць
|
||||||
|
label: Патэнцыйна далікатны кантэнт
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Вы дасягнулі макс. колькасці спісаў
|
limit: Вы дасягнулі макс. колькасці спісаў
|
||||||
@@ -1985,6 +1992,9 @@ be:
|
|||||||
other: "%{count} відэафайла"
|
other: "%{count} відэафайла"
|
||||||
boosted_from_html: Пашырыў уліковы запіс %{acct_link}
|
boosted_from_html: Пашырыў уліковы запіс %{acct_link}
|
||||||
content_warning: 'Папярэджанне аб змесціве: %{warning}'
|
content_warning: 'Папярэджанне аб змесціве: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Схаваць допіс
|
||||||
|
show: Паказаць усё роўна
|
||||||
default_language: Такая, што і мова інтэрфэйсу
|
default_language: Такая, што і мова інтэрфэйсу
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
few: 'змяшчае недазволеныя хэштэгі: %{tags}'
|
few: 'змяшчае недазволеныя хэштэгі: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ da:
|
|||||||
expires_at: Udløber
|
expires_at: Udløber
|
||||||
uses: Benyttelser
|
uses: Benyttelser
|
||||||
title: Invitér personer
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Maks. listeantal nået
|
limit: Maks. listeantal nået
|
||||||
@@ -1901,6 +1908,9 @@ da:
|
|||||||
other: "%{count} videoer"
|
other: "%{count} videoer"
|
||||||
boosted_from_html: Fremhævet fra %{acct_link}
|
boosted_from_html: Fremhævet fra %{acct_link}
|
||||||
content_warning: 'Indholdsadvarsel: %{warning}'
|
content_warning: 'Indholdsadvarsel: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Skjul indlæg
|
||||||
|
show: Vis mere
|
||||||
default_language: Samme som UI-sproget
|
default_language: Samme som UI-sproget
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'indeholdte et ikke tilladt hashtag: %{tags}'
|
one: 'indeholdte et ikke tilladt hashtag: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ de:
|
|||||||
expires_at: Läuft ab
|
expires_at: Läuft ab
|
||||||
uses: Verwendungen
|
uses: Verwendungen
|
||||||
title: Einladungen
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Du hast die maximale Anzahl an Listen erreicht
|
limit: Du hast die maximale Anzahl an Listen erreicht
|
||||||
@@ -1901,6 +1908,9 @@ de:
|
|||||||
other: "%{count} Videos"
|
other: "%{count} Videos"
|
||||||
boosted_from_html: Geteilt von %{acct_link}
|
boosted_from_html: Geteilt von %{acct_link}
|
||||||
content_warning: 'Inhaltswarnung: %{warning}'
|
content_warning: 'Inhaltswarnung: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Beitrag ausblenden
|
||||||
|
show: Beitrag anzeigen
|
||||||
default_language: Wie die Sprache des Webinterface
|
default_language: Wie die Sprache des Webinterface
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'enthält einen nicht-erlaubten Hashtag: %{tags}'
|
one: 'enthält einen nicht-erlaubten Hashtag: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ el:
|
|||||||
expires_at: Λήγει
|
expires_at: Λήγει
|
||||||
uses: Χρήσεις
|
uses: Χρήσεις
|
||||||
title: Προσκάλεσε κόσμο
|
title: Προσκάλεσε κόσμο
|
||||||
|
link_preview:
|
||||||
|
author_html: Από %{name}
|
||||||
|
potentially_sensitive_content:
|
||||||
|
action: Κάνε κλικ για εμφάνιση
|
||||||
|
confirm_visit: Σίγουρα θες να ανοίξεις αυτόν τον σύνδεσμο;
|
||||||
|
hide_button: Απόκρυψη
|
||||||
|
label: Δυνητικά ευαίσθητο περιεχόμενο
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Έχεις φτάσει το μέγιστο αριθμό λιστών
|
limit: Έχεις φτάσει το μέγιστο αριθμό λιστών
|
||||||
@@ -1901,6 +1908,9 @@ el:
|
|||||||
other: "%{count} βίντεο"
|
other: "%{count} βίντεο"
|
||||||
boosted_from_html: Ενισχύθηκε από %{acct_link}
|
boosted_from_html: Ενισχύθηκε από %{acct_link}
|
||||||
content_warning: 'Προειδοποίηση περιεχομένου: %{warning}'
|
content_warning: 'Προειδοποίηση περιεχομένου: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Απόκρυψη ανάρτησης
|
||||||
|
show: Εμφάνιση περισσότερων
|
||||||
default_language: Ίδια με γλώσσα διεπαφής
|
default_language: Ίδια με γλώσσα διεπαφής
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'περιέχει μη επιτρεπτή ετικέτα: %{tags}'
|
one: 'περιέχει μη επιτρεπτή ετικέτα: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ es-AR:
|
|||||||
expires_at: Vence
|
expires_at: Vence
|
||||||
uses: Usos
|
uses: Usos
|
||||||
title: Invitar a gente
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Alcanzaste el número máximo de listas
|
limit: Alcanzaste el número máximo de listas
|
||||||
@@ -1901,6 +1908,9 @@ es-AR:
|
|||||||
other: "%{count} videos"
|
other: "%{count} videos"
|
||||||
boosted_from_html: Adherido desde %{acct_link}
|
boosted_from_html: Adherido desde %{acct_link}
|
||||||
content_warning: 'Advertencia de contenido: %{warning}'
|
content_warning: 'Advertencia de contenido: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Ocultar mensaje
|
||||||
|
show: Mostrar más
|
||||||
default_language: Igual que el idioma de la interface
|
default_language: Igual que el idioma de la interface
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'contenía una etiqueta no permitida: %{tags}'
|
one: 'contenía una etiqueta no permitida: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ es-MX:
|
|||||||
expires_at: Expira
|
expires_at: Expira
|
||||||
uses: Usos
|
uses: Usos
|
||||||
title: Invitar a gente
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Has alcanzado la cantidad máxima de listas
|
limit: Has alcanzado la cantidad máxima de listas
|
||||||
@@ -1901,6 +1908,9 @@ es-MX:
|
|||||||
other: "%{count} vídeos"
|
other: "%{count} vídeos"
|
||||||
boosted_from_html: Impulsado desde %{acct_link}
|
boosted_from_html: Impulsado desde %{acct_link}
|
||||||
content_warning: 'Alerta de contenido: %{warning}'
|
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
|
default_language: Igual que el idioma de la interfaz
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'contenía una etiqueta no permitida: %{tags}'
|
one: 'contenía una etiqueta no permitida: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ es:
|
|||||||
expires_at: Expira
|
expires_at: Expira
|
||||||
uses: Usos
|
uses: Usos
|
||||||
title: Invitar a gente
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Has alcanzado la cantidad máxima de listas
|
limit: Has alcanzado la cantidad máxima de listas
|
||||||
@@ -1901,6 +1908,9 @@ es:
|
|||||||
other: "%{count} vídeos"
|
other: "%{count} vídeos"
|
||||||
boosted_from_html: Impulsado desde %{acct_link}
|
boosted_from_html: Impulsado desde %{acct_link}
|
||||||
content_warning: 'Alerta de contenido: %{warning}'
|
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
|
default_language: Igual que el idioma de la interfaz
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'contenía una etiqueta no permitida: %{tags}'
|
one: 'contenía una etiqueta no permitida: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ fi:
|
|||||||
expires_at: Vanhenee
|
expires_at: Vanhenee
|
||||||
uses: Käyttökertoja
|
uses: Käyttökertoja
|
||||||
title: Kutsu käyttäjiä
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Sinulla on enimmäismäärä listoja
|
limit: Sinulla on enimmäismäärä listoja
|
||||||
@@ -1901,6 +1908,9 @@ fi:
|
|||||||
other: "%{count} videota"
|
other: "%{count} videota"
|
||||||
boosted_from_html: Tehosti lähteestä %{acct_link}
|
boosted_from_html: Tehosti lähteestä %{acct_link}
|
||||||
content_warning: 'Sisältövaroitus: %{warning}'
|
content_warning: 'Sisältövaroitus: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Piilota julkaisu
|
||||||
|
show: Näytä lisää
|
||||||
default_language: Sama kuin käyttöliittymän kieli
|
default_language: Sama kuin käyttöliittymän kieli
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'sisälsi kielletyn aihetunnisteen: %{tags}'
|
one: 'sisälsi kielletyn aihetunnisteen: %{tags}'
|
||||||
|
|||||||
@@ -1591,6 +1591,13 @@ fo:
|
|||||||
expires_at: Rennir út
|
expires_at: Rennir út
|
||||||
uses: Brúk
|
uses: Brúk
|
||||||
title: Bjóða fólki
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Tú hevur rokkið mesta talið av listum
|
limit: Tú hevur rokkið mesta talið av listum
|
||||||
|
|||||||
@@ -1708,6 +1708,13 @@ ga:
|
|||||||
expires_at: In éag
|
expires_at: In éag
|
||||||
uses: Úsáidí
|
uses: Úsáidí
|
||||||
title: Tabhair cuireadh do dhaoine
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Tá uaslíon na liostaí sroichte agat
|
limit: Tá uaslíon na liostaí sroichte agat
|
||||||
@@ -2027,6 +2034,9 @@ ga:
|
|||||||
two: "%{count} físeáin"
|
two: "%{count} físeáin"
|
||||||
boosted_from_html: Molta ó %{acct_link}
|
boosted_from_html: Molta ó %{acct_link}
|
||||||
content_warning: 'Rabhadh ábhair: %{warning}'
|
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
|
default_language: Mar an gcéanna le teanga an chomhéadain
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
few: 'bhí na Haischlib dícheadaithe: %{tags}'
|
few: 'bhí na Haischlib dícheadaithe: %{tags}'
|
||||||
|
|||||||
@@ -1669,6 +1669,13 @@ he:
|
|||||||
expires_at: פג תוקף ב-
|
expires_at: פג תוקף ב-
|
||||||
uses: שימושים
|
uses: שימושים
|
||||||
title: הזמנת אנשים
|
title: הזמנת אנשים
|
||||||
|
link_preview:
|
||||||
|
author_html: מאת %{name}
|
||||||
|
potentially_sensitive_content:
|
||||||
|
action: לחץ להצגה
|
||||||
|
confirm_visit: האם להמשיך ליעד הקישור?
|
||||||
|
hide_button: להסתיר
|
||||||
|
label: תוכן שעלול להיות רגיש
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: הגעת למספר הרשימות המירבי
|
limit: הגעת למספר הרשימות המירבי
|
||||||
@@ -1985,6 +1992,9 @@ he:
|
|||||||
two: "%{count} סרטונים"
|
two: "%{count} סרטונים"
|
||||||
boosted_from_html: הודהד מ-%{acct_link}
|
boosted_from_html: הודהד מ-%{acct_link}
|
||||||
content_warning: 'אזהרת תוכן: %{warning}'
|
content_warning: 'אזהרת תוכן: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: להסתיר הודעה
|
||||||
|
show: הצג עוד
|
||||||
default_language: זהה לשפת ממשק
|
default_language: זהה לשפת ממשק
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
many: 'מכיל את התגיות האסורות: %{tags}'
|
many: 'מכיל את התגיות האסורות: %{tags}'
|
||||||
|
|||||||
@@ -1595,6 +1595,13 @@ is:
|
|||||||
expires_at: Rennur út
|
expires_at: Rennur út
|
||||||
uses: Afnot
|
uses: Afnot
|
||||||
title: Bjóða fólki
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Þú hefur náð hámarksfjölda lista
|
limit: Þú hefur náð hámarksfjölda lista
|
||||||
@@ -1905,6 +1912,9 @@ is:
|
|||||||
other: "%{count} myndskeið"
|
other: "%{count} myndskeið"
|
||||||
boosted_from_html: Endurbirt frá %{acct_link}
|
boosted_from_html: Endurbirt frá %{acct_link}
|
||||||
content_warning: 'Aðvörun vegna efnis (CW): %{warning}'
|
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
|
default_language: Sama og tungumál viðmóts
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'innihélt óleyfilegt myllumerki: %{tags}'
|
one: 'innihélt óleyfilegt myllumerki: %{tags}'
|
||||||
|
|||||||
@@ -834,6 +834,10 @@ nan:
|
|||||||
all: Kàu ta̍k ê lâng
|
all: Kàu ta̍k ê lâng
|
||||||
disabled: 無kàu tó tsi̍t ê
|
disabled: 無kàu tó tsi̍t ê
|
||||||
users: Kàu ta̍k位登入ê用者
|
users: Kàu ta̍k位登入ê用者
|
||||||
|
feed_access:
|
||||||
|
modes:
|
||||||
|
authenticated: Kan-ta hōo登入ê用者
|
||||||
|
public: Ta̍k lâng
|
||||||
registrations:
|
registrations:
|
||||||
moderation_recommandation: 佇開放hōo ta̍k ê lâng註冊進前,請確認lí有夠額koh主動反應ê管理團隊!
|
moderation_recommandation: 佇開放hōo ta̍k ê lâng註冊進前,請確認lí有夠額koh主動反應ê管理團隊!
|
||||||
preamble: 控制ē當佇lí ê服侍器註冊ê人。
|
preamble: 控制ē當佇lí ê服侍器註冊ê人。
|
||||||
@@ -992,6 +996,7 @@ nan:
|
|||||||
notified_on_html: 佇 %{date} 通知ê用者
|
notified_on_html: 佇 %{date} 通知ê用者
|
||||||
notify_users: 通知用者
|
notify_users: 通知用者
|
||||||
preview:
|
preview:
|
||||||
|
explanation_html: Tsit封email ē送hōo tī %{date} 進前註冊 ê <strong>%{display_count} ê用者</strong>。Email ē包括下跤ê文字:
|
||||||
send_preview: Kā tāi先看ê內容寄kàu %{email}
|
send_preview: Kā tāi先看ê內容寄kàu %{email}
|
||||||
send_to_all:
|
send_to_all:
|
||||||
other: 寄出 %{display_count} 張電子phue
|
other: 寄出 %{display_count} 張電子phue
|
||||||
@@ -1014,6 +1019,7 @@ nan:
|
|||||||
confirm_allow_provider: Lí kám確定beh允准所揀ê提供者?
|
confirm_allow_provider: Lí kám確定beh允准所揀ê提供者?
|
||||||
confirm_disallow: Lí kám確定無愛允准所揀ê連結?
|
confirm_disallow: Lí kám確定無愛允准所揀ê連結?
|
||||||
confirm_disallow_provider: 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: 無愛允准連結
|
||||||
disallow_provider: 無愛允准提供者
|
disallow_provider: 無愛允准提供者
|
||||||
no_link_selected: 因為無揀任何連結,所以lóng無改變
|
no_link_selected: 因為無揀任何連結,所以lóng無改變
|
||||||
@@ -1028,6 +1034,7 @@ nan:
|
|||||||
pending_review: Teh等審核
|
pending_review: Teh等審核
|
||||||
preview_card_providers:
|
preview_card_providers:
|
||||||
allowed: Tsit ê提供者ê連結通刊tī趨勢
|
allowed: Tsit ê提供者ê連結通刊tī趨勢
|
||||||
|
description_html: Tsiah ê域名來自定定受lí ê服侍器分享ê連結。連結bē變做公開趨勢,除非連結ê域名受允准。Lí ê允准(á是拒絕)擴展kàu kiánn域名。
|
||||||
rejected: Tsit ê提供者ê連結bē刊tī趨勢
|
rejected: Tsit ê提供者ê連結bē刊tī趨勢
|
||||||
title: 發布者
|
title: 發布者
|
||||||
rejected: 拒絕ê
|
rejected: 拒絕ê
|
||||||
@@ -1038,6 +1045,7 @@ nan:
|
|||||||
confirm_allow_account: Lí kám確定beh允准所揀ê口座?
|
confirm_allow_account: Lí kám確定beh允准所揀ê口座?
|
||||||
confirm_disallow: Lí kám確定無愛允准所揀ê狀態?
|
confirm_disallow: Lí kám確定無愛允准所揀ê狀態?
|
||||||
confirm_disallow_account: 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: 無允准PO文
|
||||||
disallow_account: 無允准作者
|
disallow_account: 無允准作者
|
||||||
no_status_selected: 因為無揀任何趨勢PO文,所以lóng無改變
|
no_status_selected: 因為無揀任何趨勢PO文,所以lóng無改變
|
||||||
@@ -1050,6 +1058,42 @@ nan:
|
|||||||
dashboard:
|
dashboard:
|
||||||
tag_accounts_measure: 無重複用
|
tag_accounts_measure: 無重複用
|
||||||
tag_languages_dimension: Tsia̍p用ê語言
|
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:
|
scheduled_statuses:
|
||||||
too_soon: Tio̍h用未來ê日期。
|
too_soon: Tio̍h用未來ê日期。
|
||||||
statuses:
|
statuses:
|
||||||
|
|||||||
@@ -850,7 +850,7 @@ nl:
|
|||||||
users: Aan ingelogde lokale gebruikers
|
users: Aan ingelogde lokale gebruikers
|
||||||
feed_access:
|
feed_access:
|
||||||
modes:
|
modes:
|
||||||
authenticated: Alleen geverifieerde gebruikers
|
authenticated: Alleen ingelogde gebruikers
|
||||||
public: Iedereen
|
public: Iedereen
|
||||||
registrations:
|
registrations:
|
||||||
moderation_recommandation: Zorg ervoor dat je een adequaat en responsief moderatieteam hebt voordat je registraties voor iedereen openstelt!
|
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}
|
status_title: Bericht van @%{name}
|
||||||
title: Accountberichten - @%{name}
|
title: Accountberichten - @%{name}
|
||||||
trending: Trending
|
trending: Trending
|
||||||
view_publicly: In het openbaar bekijken
|
view_publicly: Openbaar bericht bekijken
|
||||||
visibility: Zichtbaarheid
|
visibility: Zichtbaarheid
|
||||||
with_media: Met media
|
with_media: Met media
|
||||||
strikes:
|
strikes:
|
||||||
@@ -984,7 +984,7 @@ nl:
|
|||||||
name: Naam
|
name: Naam
|
||||||
newest: Nieuwste
|
newest: Nieuwste
|
||||||
oldest: Oudste
|
oldest: Oudste
|
||||||
open: In het openbaar bekijken
|
open: Oorspronkelijk bericht bekijken
|
||||||
reset: Opnieuw
|
reset: Opnieuw
|
||||||
review: Status beoordelen
|
review: Status beoordelen
|
||||||
search: Zoeken
|
search: Zoeken
|
||||||
@@ -1591,6 +1591,13 @@ nl:
|
|||||||
expires_at: Verloopt op
|
expires_at: Verloopt op
|
||||||
uses: Aantal keer te gebruiken
|
uses: Aantal keer te gebruiken
|
||||||
title: Mensen uitnodigen
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Je hebt het maximum aantal lijsten bereikt
|
limit: Je hebt het maximum aantal lijsten bereikt
|
||||||
@@ -1901,6 +1908,9 @@ nl:
|
|||||||
other: "%{count} video's"
|
other: "%{count} video's"
|
||||||
boosted_from_html: Geboost van %{acct_link}
|
boosted_from_html: Geboost van %{acct_link}
|
||||||
content_warning: 'Inhoudswaarschuwing: %{warning}'
|
content_warning: 'Inhoudswaarschuwing: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Bericht verbergen
|
||||||
|
show: Meer tonen
|
||||||
default_language: Hetzelfde als de taal van de gebruikersomgeving
|
default_language: Hetzelfde als de taal van de gebruikersomgeving
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'bevatte een niet toegestane hashtag: %{tags}'
|
one: 'bevatte een niet toegestane hashtag: %{tags}'
|
||||||
|
|||||||
@@ -283,12 +283,16 @@ nl:
|
|||||||
content_cache_retention_period: Bewaartermijn voor externe inhoud
|
content_cache_retention_period: Bewaartermijn voor externe inhoud
|
||||||
custom_css: Aangepaste CSS
|
custom_css: Aangepaste CSS
|
||||||
favicon: Favicon
|
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)
|
mascot: Aangepaste mascotte (legacy)
|
||||||
media_cache_retention_period: Bewaartermijn mediacache
|
media_cache_retention_period: Bewaartermijn mediacache
|
||||||
min_age: Vereiste minimumleeftijd
|
min_age: Vereiste minimumleeftijd
|
||||||
peers_api_enabled: Lijst van bekende servers via de API publiceren
|
peers_api_enabled: Lijst van bekende servers via de API publiceren
|
||||||
profile_directory: Gebruikersgids inschakelen
|
profile_directory: Gebruikersgids inschakelen
|
||||||
registrations_mode: Wie kan zich registreren
|
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
|
require_invite_text: Opgeven van een reden is verplicht
|
||||||
show_domain_blocks: Domeinblokkades tonen
|
show_domain_blocks: Domeinblokkades tonen
|
||||||
show_domain_blocks_rationale: Redenen voor domeinblokkades tonen
|
show_domain_blocks_rationale: Redenen voor domeinblokkades tonen
|
||||||
|
|||||||
@@ -158,6 +158,10 @@ sq:
|
|||||||
name: Emër publik për rolin, nëse roli është ujdisur të shfaqet si një stemë
|
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ë…
|
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
|
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:
|
webhook:
|
||||||
events: Përzgjidhni akte për dërgim
|
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.
|
template: Hartoni ngarkesë tuajën JSON, duke përdorur ndërkëmbim ndryshoresh. Lëreni të zbrazët, për JSON-in parazgjedhje.
|
||||||
|
|||||||
@@ -1578,6 +1578,13 @@ sq:
|
|||||||
expires_at: Skadon më
|
expires_at: Skadon më
|
||||||
uses: Përdorime
|
uses: Përdorime
|
||||||
title: Ftoni njerëz
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Keni mbërritur në numrin maksimum të listave
|
limit: Keni mbërritur në numrin maksimum të listave
|
||||||
@@ -1888,6 +1895,9 @@ sq:
|
|||||||
other: "%{count} video"
|
other: "%{count} video"
|
||||||
boosted_from_html: Përforcuar nga %{acct_link}
|
boosted_from_html: Përforcuar nga %{acct_link}
|
||||||
content_warning: 'Sinjalizim lënde: %{warning}'
|
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
|
default_language: Njësoj me gjuhën e ndërfaqes
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'përmbante një hashtag të palejuar: %{tags}'
|
one: 'përmbante një hashtag të palejuar: %{tags}'
|
||||||
|
|||||||
@@ -1901,6 +1901,9 @@ tr:
|
|||||||
other: "%{count} videolar"
|
other: "%{count} videolar"
|
||||||
boosted_from_html: "%{acct_link} kişisinden yeniden paylaştı"
|
boosted_from_html: "%{acct_link} kişisinden yeniden paylaştı"
|
||||||
content_warning: 'İçerik uyarısı: %{warning}'
|
content_warning: 'İçerik uyarısı: %{warning}'
|
||||||
|
content_warnings:
|
||||||
|
hide: Gönderiyi gizle
|
||||||
|
show: Daha fazlasını göster
|
||||||
default_language: Arayüz diliyle aynı
|
default_language: Arayüz diliyle aynı
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
one: 'izin verilmeyen bir etiket içeriyordu: %{tags}'
|
one: 'izin verilmeyen bir etiket içeriyordu: %{tags}'
|
||||||
|
|||||||
@@ -1552,6 +1552,13 @@ vi:
|
|||||||
expires_at: Hết hạn
|
expires_at: Hết hạn
|
||||||
uses: Sử dụng
|
uses: Sử dụng
|
||||||
title: Mời bạn bè
|
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:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: Bạn đã đạt đến số lượng danh sách tối đa
|
limit: Bạn đã đạt đến số lượng danh sách tối đa
|
||||||
@@ -1859,6 +1866,9 @@ vi:
|
|||||||
other: "%{count} video"
|
other: "%{count} video"
|
||||||
boosted_from_html: Đã đăng lại từ %{acct_link}
|
boosted_from_html: Đã đăng lại từ %{acct_link}
|
||||||
content_warning: 'Cảnh báo nội dung: %{warning}'
|
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
|
default_language: Giống giao diện
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
other: 'chứa các hashtag bị cấm: %{tags}'
|
other: 'chứa các hashtag bị cấm: %{tags}'
|
||||||
|
|||||||
@@ -1552,6 +1552,13 @@ zh-CN:
|
|||||||
expires_at: 失效时间
|
expires_at: 失效时间
|
||||||
uses: 已使用次数
|
uses: 已使用次数
|
||||||
title: 邀请用户
|
title: 邀请用户
|
||||||
|
link_preview:
|
||||||
|
author_html: 来自 %{name}
|
||||||
|
potentially_sensitive_content:
|
||||||
|
action: 点击查看
|
||||||
|
confirm_visit: 您确定要打开此链接吗?
|
||||||
|
hide_button: 隐藏
|
||||||
|
label: 可能为敏感内容
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: 你已达到列表数量的上限
|
limit: 你已达到列表数量的上限
|
||||||
@@ -1859,6 +1866,9 @@ zh-CN:
|
|||||||
other: "%{count} 段视频"
|
other: "%{count} 段视频"
|
||||||
boosted_from_html: 转嘟自 %{acct_link}
|
boosted_from_html: 转嘟自 %{acct_link}
|
||||||
content_warning: 内容警告:%{warning}
|
content_warning: 内容警告:%{warning}
|
||||||
|
content_warnings:
|
||||||
|
hide: 隐藏嘟文
|
||||||
|
show: 显示更多
|
||||||
default_language: 与界面显示语言相同
|
default_language: 与界面显示语言相同
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
other: 包含以下被禁止的话题:%{tags}
|
other: 包含以下被禁止的话题:%{tags}
|
||||||
|
|||||||
@@ -1554,6 +1554,13 @@ zh-TW:
|
|||||||
expires_at: 失效時間
|
expires_at: 失效時間
|
||||||
uses: 已使用次數
|
uses: 已使用次數
|
||||||
title: 邀請使用者
|
title: 邀請使用者
|
||||||
|
link_preview:
|
||||||
|
author_html: 來自 %{name}
|
||||||
|
potentially_sensitive_content:
|
||||||
|
action: 點擊以顯示
|
||||||
|
confirm_visit: 您確定要開啟此連結嗎?
|
||||||
|
hide_button: 隱藏
|
||||||
|
label: 可能為敏感內容
|
||||||
lists:
|
lists:
|
||||||
errors:
|
errors:
|
||||||
limit: 您所建立之列表數量已達上限
|
limit: 您所建立之列表數量已達上限
|
||||||
@@ -1861,6 +1868,9 @@ zh-TW:
|
|||||||
other: "%{count} 段影片"
|
other: "%{count} 段影片"
|
||||||
boosted_from_html: 轉嘟自 %{acct_link}
|
boosted_from_html: 轉嘟自 %{acct_link}
|
||||||
content_warning: 內容警告: %{warning}
|
content_warning: 內容警告: %{warning}
|
||||||
|
content_warnings:
|
||||||
|
hide: 隱藏嘟文
|
||||||
|
show: 顯示更多
|
||||||
default_language: 與介面語言相同
|
default_language: 與介面語言相同
|
||||||
disallowed_hashtags:
|
disallowed_hashtags:
|
||||||
other: 含有不得使用的標籤: %{tags}
|
other: 含有不得使用的標籤: %{tags}
|
||||||
|
|||||||
@@ -165,14 +165,17 @@ module Mastodon::CLI
|
|||||||
user.role_id = nil
|
user.role_id = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
password = SecureRandom.hex if options[:reset_password]
|
|
||||||
user.password = password if options[:reset_password]
|
|
||||||
user.email = options[:email] if options[:email]
|
user.email = options[:email] if options[:email]
|
||||||
user.disabled = false if options[:enable]
|
user.disabled = false if options[:enable]
|
||||||
user.disabled = true if options[:disable]
|
user.disabled = true if options[:disable]
|
||||||
user.approved = true if options[:approve]
|
user.approved = true if options[:approve]
|
||||||
user.disable_two_factor! if options[:disable_2fa]
|
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
|
if user.save
|
||||||
user.confirm if options[:confirm]
|
user.confirm if options[:confirm]
|
||||||
|
|
||||||
|
|||||||
@@ -361,11 +361,20 @@ RSpec.describe Mastodon::CLI::Accounts do
|
|||||||
context 'with --reset-password option' do
|
context 'with --reset-password option' do
|
||||||
let(:options) { { reset_password: true } }
|
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
|
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 }
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -382,12 +382,15 @@ RSpec.describe User do
|
|||||||
|
|
||||||
let(:current_sign_in_at) { Time.zone.now }
|
let(:current_sign_in_at) { Time.zone.now }
|
||||||
|
|
||||||
before do
|
|
||||||
user.disable!
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'disables user' do
|
it 'disables user' do
|
||||||
|
allow(redis).to receive(:publish)
|
||||||
|
|
||||||
|
user.disable!
|
||||||
|
|
||||||
expect(user).to have_attributes(disabled: true)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
require 'debug'
|
|
||||||
|
|
||||||
RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do
|
RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do
|
||||||
let(:application) { Fabricate(:application, confidential: false) }
|
let(:application) { Fabricate(:application, confidential: false) }
|
||||||
@@ -15,6 +14,25 @@ RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do
|
|||||||
streaming_client.close
|
streaming_client.close
|
||||||
end
|
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
|
context 'when the access token has read scope' do
|
||||||
let(:scopes) { 'read' }
|
let(:scopes) { 'read' }
|
||||||
|
|
||||||
@@ -39,11 +57,52 @@ RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context 'when the access token cannot read notifications' do
|
context 'when the access token has read:statuses scope' do
|
||||||
let(:scopes) { 'read:statuses' }
|
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
|
it 'cannot subscribing to the user:notifications channel' do
|
||||||
streaming_client.authenticate(access_token.token)
|
streaming_client.authenticate(access_token.token)
|
||||||
|
|
||||||
@@ -59,4 +118,27 @@ RSpec.describe 'Channel Subscriptions', :inline_jobs, :streaming do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|||||||
@@ -74,4 +74,28 @@ RSpec.describe 'Streaming', :inline_jobs, :streaming do
|
|||||||
expect(streaming_client.open?).to be(false)
|
expect(streaming_client.open?).to be(false)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|||||||
@@ -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
|
// Used for priming the counters/gauges for the various metrics that are
|
||||||
// per-channel
|
// per-channel
|
||||||
const CHANNEL_NAMES = [
|
const CHANNEL_NAMES = [
|
||||||
@@ -97,7 +86,14 @@ const CHANNEL_NAMES = [
|
|||||||
'user:notification',
|
'user:notification',
|
||||||
'list',
|
'list',
|
||||||
'direct',
|
'direct',
|
||||||
...PUBLIC_CHANNELS
|
'public',
|
||||||
|
'public:media',
|
||||||
|
'public:local',
|
||||||
|
'public:local:media',
|
||||||
|
'public:remote',
|
||||||
|
'public:remote:media',
|
||||||
|
'hashtag',
|
||||||
|
'hashtag:local',
|
||||||
];
|
];
|
||||||
|
|
||||||
const startServer = async () => {
|
const startServer = async () => {
|
||||||
@@ -355,7 +351,7 @@ const startServer = async () => {
|
|||||||
* @returns {Promise<ResolvedAccount>}
|
* @returns {Promise<ResolvedAccount>}
|
||||||
*/
|
*/
|
||||||
const accountFromToken = async (token, req) => {
|
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) {
|
if (result.rows.length === 0) {
|
||||||
throw new AuthenticationError('Invalid access token');
|
throw new AuthenticationError('Invalid access token');
|
||||||
@@ -434,12 +430,6 @@ const startServer = async () => {
|
|||||||
const checkScopes = (req, logger, channelName) => new Promise((resolve, reject) => {
|
const checkScopes = (req, logger, channelName) => new Promise((resolve, reject) => {
|
||||||
logger.debug(`Checking OAuth scopes for ${channelName}`);
|
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
|
// The `read` scope has the highest priority, if the token has it
|
||||||
// then it can access all streams
|
// then it can access all streams
|
||||||
const requiredScopes = ['read'];
|
const requiredScopes = ['read'];
|
||||||
|
|||||||
Reference in New Issue
Block a user