From 17ba5e1e616c853a389b9c24a347d873747f2126 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 4 Jun 2022 06:44:49 +0200 Subject: New Crowdin updates (#18561) * New translations en.yml (Portuguese) * New translations en.yml (Lithuanian) * New translations en.yml (Serbian (Cyrillic)) * New translations en.yml (Turkish) * New translations en.yml (Ukrainian) * New translations en.yml (Chinese Traditional) * New translations en.yml (Urdu (Pakistan)) * New translations en.yml (Icelandic) * New translations en.yml (Portuguese, Brazilian) * New translations en.yml (Indonesian) * New translations en.yml (Tamil) * New translations en.yml (Macedonian) * New translations en.yml (Korean) * New translations en.yml (Georgian) * New translations en.yml (Slovak) * New translations en.yml (Chinese Simplified) * New translations en.yml (Swedish) * New translations en.yml (Hebrew) * New translations en.yml (Italian) * New translations en.yml (Japanese) * New translations en.yml (Russian) * New translations en.yml (Slovenian) * New translations en.yml (Armenian) * New translations en.yml (Vietnamese) * New translations en.yml (Scottish Gaelic) * New translations en.yml (Occitan) * New translations en.yml (Persian) * New translations en.yml (Galician) * New translations en.yml (Hungarian) * New translations en.yml (Spanish, Argentina) * New translations en.yml (Irish) * New translations en.json (Arabic) * New translations en.json (Irish) * New translations en.json (German) * New translations en.yml (Spanish, Mexico) * New translations en.json (Turkish) * New translations en.yml (Kabyle) * New translations en.yml (Ido) * New translations en.yml (Taigi) * New translations en.yml (Silesian) * New translations en.yml (Standard Moroccan Tamazight) * New translations en.json (Japanese) * New translations en.json (Korean) * New translations en.json (Vietnamese) * New translations en.json (Chinese Simplified) * New translations en.yml (Sardinian) * New translations en.json (Portuguese, Brazilian) * New translations en.json (Asturian) * New translations en.json (Scottish Gaelic) * New translations en.json (Welsh) * New translations en.json (Galician) * New translations en.json (Slovak) * New translations en.json (Icelandic) * New translations en.yml (Sanskrit) * New translations en.yml (Corsican) * New translations en.yml (Bengali) * New translations en.yml (Esperanto) * New translations en.yml (Marathi) * New translations en.yml (Croatian) * New translations en.yml (Norwegian Nynorsk) * New translations en.yml (Kazakh) * New translations en.yml (Estonian) * New translations en.yml (Latvian) * New translations en.yml (Hindi) * New translations en.yml (Malay) * New translations en.yml (Telugu) * New translations en.yml (Welsh) * New translations en.yml (Uyghur) * New translations en.yml (Sorani (Kurdish)) * New translations en.yml (Chinese Traditional, Hong Kong) * New translations en.yml (Tatar) * New translations en.yml (Malayalam) * New translations en.yml (Breton) * New translations en.yml (Sinhala) * New translations en.yml (Cornish) * New translations en.yml (Kannada) * New translations en.yml (Asturian) * New translations en.yml (Serbian (Latin)) * New translations en.yml (Kurmanji (Kurdish)) * New translations en.json (Sorani (Kurdish)) * New translations en.json (Greek) * New translations en.json (Romanian) * New translations en.json (French) * New translations en.json (Spanish) * New translations en.json (Afrikaans) * New translations en.json (Bulgarian) * New translations en.json (Czech) * New translations en.json (Danish) * New translations en.json (Basque) * New translations en.json (Finnish) * New translations en.json (Hebrew) * New translations en.json (Spanish, Mexico) * New translations en.json (Marathi) * New translations en.json (Bengali) * New translations en.json (English, United Kingdom) * New translations en.json (Spanish, Argentina) * New translations en.json (Tamil) * New translations en.json (Croatian) * New translations en.json (Persian) * New translations en.json (Thai) * New translations en.json (Malay) * New translations en.json (Norwegian Nynorsk) * New translations en.json (Kazakh) * New translations en.json (Estonian) * New translations en.json (Latvian) * New translations en.json (Hindi) * New translations en.json (Urdu (Pakistan)) * New translations en.json (Telugu) * New translations en.json (Esperanto) * New translations en.json (Indonesian) * New translations en.json (Slovenian) * New translations en.json (Chinese Traditional) * New translations en.json (Dutch) * New translations en.json (Norwegian) * New translations en.json (Hungarian) * New translations en.json (Armenian) * New translations en.json (Italian) * New translations en.json (Georgian) * New translations en.json (Lithuanian) * New translations en.json (Macedonian) * New translations en.json (Punjabi) * New translations en.json (Ukrainian) * New translations en.json (Polish) * New translations en.json (Portuguese) * New translations en.json (Russian) * New translations en.yml (English, United Kingdom) * New translations en.json (Albanian) * New translations en.json (Serbian (Cyrillic)) * New translations en.json (Swedish) * New translations en.json (Uyghur) * New translations en.json (Chinese Traditional, Hong Kong) * New translations en.json (Corsican) * New translations en.json (Silesian) * New translations en.json (Taigi) * New translations en.json (Ido) * New translations en.json (Kabyle) * New translations en.json (Sanskrit) * New translations en.json (Sardinian) * New translations en.json (Kurmanji (Kurdish)) * New translations en.json (Tatar) * New translations en.json (Serbian (Latin)) * New translations en.json (Occitan) * New translations en.json (Kannada) * New translations en.json (Cornish) * New translations en.json (Sinhala) * New translations en.json (Breton) * New translations en.json (Malayalam) * New translations en.json (Standard Moroccan Tamazight) * New translations en.json (Spanish, Argentina) * New translations en.json (Galician) * New translations en.json (Chinese Traditional) * New translations en.json (Greek) * New translations en.json (Swedish) * New translations en.json (Russian) * New translations en.json (Chinese Simplified) * New translations en.json (Catalan) * New translations en.json (Polish) * New translations en.json (Latvian) * New translations en.yml (Turkish) * New translations en.json (Turkish) * New translations en.json (Czech) * New translations en.json (Slovenian) * New translations en.json (Icelandic) * New translations en.json (Hungarian) * New translations en.json (Italian) * New translations en.json (Vietnamese) * New translations en.yml (Russian) * New translations doorkeeper.en.yml (Russian) * New translations en.yml (Japanese) * New translations en.json (Japanese) * New translations en.json (Danish) * New translations en.json (Dutch) * New translations en.json (Portuguese) * New translations en.json (Frisian) * New translations en.yml (Frisian) * New translations simple_form.en.yml (Frisian) * New translations activerecord.en.yml (Frisian) * New translations devise.en.yml (Frisian) * New translations doorkeeper.en.yml (Frisian) * New translations en.json (Frisian) * New translations en.yml (Breton) * New translations en.json (Breton) * New translations en.yml (Polish) * New translations en.yml (Russian) * New translations en.yml (Catalan) * New translations en.yml (Korean) * New translations en.yml (Spanish, Argentina) * New translations en.json (Korean) * New translations en.yml (Greek) * New translations en.yml (Kurmanji (Kurdish)) * New translations en.yml (Ukrainian) * New translations en.yml (Czech) * New translations en.json (Ukrainian) * New translations en.yml (Icelandic) * New translations en.yml (Portuguese) * New translations en.yml (Latvian) * New translations en.yml (Hungarian) * New translations en.json (Irish) * New translations en.json (Irish) * New translations en.json (Irish) * New translations en.yml (Czech) * New translations en.yml (Danish) * New translations en.yml (Chinese Traditional) * New translations en.yml (Galician) * New translations en.yml (Galician) * New translations simple_form.en.yml (Galician) * New translations en.json (Frisian) * New translations en.json (Frisian) * New translations en.json (Frisian) * New translations en.json (Frisian) * New translations en.yml (Frisian) * New translations en.json (Frisian) * New translations en.yml (Frisian) * New translations activerecord.en.yml (Frisian) * New translations activerecord.en.yml (Frisian) * New translations en.json (Frisian) * New translations devise.en.yml (Frisian) * New translations doorkeeper.en.yml (Frisian) * New translations en.json (Frisian) * New translations en.yml (Frisian) * New translations en.yml (Slovenian) * New translations en.json (Frisian) * New translations en.yml (Frisian) * New translations doorkeeper.en.yml (Frisian) * New translations en.json (Frisian) * New translations en.yml (Frisian) * New translations simple_form.en.yml (Frisian) * New translations en.json (Frisian) * New translations en.yml (Frisian) * New translations en.json (Frisian) * New translations en.json (Frisian) * New translations en.json (Frisian) * New translations en.json (Frisian) * New translations en.yml (Indonesian) * New translations en.json (Indonesian) * New translations en.json (Spanish) * New translations en.yml (Spanish) * New translations en.yml (Italian) * New translations en.yml (Ido) * New translations en.json (Ido) * New translations en.json (French) * New translations en.yml (Korean) * New translations simple_form.en.yml (Korean) * New translations simple_form.en.yml (Korean) * New translations en.yml (Russian) * New translations en.yml (Russian) * Run `yarn manage:translations` * Run `bundle exec i18n-tasks normalize` * Fix default message Co-authored-by: Yamagishi Kazutoshi --- config/locales/activerecord.fy.yml | 24 ++++++++++ config/locales/br.yml | 5 +++ config/locales/ca.yml | 1 + config/locales/cs.yml | 29 ++++++------ config/locales/da.yml | 1 + config/locales/de.yml | 49 +++++++++++++++++++++ config/locales/devise.fy.yml | 7 +++ config/locales/doorkeeper.fy.yml | 23 ++++++++++ config/locales/doorkeeper.ru.yml | 1 + config/locales/el.yml | 1 + config/locales/es-AR.yml | 1 + config/locales/es-MX.yml | 48 ++++++++++++++++++++ config/locales/es.yml | 1 + config/locales/fy.yml | 54 +++++++++++++++++++++++ config/locales/gl.yml | 49 +++++++++++++++++++++ config/locales/hu.yml | 1 + config/locales/id.yml | 1 + config/locales/io.yml | 1 + config/locales/is.yml | 1 + config/locales/it.yml | 1 + config/locales/ja.yml | 81 ++++++++++++++++++++++++++++++++++ config/locales/ko.yml | 90 ++++++++++++++++++++++++++++++++++++-- config/locales/ku.yml | 1 + config/locales/lv.yml | 1 + config/locales/pl.yml | 1 + config/locales/pt-PT.yml | 1 + config/locales/ru.yml | 11 +++++ config/locales/simple_form.fy.yml | 6 +++ config/locales/simple_form.ko.yml | 6 +-- config/locales/sl.yml | 1 + config/locales/th.yml | 1 + config/locales/tr.yml | 80 +++++++++++++++++++++++++++++++++ config/locales/uk.yml | 1 + config/locales/zh-TW.yml | 1 + 34 files changed, 560 insertions(+), 21 deletions(-) create mode 100644 config/locales/activerecord.fy.yml create mode 100644 config/locales/devise.fy.yml create mode 100644 config/locales/doorkeeper.fy.yml create mode 100644 config/locales/fy.yml create mode 100644 config/locales/simple_form.fy.yml (limited to 'config') diff --git a/config/locales/activerecord.fy.yml b/config/locales/activerecord.fy.yml new file mode 100644 index 000000000..a3398cfba --- /dev/null +++ b/config/locales/activerecord.fy.yml @@ -0,0 +1,24 @@ +--- +fy: + activerecord: + attributes: + poll: + options: Karren + user: + email: E-mailadres + locale: Taal + password: Wachtwurd + user/account: + username: Brûkersnamme + user/invite_request: + text: Reden + errors: + models: + account: + attributes: + username: + invalid: mei allinnich letters, nûmers en ûnderstreekjes befetsje + user: + attributes: + email: + unreachable: liket net te bestean diff --git a/config/locales/br.yml b/config/locales/br.yml index 07e12a531..f7c060579 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -10,6 +10,8 @@ br: discover_users: Dizoleiñ implijer·ien·ezed learn_more: Gouzout hiroc'h privacy_policy: Reolennoù prevezded + rules: Reolennoù ar servijer + server_stats: 'Stadegoù ar servijer:' source_code: Boneg tarzh status_count_after: few: toud @@ -36,6 +38,7 @@ br: other: Heulier·ez two: Heulier·ez following: O heuliañ + media: Media posts: few: Toud many: Toud @@ -52,6 +55,7 @@ br: unfollow: Diheuliañ admin: accounts: + avatar: Avatar by_domain: Domani change_email: current_email: Postel bremanel @@ -60,6 +64,7 @@ br: submit: Kemm ar postel deleted: Dilamet domain: Domani + edit: Aozañ email: Postel enable: Gweredekaat enabled: Gweredekaet diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 461d27fa3..f0efd3f50 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -428,6 +428,7 @@ ca: destroyed_msg: El bloqueig de domini s'ha desfet domain: Domini edit: Editar el bloqueig del domini + existing_domain_block: Ja s'han imposat mesures més estrictes a %{name}. existing_domain_block_html: Ja has imposat uns límits més estrictes a %{name}, l'hauries de desbloquejar-lo primer. new: create: Crea un bloqueig diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 9244ddeac..0140d4127 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -76,7 +76,7 @@ cs: last_active: naposledy aktivní link_verified_on: Vlastnictví tohoto odkazu bylo zkontrolováno %{date} media: Média - moved_html: "%{name} se přesunul a na %{new_profile_link}:" + moved_html: 'Uživatel %{name} se přesunul na %{new_profile_link}:' network_hidden: Tato informace není k dispozici nothing_here: Nic tu není! people_followed_by: Lidé, které sleduje %{name} @@ -209,8 +209,8 @@ cs: security_measures: only_password: Pouze heslo password_and_2fa: Heslo a 2FA - sensitive: Citlivý - sensitized: označen jako citlivý + sensitive: Vynutit citlivost + sensitized: Označen jako citlivý shared_inbox_url: URL sdílené příchozí schránky show: created_reports: Vytvořená hlášení @@ -228,10 +228,10 @@ cs: unblock_email: Odblokovat e-mailovou adresu unblocked_email_msg: E-mailová adresa %{username} byla úspěšně odblokována unconfirmed_email: Nepotvrzený e-mail - undo_sensitized: Vrátit zpět citlivost + undo_sensitized: Zrušit vynucení citlivosti undo_silenced: Zrušit omezení undo_suspension: Zrušit pozastavení - unsilenced_msg: Omezení účtu %{username} úspěšně odstraněno + unsilenced_msg: Omezení účtu %{username} úspěšně zrušeno unsubscribe: Přestat odebírat unsuspended_msg: Úspěšně obnoven účet %{username} username: Uživatelské jméno @@ -279,12 +279,12 @@ cs: reopen_report: Znovu otevřít hlášení reset_password_user: Obnovit heslo resolve_report: Označit hlášení jako vyřešené - sensitive_account: Označit média ve vašem účtu jako citlivá + sensitive_account: Vynucení citlivosti účtu silence_account: Omezit účet suspend_account: Pozastavit účet unassigned_report: Zrušit přiřazení hlášení unblock_email_account: Odblokovat e-mailovou adresu - unsensitive_account: Zrušit označení médií ve vašem účtu jako citlivých + unsensitive_account: Zrušit vynucení citlivosti účtu unsilence_account: Zrušit omezení účtu unsuspend_account: Zrušit pozastavení účtu update_announcement: Aktualizovat oznámení @@ -331,12 +331,12 @@ cs: reset_password_user_html: Uživatel %{name} obnovil heslo uživatele %{target} resolve_report_html: Uživatel %{name} vyřešil hlášení %{target} sensitive_account_html: "%{name} označil média účtu %{target} jako citlivá" - silence_account_html: Uživatel %{name} ztišil uživatele %{target} + silence_account_html: Uživatel %{name} omezil účet %{target} suspend_account_html: Uživatel %{name} pozastavil účet uživatele %{target} unassigned_report_html: Uživatel %{name} odebral hlášení %{target} unblock_email_account_html: Uživatel %{name} odblokoval e-mailovou adresu %{target} unsensitive_account_html: "%{name} zrušil označení médií účtu %{target} jako citlivých" - unsilence_account_html: Uživatel %{name} zrušil ztišení uživatele %{target} + unsilence_account_html: Uživatel %{name} zrušil omezení účtu %{target} unsuspend_account_html: Uživatel %{name} zrušil pozastavení účtu uživatele %{target} update_announcement_html: Uživatel %{name} aktualizoval oznámení %{target} update_custom_emoji_html: Uživatel %{name} aktualizoval emoji %{target} @@ -443,10 +443,11 @@ cs: domain_blocks: add_new: Přidat novou blokaci domény created_msg: Blokace domény se právě vyřizuje - destroyed_msg: Blokace domény byla vrácena + destroyed_msg: Blokace domény byla odvolána domain: Doména edit: Upravit blokaci domény - existing_domain_block_html: Pro účet %{name} jste už nastavili přísnější omezení, nejprve jej odblokujte. + existing_domain_block: Pro %{name} už jste nastavili přísnější omezení. + existing_domain_block_html: Pro %{name} už jste nastavili přísnější omezení, nejprve ji odblokujte. new: create: Vytvořit blokaci hint: Blokace domény nezakáže vytváření záznamů účtů v databázi, ale bude na tyto účty zpětně a automaticky aplikovat specifické metody moderování. @@ -466,7 +467,7 @@ cs: reject_media_hint: Odstraní lokálně uložené mediální soubory a odmítne jejich stahování v budoucnosti. Nepodstatné pro pozastavení reject_reports: Odmítat hlášení reject_reports_hint: Ignorovat všechna hlášení pocházející z této domény. Nepodstatné pro pozastavení - undo: Vrátit blokaci domény + undo: Odvolat blokaci domény view: Zobrazit blokaci domény email_domain_blocks: add_new: Přidat @@ -1332,7 +1333,7 @@ cs: code_hint: Pro potvrzení zadejte kód vygenerovaný Vaší ověřovací aplikací description_html: Zapnete-li dvoufázové ověřování pomocí ověřovací aplikace, k přihlášení budete u sebe muset mít svůj mobil, který pro Vás bude generovat kódy k opsání. enable: Zapnout - instructions_html: "Naskenujte tento QR kód do Google Authenticator nebo podobné TOTP aplikace na Vašem telefonu. Následně bude tato aplikace generovat kódy, které budete zadávat při přihlašování." + instructions_html: "Naskenujte tento QR kód do Google Authenticator nebo podobné TOTP aplikace na svém telefonu. Následně bude tato aplikace generovat kódy, které budete zadávat při přihlašování." manual_instructions: 'Nemůžete-li načíst QR kód a potřebujete ho zadat ručně, zde je tajemství v textové podobě:' setup: Nastavit wrong_code: Zadaný kód je neplatný! Je čas na serveru i zařízení generujícím kód správný? @@ -1404,7 +1405,7 @@ cs: account: Veřejné příspěvky od @%{acct} tag: 'Veřejné příspěvky s hashtagem #%{hashtag}' scheduled_statuses: - over_daily_limit: Překročili jste limit %{limit} příspěvků naplánovaných na tento den + over_daily_limit: Pro dnešek jste překročili limit %{limit} naplánovaných příspěvků over_total_limit: Překročili jste limit %{limit} naplánovaných příspěvků too_soon: Plánované datum musí být v budoucnosti sessions: diff --git a/config/locales/da.yml b/config/locales/da.yml index b1c26b68b..0195aa5a3 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -428,6 +428,7 @@ da: destroyed_msg: Domæneblokering er blevet fjernet domain: Domæne edit: Redigér domæneblokering + existing_domain_block: "%{name} er allerede pålagt strengere restriktioner." existing_domain_block_html: Der har allerede pålagt %{name} strengere begrænsninger, så dette kræver først en afblokering. new: create: Opret blokering diff --git a/config/locales/de.yml b/config/locales/de.yml index abe988a98..a52841a39 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1525,6 +1525,55 @@ de: tags: does_not_match_previous_name: entspricht nicht dem vorherigen Namen terms: + body_html: | +

Datenschutzerklärung

+

Welche Informationen sammeln wir?

+ +
+

Für was verwenden wir deine Informationen?

+

Jede der von dir gesammelten Information kann in den folgenden Weisen verwendet werden:

+ +
+

Wie beschützen wir deine Informationen?

+

Wir implementieren eine Reihe von Sicherheitsmaßnahmen, um die Sicherheit deiner persönlichen Information sicherzustellen, wenn du persönliche Informationen eingibst, übermittelst oder auf sie zugreifst. Neben anderen Dingen, wird sowohl deine Browsersitzung, als auch der Datenverkehr zwischen deinen Anwendungen und der Programmierschnittstelle (API) mit SSL gesichert, dein Passwort wird mit einem starken Einwegalgorithmus gehasht. Du kannst Zwei-Faktor-Authentifizierung aktivieren, um den Zugriff auf dein Konto zusätzlich abzusichern.

+
+

Was ist unsere Datenspeicherungsrichtlinie?

+

Wir werden mit bestem Wissen und Gewissen:

+ +

Du kannst ein Archiv deines Inhalts anfordern und herunterladen, inkludierend deiner Beiträge, Medienanhänge, Profilbilder und Headerbilder.

+

Es ist in den meisten Fällen möglich dein Konto jederzeit eigenmächtig unwiderruflich zu löschen.

+
+

Verwenden wir Cookies?

+

Ja. Cookies sind kleine Dateien, die eine Webseite oder ihr Serviceanbieter über deinen Webbrowser (sofern er es erlaubt) auf die Festplatte deines Computers überträgt. Diese Cookies ermöglichen es der Seite deinen Browser wiederzuerkennen und, sofern du ein registriertes Konto hast, diesen mit deinem registrierten Konto zu verknüpfen.

+

Wir verwenden Cookies, um deine Einstellungen zu verstehen und für zukünftige Besuche zu speichern.

+
+

Offenbaren wir Informationen an Dritte?

+

Wir verkaufen nicht, handeln nicht mit oder übertragen deine persönlich identifizierbaren Informationen nicht an Dritte. Dies beinhaltet nicht Dritte, die vertrauenswürdig sind und uns beim Betreiben unserer Seite, Leiten unseres Geschäftes oder dabei, die Dienste für dich bereitzustellen, unterstützen, sofern diese Dritte zustimmen, diese Informationen vertraulich zu halten. Wir können auch Informationen freigeben, wenn wir glauben, dass Freigabe angemessen ist, um dem Gesetz zu entsprechen, unsere Seitenrichtlinien durchzusetzen oder unsere Rechte, Eigentum und/oder Sicherheit oder die anderer zu beschützen.

+

Dein öffentlicher Inhalt kann durch andere Server im Netzwerk heruntergeladen werden. Deine öffentlichen und "Nur Folgende"-Beiträge werden an die Server ausgeliefert, bei denen sich deine Folgenden befinden und direkte Nachrichten werden an die Server des Empfängers ausgeliefert, falls diese Folgenden oder Empfänger sich auf einem anderen Server als diesen befinden.

+

Wenn du eine Anwendung autorisierst, dein Konto zu benutzen, kann diese – abhängig von den von dir genehmigten Befugnissen – auf deine öffentlichen Profilinformationen, deine Folgt- und Folgende-Liste, deine Listen, alle deine Beiträge und deine Favoriten zugreifen. Anwendungen können nie auf deine E-Mail-Adresse oder dein Passwort zugreifen

+
+

Webseitenbenutzung durch Kinder

+

Wenn sich dieser Server in der EU oder im Europäischen Wirtschaftsraum befindet: Unsere Website, Produkte und Dienstleistungen sind alle an Leute gerichtet, die mindestens 16 Jahre als sind. Wenn du unter 16 bist, darfst du nach den Bestimmungen der DSGVO (Datenschutz-Grundverordnung) diese Webseite nicht benutzen.

+

Wenn sich dieser Server in den USA befindet: Unsere Webseite, Produkte und Dienstleistungen sind alle an Leute gerichtet, die mindestens 13 Jahre alt sind. Wenn du unter 13 bist, darfst du nach den Bestimmungen des COPPA (Children's Online Privacy Protection Act, dt. "Gesetz zum Schutz der Privatsphäre von Kindern im Internet") diese Webseite nicht benutzen.

+

Gesetzesvorschriften können unterschiedlich sein, wenn sich dieser Server in anderer Gerichtsbarkeit befindet.

+
+

Änderung an unserer Datenschutzerklärung

+

Wenn wir uns entscheiden, Änderungen an unserer Datenschutzerklärung vorzunehmen, werden wir diese Änderungen auf dieser Seite bekannt gegeben.

+

Dies ist eine Übersetzung, Irrtümer und Übersetzungsfehler vorbehalten. Im Zweifelsfall gilt die englische Originalversion.

+

Dieses Dokument ist CC-BY-SA. Es wurde zuletzt aktualisiert am 26. Mai 2022.

+

Ursprünglich übernommen von der Discourse-Datenschutzerklärung.

title: "%{instance} Nutzungsbedingungen und Datenschutzerklärung" themes: contrast: Mastodon (Hoher Kontrast) diff --git a/config/locales/devise.fy.yml b/config/locales/devise.fy.yml new file mode 100644 index 000000000..e96c4089d --- /dev/null +++ b/config/locales/devise.fy.yml @@ -0,0 +1,7 @@ +--- +fy: + devise: + failure: + inactive: Jo account is not net aktivearre. + passwords: + updated_not_active: Jo wachtwurd is mei sukses feroare. diff --git a/config/locales/doorkeeper.fy.yml b/config/locales/doorkeeper.fy.yml new file mode 100644 index 000000000..385274868 --- /dev/null +++ b/config/locales/doorkeeper.fy.yml @@ -0,0 +1,23 @@ +--- +fy: + activerecord: + attributes: + doorkeeper/application: + name: Namme fan applikaasje + website: Webstee fan applikaasje + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: mei gjin fragmint befetsje. + invalid_uri: moat in jildige URI wêze. + relative_uri: moat in absolute URI wêze. + secured_uri: moat in HTTPS/SSL URI wêze. + doorkeeper: + grouped_scopes: + title: + conversations: Petearen + scopes: + write:conversations: petearen negearre en fuortsmite + write:mutes: minsken en petearen negearre diff --git a/config/locales/doorkeeper.ru.yml b/config/locales/doorkeeper.ru.yml index ff0e48720..7f4cca82b 100644 --- a/config/locales/doorkeeper.ru.yml +++ b/config/locales/doorkeeper.ru.yml @@ -76,6 +76,7 @@ ru: last_used_at: Последнее использование %{date} never_used: Не использовалось scopes: Разрешения + superapp: Внутреннее title: Ваши авторизованные приложения errors: messages: diff --git a/config/locales/el.yml b/config/locales/el.yml index 47f7097e8..1320dcbb4 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -340,6 +340,7 @@ el: destroyed_msg: Ο αποκλεισμός τομέα άρθηκε domain: Τομέας edit: Διαχείρηση αποκλεισμένου τομέα + existing_domain_block: Έχετε ήδη επιβάλει αυστηρότερα όρια στο %{name}. existing_domain_block_html: Έχεις ήδη επιβάλλει αυστηρότερους περιορισμούς στο %{name}, πρώτα θα πρέπει να τους αναιρέσεις. new: create: Δημιουργία αποκλεισμού diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index b01f983b0..aeba0b97d 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -428,6 +428,7 @@ es-AR: destroyed_msg: Se deshizo el bloqueo de dominio domain: Dominio edit: Editar bloqueo de dominio + existing_domain_block: Ya impusiste límites más estrictos a %{name}. existing_domain_block_html: Ya le aplicaste límites más estrictos a %{name}, por lo que primero necesitás desbloquearlo. new: create: Crear bloqueo diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index f396d6138..5f9a9f5e7 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -1525,6 +1525,54 @@ es-MX: tags: does_not_match_previous_name: no coincide con el nombre anterior terms: + body_html: | +

Política de Privacidad

+

¿Qué información recogemos?

+ +
+

¿Para qué utilizamos su información?

+

Toda la información que obtenemos de usted puede ser utilizada de las siguientes maneras:

+ +
+

¿Cómo protegemos su información?

+

Implementamos una variedad de medidas de seguridad para mantener la seguridad de su información personal cuando usted ingresa, envía o accede a su información personal. Entre otras cosas, la sesión de su navegador, así como el tráfico entre sus aplicaciones y la API, están protegidos con SSL, y su contraseña está protegida mediante un algoritmo unidireccional fuerte. Puede habilitar la autenticación de dos factores para un acceso más seguro a su cuenta.

+
+

¿Cuál es nuestra política de retención de datos?

+

Haremos un esfuerzo de buena fe para:

+ +

Puede solicitar y descargar un archivo de su contenido, incluidos sus mensajes, archivos adjuntos multimedia, foto de perfil e imagen de cabecera.

+

Usted puede borrar su cuenta de forma irreversible en cualquier momento.

+
+

¿Utilizamos cookies?

+

Sí. Las cookies son pequeños archivos que un sitio o su proveedor de servicios transfiere al disco duro de su ordenador a través de su navegador web (si usted lo permite). Estas cookies permiten al sitio reconocer su navegador y, si tiene una cuenta registrada, asociarla con su cuenta registrada.

+

Utilizamos cookies para entender y guardar sus preferencias para futuras visitas.

+
+

¿Revelamos alguna información a terceros?

+

No vendemos, comerciamos ni transferimos a terceros su información personal identificable. Esto no incluye a los terceros de confianza que nos asisten en la operación de nuestro sitio, en la realización de nuestros negocios o en la prestación de servicios, siempre y cuando dichas partes acuerden mantener la confidencialidad de esta información. También podemos divulgar su información cuando creamos que es apropiado para cumplir con la ley, hacer cumplir las políticas de nuestro sitio, o proteger nuestros u otros derechos, propiedad o seguridad.

+

Su contenido público puede ser descargado por otros servidores de la red. Tus mensajes públicos y sólo para seguidores se envían a los servidores donde residen tus seguidores, y los mensajes directos se envían a los servidores de los destinatarios, en la medida en que dichos seguidores o destinatarios residan en un servidor diferente.

+

Cuando usted autoriza a una aplicación a usar su cuenta, dependiendo del alcance de los permisos que usted apruebe, puede acceder a la información de su perfil público, su lista de seguimiento, sus seguidores, sus listas, todos sus mensajes y sus favoritos. Las aplicaciones nunca podrán acceder a su dirección de correo electrónico o contraseña.

+
+

Uso del sitio por parte de los niños

+

Si este servidor está en la UE o en el EEE: Nuestro sitio, productos y servicios están dirigidos a personas mayores de 16 años. Si es menor de 16 años, según los requisitos de la GDPR (General Data Protection Regulation) no utilice este sitio.

+

Si este servidor está en los EE.UU.: Nuestro sitio, productos y servicios están todos dirigidos a personas que tienen al menos 13 años de edad. Si usted es menor de 13 años, según los requisitos de COPPA (Children's Online Privacy Protection Act) no utilice este sitio.

+

Los requisitos legales pueden ser diferentes si este servidor está en otra jurisdicción.

+
+

Cambios en nuestra Política de Privacidad

+

Si decidimos cambiar nuestra política de privacidad, publicaremos esos cambios en esta página.

+

Este documento es CC-BY-SA. Fue actualizado por última vez el 26 de mayo de 2022.

+

Adaptado originalmente desde la política de privacidad de Discourse.

title: Términos del Servicio y Políticas de Privacidad de %{instance} themes: contrast: Alto contraste diff --git a/config/locales/es.yml b/config/locales/es.yml index fcab7856a..900193134 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -428,6 +428,7 @@ es: destroyed_msg: El bloque de dominio se deshizo domain: Dominio edit: Editar nuevo dominio bloqueado + existing_domain_block: Ya impusiste límites más estrictos a %{name}. existing_domain_block_html: Ya ha impuesto límites más estrictos a %{name}, necesita desbloquearlo primero. new: create: Crear bloque diff --git a/config/locales/fy.yml b/config/locales/fy.yml new file mode 100644 index 000000000..fa727d6fe --- /dev/null +++ b/config/locales/fy.yml @@ -0,0 +1,54 @@ +--- +fy: + about: + active_count_after: warber + active_footnote: Moanliks Warbere Brûkers (MWB) + accounts: + last_active: letst warber + admin: + accounts: + moderation: + active: Aktyf + security_measures: + only_password: Allinnich wachtwurd + password_and_2fa: Wachtwurd en 2FA + dashboard: + active_users: warbere brûkers + top_languages: Meast aktive talen + top_servers: Meast aktive tsjinners + instances: + confirm_purge: Wolle jo werklik alle gegevens fan dit domein foar ivich fuortsmite? + dashboard: + instance_accounts_measure: bewarre accounts + system_checks: + database_schema_check: + message_html: Der binne database migraasjes yn ôfwachting. Jo moatte dizze útfiere om der foar te soargjen dat de applikaasje wurkjen bliuwt sa as it heard + errors: + '400': The request you submitted was invalid or malformed. + '403': You don't have permission to view this page. + '404': The page you are looking for isn't here. + '406': This page is not available in the requested format. + '410': The page you were looking for doesn't exist here anymore. + '422': + '429': Too many requests + '500': + '503': The page could not be served due to a temporary server failure. + filters: + contexts: + thread: Petearen + notification_mailer: + digest: + mention: "%{name} hat jo fermeld yn:" + mention: + action: Beäntwurdzje + body: 'Jo binne fermeld troch %{name} yn:' + subject: Jo binne fermeld troch %{name} + title: Nije fermelding + relationships: + last_active: Letst warber + rss: + content_warning: 'Ynhâldswarskôging:' + statuses: + content_warning: 'Ynhâldswarskôging: %{warning}' + pin_errors: + direct: Berjochten dy allinnich sichtber binne foar fermelde brûkers kinne net fêstset wurde diff --git a/config/locales/gl.yml b/config/locales/gl.yml index ba3084f90..48435b45b 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -428,6 +428,7 @@ gl: destroyed_msg: Desfíxose o bloqueo de dominio domain: Dominio edit: Editar bloqueo de dominio + existing_domain_block: Xa tes establecidas restricións maiores para %{name}. existing_domain_block_html: Xa impuxeches límites máis estrictos a %{name}, precisas desbloquealo primeiro. new: create: Crear bloqueo @@ -1525,6 +1526,54 @@ gl: tags: does_not_match_previous_name: non concorda co nome anterior terms: + body_html: | +

Privacidade

+

Que información recollemos?

+ +
+

De que xeito utilizamos os teus datos?

+

Toda a información que recollemos podería ser utilizada dos seguintes xeitos:

+ +
+

Como proxetemos os teus datos?

+

Implementamos varias medidas de seguridade para protexer os teus datos persoais cando introduces, envías ou accedes á túa información persoal. Entre outras medidas, a túa sesión de navegación, así como o tráfico entre as túas aplicacións e o API están aseguradas mediante SSL, e o teu contrasinal está camuflado utilizando un algoritmo potente de unha sóa vía. Podes habilitar a autenticación por dobre factor para protexer aínda máis o acceso á túa conta.

+
+

Cal é a nosa política de retención de datos?

+

Faremos un sincero esforzo en:

+ +

Podes solicitar e descargar un ficheiro cos teus contidos, incluíndo publicacións, anexos multimedia, imaxes de perfil e imaxe da cabeceira.

+

En todo momento podes eliminar de xeito irreversible a túa conta.

+
+

Utilizamos cookies?

+

Si. As cookies son pequenos ficheiros que un sitio web ou o provedor de servizo transfiren ao disco duro da túa computadora a través do navegador web (se o permites). Estas cookies posibilitan ao sitio web recoñecer o teu navegador e, se tes unha conta rexistrada, asocialo con dita conta.

+

Utilizamos cookies para comprender e gardar as túas preferencias para futuras visitas.

+
+

Entregamos algunha información a terceiras partes alleas?

+

Non vendemos, negociamos ou transferimos de ningún xeito a terceiras partes alleas a túa información identificativa persoal. Esto non inclúe terceiras partes de confianza que nos axudan a xestionar o sitio web, a xestionar a empresa, ou darche servizo se esas partes aceptan manter esa información baixo confidencialidade. Poderiamos liberar esa información se cremos que eso da cumplimento axeitado a lei, reforza as políticas do noso sitio ou protexe os nosos, e de outros, dereitos, propiedade ou seguridade.

+

O teu contido público podería ser descargado por outros servidores na rede. As túas publicacións públicas e para só seguidoras son entregadas aos servidores onde residen as túas seguidoras na rede, e as mensaxes directas son entregadas aos servidores das destinatarias sempre que esas seguidoras ou destinatarios residan en servidores distintos de este.

+

Cado autorizas a unha aplicación a utilizar a túa conta, dependendo do ámbito dos permisos que autorices, podería acceder a información pública de perfil, á lista de seguimento, ás túas seguidoras, as túas listas, todas as túas publicacións, as publicacións favoritas. As aplicacións non poden acceder nunca ao teu enderezo de correo nin ao teu contrasinal.

+
+

Utilización do sitio web por menores

+

Se este servidor está na UE ou no EEE: a nosa web, productos e servizos están dirixidos a persoas de 16 ou máis anos. Se tes menos de 16 anos, a requerimento da GDPR (General Data Protection Regulation) non uses esta web.

+

Se este servidor está nos EEUU: a nosa web, productos e servizos están dirixidos a persoas de 13 ou máis anos. Se non tes 13 anos de idade, a requerimento de COPPA (Children's Online Privacy Protection Act) non uses esta web.

+

Os requerimentos legais poden ser diferentes se este servidor está baixo outra xurisdición.

+
+

Cambios na nosa política de privacidade

+

Se decidimos cambiar a nosa política de privacidade publicaremos os cambios nesta páxina.

+

Este documento ten licenza CC-BY-SA. Actualizouse o 26 de maio de 2022.

+

Adaptado do orixinal política de privacidade de Discourse.

title: "%{instance} Termos do Servizo e Política de Intimidade" themes: contrast: Mastodon (Alto contraste) diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 0e3ff6440..faee9de06 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -430,6 +430,7 @@ hu: destroyed_msg: A domain tiltása feloldva domain: Domain edit: Domain tiltás szerkesztése + existing_domain_block: 'Már szigorúbb korlátozások vonatkoznak a következőre: %{name}.' existing_domain_block_html: A %{name} domainen már szorosabb korlátokat állítottál be, először oldd fel a tiltást. new: create: Tiltás létrehozása diff --git a/config/locales/id.yml b/config/locales/id.yml index 8b364ddc9..c278f749f 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -417,6 +417,7 @@ id: destroyed_msg: Pemblokiran domain telah dibatalkan domain: Domain edit: Edit blok domain + existing_domain_block: Anda sudah menerapkan batasan ketat terhadap %{name}. existing_domain_block_html: Anda telah menerapkan batasan yang lebih ketat pada %{name}, Anda harus membuka blokirnya lebih dulu. new: create: Buat pemblokiran diff --git a/config/locales/io.yml b/config/locales/io.yml index 1d0304d09..3649ec946 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -428,6 +428,7 @@ io: destroyed_msg: Domenobstrukto desagesis domain: Domeno edit: Modifikez domenobstrukto + existing_domain_block: Vu ja exekutis plu rigoroza limiti a %{name}. existing_domain_block_html: Vu ja povis plu rigoroza limiti a %{name}, vu bezonas deobstruktar unesme. new: create: Kreez obstrukto diff --git a/config/locales/is.yml b/config/locales/is.yml index 28d6914e5..4e3f9353e 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -428,6 +428,7 @@ is: destroyed_msg: Útilokun léns hefur verið aflétt domain: Lén edit: Breyta útilokun léns + existing_domain_block: Þú hefur þegar gert kröfu um strangari takmörk fyrir %{name}. existing_domain_block_html: Þú ert þegar búin/n að setja strangari takmörk á %{name}, þú þarft fyrst að aflétta útilokun á því. new: create: Búa til útilokun diff --git a/config/locales/it.yml b/config/locales/it.yml index 43fa1c07b..708436ee1 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -428,6 +428,7 @@ it: destroyed_msg: Il blocco del dominio è stato rimosso domain: Dominio edit: Modifica blocco di dominio + existing_domain_block: Hai già imposto limiti più severi a %{name}. existing_domain_block_html: Hai già impostato limitazioni più stringenti su %{name}, dovresti sbloccarlo prima. new: create: Crea blocco diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 38420d07f..defd5ab7c 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1482,6 +1482,87 @@ ja: tags: does_not_match_previous_name: 以前の名前と一致しません terms: + body_html: | +

プライバシーポリシー

+

どのような情報を収集しますか?

+ + + +
+ +

情報を何に使用しますか?

+ +

収集した情報は次の用途に使用されることがあります:

+ + + +
+ +

情報をどのように保護しますか?

+ +

私たちはあなたが入力・送信する際や自身の情報にアクセスする際に個人情報を安全に保つため、さまざまなセキュリティ上の対策を実施します。特にブラウザーセッションだけでなくアプリケーションとAPI間の通信もSSLによって保護されます。またパスワードは強力な不可逆アルゴリズムでハッシュ化されます。二要素認証を有効にし、アカウントへのアクセスをさらに安全にすることができます。

+ +
+ +

データ保持方針はどうなっていますか?

+ +

私たちは次のように誠意を持って努めます:

+ + + +

あなたは投稿・添付メディア・プロフィール画像・ヘッダー画像を含む自身のデータのアーカイブを要求し、ダウンロードすることができます。

+ +

あなたはいつでもアカウントの削除を要求できます。削除は取り消すことができません。

+ +
+ +

クッキーを使用していますか?

+ +

はい。クッキーは (あなたが許可した場合に) WebサイトやサービスがWebブラウザーを介してコンピューターに保存する小さなファイルです。使用することでWebサイトがブラウザーを識別し、登録済みのアカウントがある場合関連付けます。

+ +

私たちはクッキーを将来の訪問のために設定を保存し呼び出す用途に使用します。

+ +
+ +

なんらかの情報を外部に提供していますか?

+ +

私たちは個人を特定できる情報を外部へ販売・取引・その他方法で渡すことはありません。これには当サイトの運営・業務遂行・サービス提供を行ううえで補助する信頼できる第三者をこの機密情報の保護に同意するかぎり含みません。法令の遵守やサイトポリシーの施行、権利・財産・安全の保護に適切と判断した場合、あなたの情報を公開することがあります。

+ +

あなたの公開情報はネットワーク上の他のサーバーにダウンロードされることがあります。相手が異なるサーバーに所属する場合、「公開」と「フォロワー限定」投稿はフォロワーの所属するサーバーに配信され、「ダイレクト」投稿は受信者の所属するサーバーに配信されます。

+ +

あなたがアカウントの使用をアプリケーションに許可すると、承認した権限の範囲内で公開プロフィール情報・フォローリスト・フォロワー・リスト・すべての投稿・お気に入り登録にアクセスできます。アプリケーションはメールアドレスやパスワードに決してアクセスできません。

+ +
+ +

児童によるサイト利用について

+ +

サーバーがEUまたはEEA圏内にある場合: 当サイト・製品・サービスは16歳以上の人を対象としています。あなたが16歳未満の場合、GDPR (General Data Protection Regulation - EU一般データ保護規則) により当サイトを使用できません。

+ +

サーバーが米国にある場合: 当サイト・製品・サービスは13歳以上の人を対象としています。あなたが13歳未満の場合、COPPA (Children's Online Privacy Protection Act - 児童オンラインプライバシー保護法) により当サイトを使用できません。

+ +

サーバーが別の管轄区域にある場合、法的要件は異なることがあります。

+ +
+ +

プライバシーポリシーの変更

+ +

プライバシーポリシーの変更を決定した場合、このページに変更点を掲載します。

+ +

この文章のライセンスはCC-BY-SAです。最終更新日は2021年6月1日です。

+ +

オリジナルの出典: Discourse privacy policy

title: "%{instance} 利用規約・プライバシーポリシー" themes: contrast: Mastodon (ハイコントラスト) diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 538c14a91..630beabfb 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -419,6 +419,7 @@ ko: destroyed_msg: 도메인 차단이 해제되었습니다 domain: 도메인 edit: 도메인 차단 수정 + existing_domain_block: 이미 %{name}에 대한 더 강력한 제한이 있습니다. existing_domain_block_html: 이미 %{name}에 대한 더 강력한 제한이 걸려 있습니다, 차단 해제를 먼저 해야 합니다. new: create: 차단 추가 @@ -525,7 +526,7 @@ ko: private_comment: 비공개 주석 public_comment: 공개 주석 purge: 제거 - purge_description_html: 이 도메인이 영구적으로 오프라인 상태라고 생각되면 스토리지에서 이 도메인의 모든 계정 레코드와 관련 데이터를 삭제할 수 있습니다. 이 작업은 시간이 좀 걸릴 수 있습니다. + purge_description_html: 이 도메인이 영구적으로 오프라인 상태라고 생각되면, 스토리지에서 이 도메인의 모든 계정 레코드와 관련 데이터를 삭제할 수 있습니다. 이 작업은 시간이 좀 걸릴 수 있습니다. title: 연합 total_blocked_by_us: 우리에게 차단 됨 total_followed_by_them: 우리를 팔로우 @@ -591,7 +592,7 @@ ko: resolve_description_html: 신고된 계정에 대해 아무런 동작도 취하지 않으며, 처벌기록이 남지 않으며, 신고는 처리됨으로 변경됩니다. silence_description_html: 이미 팔로우 하고 있는 사람이나 수동으로 찾아보는 사람에게만 프로필이 보여지고, 도달 범위를 엄격하게 제한합니다. 언제든지 되돌릴 수 있습니다. suspend_description_html: 프로필과 모든 컨텐츠가 최종적으로 삭제될 때까지 접근 불가상태가 됩니다. 이 계정과의 상호작용은 불가능해집니다. 30일 이내에 되돌릴 수 있습니다. - actions_description_html: 이 보고서를 해결하기 위해 취해야 할 조치를 지정해주세요. 신고된 계정에 대해 처벌 조치를 취하면 스팸 카테고리가 선택된 경우를 제외하고 이메일 알림이 해당 계정으로 전송됩니다. + actions_description_html: 이 신고를 해결하기 위해 취해야 할 조치를 지정해주세요. 신고된 계정에 대해 처벌 조치를 취하면, 스팸 카테고리가 선택된 경우를 제외하고 해당 계정으로 이메일 알림이 전송됩니다. add_to_report: 신고에 더 추가하기 are_you_sure: 정말로 실행하시겠습니까? assign_to_self: 나에게 할당하기 @@ -618,7 +619,7 @@ ko: placeholder: 이 리포트에 대한 조치, 기타 관련 된 사항에 대해 설명합니다… title: 노트 notes_description_html: 확인하고 다른 중재자나 미래의 자신을 위해 기록을 작성합니다 - quick_actions_description_html: '보고된 콘텐츠를 보려면 빠른 조치를 취하거나 아래로 스크롤하세요:' + quick_actions_description_html: '빠른 조치를 취하거나 아래로 스크롤해서 신고된 콘텐츠를 확인하세요:' remote_user_placeholder: "%{instance}의 리모트 사용자" reopen: 리포트 다시 열기 report: '신고 #%{id}' @@ -1500,6 +1501,87 @@ ko: tags: does_not_match_previous_name: 이전 이름과 맞지 않습니다 terms: + body_html: | +

개인정보 정책

+

우리가 어떤 정보를 수집하나요?

+ + + +
+ +

우리가 당신의 정보를 어디에 쓰나요?

+ +

당신에게서 수집한 정보는 다음과 같은 곳에 사용 됩니다:

+ + + +
+ +

어떻게 당신의 정보를 보호하나요?

+ +

우리는 당신이 입력, 전송, 접근하는 개인정보를 보호하기 위해 다양한 보안 대책을 적용합니다. 당신의 브라우저 세션, 당신의 응용프로그램과의 통신, API는 SSL로 보호 되며 패스워드는 강력한 단방향 해시 알고리즘을 사용합니다. 계정의 더 나은 보안을 위해 2단계 인증을 활성화 할 수 있습니다.

+ +
+ +

자료 저장 정책은 무엇이죠?

+ +

우리는 다음을 위해 노력을 할 것입니다:

+ + + +

당신은 언제든지 게시물, 미디어 첨부, 프로필 이미지, 헤더 이미지를 포함한 당신의 컨텐트에 대한 아카이브를 요청하고 다운로드 할 수 있습니다.

+ +

언제든지 계정을 완전히 삭제할 수 있습니다.

+ +
+ +

쿠키를 사용하나요?

+ +

네. 쿠키는 (당신이 허용한다면) 당신의 웹 브라우저를 통해 서버에서 당신의 하드드라이브에 저장하도록 전송하는 작은 파일들입니다. 이 쿠키들은 당신의 브라우저를 인식하고, 계정이 있는 경우 이와 연결하는 것을 가능하게 합니다.

+ +

당신의 환경설정을 저장하고 다음 방문에 활용하기 위해 쿠키를 사용합니다.

+ +
+ +

외부에 정보를 공개하나요?

+ +

우리는 당신을 식별 가능한 개인정보를 외부에 팔거나 제공하거나 전송하지 않습니다. 이는 당사의 사이트를 운영하기 위한, 기밀 유지에 동의하는, 신뢰 가능한 서드파티를 포함하지 않습니다. 또한 법률 준수, 사이트 정책 시행, 또는 당사나 타인에 대한 권리, 재산, 또는 안전보호를 위해 적절하다고 판단되는 경우 당신의 정보를 공개할 수 있습니다.

+ +

당신의 공개 게시물은 네트워크에 속한 다른 서버가 다운로드 할 수 있습니다. 당신의 팔로워나 수신자가 이 서버가 아닌 다른 곳에 존재하는 경우 당신의 공개, 팔로워 공개 게시물은 당신의 팔로워가 존재하는 서버로 전송되며, 다이렉트메시지는 수신자가 존재하는 서버로 전송 됩니다.

+ +

당신이 계정을 사용하기 위해 응용프로그램을 승인하는 경우 당신이 허용한 권한에 따라 응용프로그램은 당신의 공개 계정정보, 팔로잉 리스트, 팔로워 리스트, 게시물, 좋아요 등에 접근이 가능해집니다. 응용프로그램은 절대로 당신의 이메일 주소나 패스워드에 접근할 수 없습니다.

+ +
+ +

어린이의 사이트 사용

+ +

이 서버가 EU나 EEA에 속해 있다면: 당사의 사이트, 제품과 서비스는 16세 이상인 사람들을 위해 제공됩니다. 당신이 16세 미만이라면 GDPR(General Data Protection Regulation)의 요건에 따라 이 사이트를 사용할 수 없습니다.

+ +

이 서버가 미국에 속해 있다면: 당사의 사이트, 제품과 서비스는 13세 이상인 사람들을 위해 제공됩니다. 당신이 13세 미만이라면 COPPA (Children's Online Privacy Protection Act)의 요건에 따라 이 사이트를 사용할 수 없습니다.

+ +

이 서버가 있는 관할권에 따라 법적 요구가 달라질 수 있습니다.

+ +
+ +

개인정보 정책의 변경

+ +

만약 우리의 개인정보 정책이 바뀐다면, 이 페이지에 바뀐 정책이 게시됩니다.

+ +

이 문서는 CC-BY-SA 라이센스입니다. 마지막 업데이트는 2012년 5월 26일입니다.

+ +

Originally adapted from the Discourse privacy policy.

title: "%{instance} 이용약관과 개인정보 취급 방침" themes: contrast: 마스토돈 (고대비) @@ -1553,7 +1635,7 @@ ko: spam: 스팸 violation: 컨텐츠가 다음의 커뮤니티 규정을 위반합니다 explanation: - delete_statuses: 귀하의 게시물 중 일부가 하나 이상의 커뮤니티 가이드라인을 위반한 것으로 확인되어 %{instance} 모더레이터에 의해 삭제되었습니다. + delete_statuses: 귀하의 게시물 중 일부가 하나 이상의 커뮤니티 가이드라인을 위반한 것으로 확인되어 %{instance}의 중재자에 의해 삭제되었습니다. disable: 당신은 더이상 당신의 계정을 사용할 수 없습니다, 하지만 프로필과 다른 데이터들은 여전히 그대로 남아있습니다. 당신의 데이터에 대한 백업을 요청하거나, 계정 설정을 변경 또는 계정을 삭제할 수 있습니다. mark_statuses_as_sensitive: 당신의 몇몇 게시물들은 %{instance}의 중재자에 의해 민감함으로 설정되었습니다. 이것은 사람들이 미리보기를 보기 전에 미디어를 한번 눌러야 함을 의미합니다. 당신은 스스로도 자신의 게시물을 작성할 때 미디어를 민감함으로 설정할 수 있습니다. sensitive: 지금부터는, 당신이 업로드한 미디어 파일들은 민감함 표시가 뜨게 되고 클릭해야만 볼 수 있다는 경고문 뒤에 가려지게 됩니다. diff --git a/config/locales/ku.yml b/config/locales/ku.yml index 085624c54..78d99c2e5 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -428,6 +428,7 @@ ku: destroyed_msg: Navpera asteng kirinê hat rakirin domain: Navper edit: Astengkirina navperê serrast bike + existing_domain_block: Jixwe te sînorên tundtir li ser %{name} daye kirine. existing_domain_block_html: Te bi bandorê mezin sînor danî ser %{name}, Divê tu asteng kirinê rabikî, pêşî ya . new: create: Astengkirinekê çê bike diff --git a/config/locales/lv.yml b/config/locales/lv.yml index e7882c510..f9d404303 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -437,6 +437,7 @@ lv: destroyed_msg: Domēna bloķēšana ir atsaukta domain: Domēns edit: Rediģēt domēna bloķēšanu + existing_domain_block: Tu jau esi noteicis stingrākus ierobežojumus %{name}. existing_domain_block_html: Tu jau esi noteicis stingrākus ierobežojumus %{name}, vispirms tev jāatbloķē. new: create: Izveodot bloku diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 845e0237d..2709572de 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -446,6 +446,7 @@ pl: destroyed_msg: Blokada domeny nie może zostać odwrócona domain: Domena edit: Edytuj blokadę domeny + existing_domain_block: Już nałożyłeś surowsze limity na %{name}. existing_domain_block_html: Już narzuciłeś bardziej rygorystyczne limity na %{name}, musisz najpierw je odblokować. new: create: Utwórz blokadę diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 2765bf941..377360a9d 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -428,6 +428,7 @@ pt-PT: destroyed_msg: Bloqueio de domínio está a ser removido domain: Domínio edit: Editar bloqueio de domínio + existing_domain_block: Já impôs limites mais rigorosos a %{name}. existing_domain_block_html: Você já impôs limites mais restritivos a %{name}, é necessário primeiro desbloqueá-lo. new: create: Criar bloqueio diff --git a/config/locales/ru.yml b/config/locales/ru.yml index c0495c3ee..39a3b3eb7 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -426,6 +426,7 @@ ru: destroyed_msg: Блокировка домена снята domain: Домен edit: Редактировать блокировку + existing_domain_block: Вы уже установили более строгие ограничения для %{name}. existing_domain_block_html: Вы уже ввели более строгие ограничения на %{name}, вам нужно разблокировать его сначала. new: create: Создать блокировку @@ -495,8 +496,12 @@ ru: comment: Внутренняя заметка policies: reject_media: Отклонить медиа + silence: Лимит + suspend: Приостановить policy: Политика + reason: Публичная причина dashboard: + instance_accounts_dimension: Популярные аккаунты instance_accounts_measure: сохраненные учетные записи instance_languages_dimension: Популярные языки instance_media_attachments_measure: сохраненные медиафайлы @@ -796,6 +801,8 @@ ru: title: Издатели rejected: Отклонённые statuses: + allow: Разрешить пост + allow_account: Разрешить автора title: Популярные посты tags: current_score: Текущий счет %{score} @@ -847,6 +854,7 @@ ru: new_trending_statuses: title: Популярные посты new_trending_tags: + no_approved_tags: На данный момент популярные подтвержденные хэштеги отсутствуют. title: Популярные хэштеги aliases: add_new: Создать псевдоним @@ -1008,9 +1016,12 @@ ru: title: "%{action} от %{date}" title_actions: delete_statuses: Удаление поста + disable: Заморозка аккаунта mark_statuses_as_sensitive: Помечать посты как деликатные + none: Требующие внимания sensitive: Отметить учетную запись как деликатную silence: Ограничение учетной записи + suspend: Приостановка Аккаунта your_appeal_approved: Ваша апелляция одобрена your_appeal_pending: Вы подали апелляцию your_appeal_rejected: Ваша апелляция отклонена diff --git a/config/locales/simple_form.fy.yml b/config/locales/simple_form.fy.yml new file mode 100644 index 000000000..b568750e2 --- /dev/null +++ b/config/locales/simple_form.fy.yml @@ -0,0 +1,6 @@ +--- +fy: + simple_form: + labels: + notification_emails: + mention: Ien hat jo fermeld diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml index 9d82e43a4..71d4058c8 100644 --- a/config/locales/simple_form.ko.yml +++ b/config/locales/simple_form.ko.yml @@ -37,7 +37,7 @@ ko: current_password: 보안을 위해 현재 계정의 암호를 입력해주세요 current_username: 확인을 위해, 현재 계정의 사용자명을 입력해주세요 digest: 오랫동안 활동하지 않았을 때 받은 멘션들에 대한 요약 받기 - discoverable: 추천, 트렌드 및 기타 기능을 통해 낯선 사람이 귀하의 계정을 찾을 수 있도록 허용합니다 + discoverable: 추천, 트렌드 및 기타 기능을 통해 낯선 사람이 내 계정을 발견할 수 있도록 허용합니다 email: 당신은 확인 메일을 받게 됩니다 fields: 당신의 프로파일에 최대 4개까지 표 형식으로 나타낼 수 있습니다 header: PNG, GIF 혹은 JPG. 최대 %{size}. %{dimensions}px로 축소 됨 @@ -206,10 +206,10 @@ ko: digest: 요약 이메일 보내기 favourite: 누군가 내 상태를 마음에 들어했을 때 follow: 누군가 나를 팔로우 했을 때 - follow_request: 누군가 나를 팔로우 하길 원할 때 + follow_request: 누군가 나를 팔로우 하길 요청할 때 mention: 누군가 나를 언급했을 때 pending_account: 새 계정이 심사가 필요할 때 - reblog: 누군가 내 툿을 부스트 했을 때 + reblog: 누군가 내 게시물을 부스트 했을 때 report: 새 신고가 접수되었을 때 trending_tag: 새 트렌드에 대한 리뷰가 필요할 때 rule: diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 58190e95b..8f54e9f74 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -446,6 +446,7 @@ sl: destroyed_msg: Domenski blok je bil razveljavljen domain: Domena edit: Uredi domenski blok + existing_domain_block: Ste že uveljavili strožje omejitve na %{name}. existing_domain_block_html: Uvedli ste strožje omejitve za %{name}, sedaj ga morate najprej odblokirati. new: create: Ustvari blok diff --git a/config/locales/th.yml b/config/locales/th.yml index 25fc7034e..9fd23f5b3 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -174,6 +174,7 @@ th: already_confirmed: ผู้ใช้นี้ได้รับการยืนยันอยู่แล้ว send: ส่งอีเมลยืนยันใหม่ success: ส่งอีเมลยืนยันสำเร็จ! + reset: รีเซ็ต reset_password: ตั้งรหัสผ่านใหม่ resubscribe: บอกรับใหม่ role: สิทธิอนุญาต diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 15f4bf57c..23fe6508b 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1525,6 +1525,86 @@ tr: tags: does_not_match_previous_name: önceki adla eşleşmiyor terms: + body_html: | +

Gizlilik Politikası

+

Hangi bilgileri topluyoruz?

+ + + +
+ +

Bilgilerinizi ne için kullanıyoruz?

+ +

Sizden topladığımız bilgilerin herhangi bir kısmı aşağıdaki şekillerde kullanılabilir:

+ + + +
+ +

Bilgilerinizi nasıl koruyoruz?

+ +

Kişisel bilgilerinizi girerken, gönderirken veya onlara erişirken kişisel bilgilerinizin güvenliğini sağlamak için çeşitli güvenlik önlemleri uyguluyoruz. Diğer şeylerin yanı sıra, tarayıcı oturumunuz ve uygulamalarınız ile API arasındaki trafik SSL ile güvence altına alınır ve şifreniz sağlam bir tek yönlü bir algoritma kullanılarak şifrelenir. Hesabınıza daha güvenli bir şekilde erişebilmek için iki adımlı kimlik doğrulamasını etkinleştirebilirsiniz.

+ +
+ +

Veri saklama politikamız nedir?

+ +

Şunları yapmak için iyi niyetli bir şekilde çalışacağız:

+ + +

Gönderileriniz, medya ekleriniz, profil fotoğrafınız ve başlık resminiz dahil, içeriğimizin arşivini talep edebilir ve indirebilirsiniz.

+ +

Hesabınızı istediğiniz zaman geri alınamaz şekilde silebilirsiniz.

+ +
+ +

Çerez kullanıyor muyuz?

+ +

Evet. Çerezler, bir sitenin veya servis sağlayıcısının Web tarayıcınız üzerinden bilgisayarınızın sabit diskine aktardığı küçük dosyalardır (eğer izin verirseniz). Bu çerezler sitenin tarayıcınızı tanımasını ve kayıtlı bir hesabınız varsa, kayıtlı hesabınızla ilişkilendirmesini sağlar.

+ +

Sonraki ziyaretlerde tercihlerinizi anlamak ve kaydetmek için çerezleri kullanıyoruz.

+ +
+ +

Herhangi bir bilgiyi dış taraflara açıklıyor muyuz?

+ +

Kişisel olarak tanımlanabilir bilgilerinizi dış taraflara satmıyor, takas etmiyor veya devretmiyoruz. Bu, taraflarımız bu bilgileri gizli tutmayı kabul ettiği sürece sitemizi işletmemize, işimizi yürütmemize veya size hizmet etmemize yardımcı olan güvenilir üçüncü tarafları içermemektedir. Ayrıca, yayınlanmanın yasalara uymayı, site politikalarımızı yürürlüğe koymayı ya da kendimizin ya da diğerlerinin haklarını, mülklerini ya da güvenliğini korumamızı sağladığına inandığımızda bilgilerinizi açıklayabiliriz.

+ +

Herkese açık içeriğiniz ağdaki diğer sunucular tarafından indirilebilir. Bu takipçiler veya alıcılar bundan farklı bir sunucuda bulundukları sürece, herkese açık ve takipçilere özel gönderileriniz, takipçilerinizin bulunduğu sunuculara, ve doğrudan mesajlar, alıcıların sunucularına iletilir.

+ +

Hesabınızı kullanması için bir uygulamayı yetkilendirdiğinizde, onayladığınız izinlerin kapsamına bağlı olarak, herkese açık profil bilgilerinize, takip ettiklerinizin listesine, takipçilerinize, listelerinize, tüm gönderilerinize ve favorilerinize erişebilir. Uygulamalar e-posta adresinize veya parolanıza asla erişemez.

+ +
+ +

Sitenin çocuklar tarafından kullanımı

+ +

Bu sunucu AB’de veya AEA’da ise: Site, ürün ve hizmetlerimizin tamamı en az 16 yaşında olan kişilere yöneliktir. Eğer 16 yaşın altındaysanız, GDPR yükümlülükleri gereği (General Data Protection Regulation) bu siteyi kullanmayın.

+ +

Bu sunucu ABD’de ise: Site, ürün ve hizmetlerimizin tamamı en az 13 yaşında olan kişilere yöneliktir. Eğer 13 yaşın altındaysanız, COPPA yükümlülükleri gereği (Children's Online Privacy Protection Act) bu siteyi kullanmayın.

+ +

Bu sunucu başka bir ülkede ise yasal gereklilikler farklı olabilir.

+ +
+ +

Gizlilik Politikamızdaki Değişiklikler

+ +

Gizlilik politikamızı değiştirmeye karar verirsek, bu değişiklikleri bu sayfada yayınlayacağız.

+ +

Bu belge CC-BY-SA altında lisanslanmıştır. En son 26 Mayıs 2022 tarihinde güncellenmiştir.

+ +

Discourse gizlilik politikasından uyarlanmıştır.

title: "%{instance} Hizmet Şartları ve Gizlilik Politikası" themes: contrast: Mastodon (Yüksek karşıtlık) diff --git a/config/locales/uk.yml b/config/locales/uk.yml index dfe25ebb2..aa210c980 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -444,6 +444,7 @@ uk: destroyed_msg: Блокування домену знято domain: Домен edit: Редагувати блокування доменів + existing_domain_block: Ви вже наклали суворіші обмеження на %{name}. existing_domain_block_html: Ви вже наклали більш суворі обмеження на %{name}, вам треба спочатку розблокувати його. new: create: Створити блокування diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 95561abb7..032a5c951 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -417,6 +417,7 @@ zh-TW: destroyed_msg: 已撤銷站點封鎖 domain: 站點 edit: 更改封鎖的站台 + existing_domain_block: 您已對 %{name} 施加了更嚴格的限制。 existing_domain_block_html: 您已經對 %{name} 施加了更嚴格的限制,您需要先把他取消封鎖。 new: create: 新增封鎖 -- cgit From a2871cd74719a7a5a104daaa3dcc0e2670b7c2df Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 9 Jun 2022 21:57:36 +0200 Subject: Add administrative webhooks (#18510) * Add administrative webhooks * Fix error when webhook is deleted before delivery worker runs --- .../admin/webhooks/secrets_controller.rb | 19 ++++++ app/controllers/admin/webhooks_controller.rb | 77 ++++++++++++++++++++++ app/javascript/styles/mastodon/admin.scss | 8 +++ app/models/admin/action_log.rb | 1 + app/models/report.rb | 6 ++ app/models/user.rb | 10 ++- app/models/webhook.rb | 58 ++++++++++++++++ app/policies/webhook_policy.rb | 35 ++++++++++ app/presenters/webhooks/event_presenter.rb | 13 ++++ app/serializers/rest/admin/report_serializer.rb | 3 +- .../rest/admin/webhook_event_serializer.rb | 26 ++++++++ app/services/base_service.rb | 4 ++ app/services/webhook_service.rb | 22 +++++++ app/validators/url_validator.rb | 2 +- app/views/admin/webhooks/_form.html.haml | 11 ++++ app/views/admin/webhooks/_webhook.html.haml | 19 ++++++ app/views/admin/webhooks/edit.html.haml | 4 ++ app/views/admin/webhooks/index.html.haml | 18 +++++ app/views/admin/webhooks/new.html.haml | 4 ++ app/views/admin/webhooks/show.html.haml | 34 ++++++++++ app/views/layouts/admin.html.haml | 5 +- app/workers/trigger_webhook_worker.rb | 12 ++++ app/workers/webhooks/delivery_worker.rb | 37 +++++++++++ config/locales/activerecord.en.yml | 8 +++ config/locales/en.yml | 21 +++++- config/locales/simple_form.en.yml | 6 ++ config/navigation.rb | 1 + config/routes.rb | 11 ++++ db/migrate/20220606044941_create_webhooks.rb | 12 ++++ db/schema.rb | 12 +++- spec/fabricators/webhook_fabricator.rb | 5 ++ spec/models/webhook_spec.rb | 32 +++++++++ spec/validators/url_validator_spec.rb | 2 +- 33 files changed, 530 insertions(+), 8 deletions(-) create mode 100644 app/controllers/admin/webhooks/secrets_controller.rb create mode 100644 app/controllers/admin/webhooks_controller.rb create mode 100644 app/models/webhook.rb create mode 100644 app/policies/webhook_policy.rb create mode 100644 app/presenters/webhooks/event_presenter.rb create mode 100644 app/serializers/rest/admin/webhook_event_serializer.rb create mode 100644 app/services/webhook_service.rb create mode 100644 app/views/admin/webhooks/_form.html.haml create mode 100644 app/views/admin/webhooks/_webhook.html.haml create mode 100644 app/views/admin/webhooks/edit.html.haml create mode 100644 app/views/admin/webhooks/index.html.haml create mode 100644 app/views/admin/webhooks/new.html.haml create mode 100644 app/views/admin/webhooks/show.html.haml create mode 100644 app/workers/trigger_webhook_worker.rb create mode 100644 app/workers/webhooks/delivery_worker.rb create mode 100644 db/migrate/20220606044941_create_webhooks.rb create mode 100644 spec/fabricators/webhook_fabricator.rb create mode 100644 spec/models/webhook_spec.rb (limited to 'config') diff --git a/app/controllers/admin/webhooks/secrets_controller.rb b/app/controllers/admin/webhooks/secrets_controller.rb new file mode 100644 index 000000000..16af1cf7b --- /dev/null +++ b/app/controllers/admin/webhooks/secrets_controller.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Admin + class Webhooks::SecretsController < BaseController + before_action :set_webhook + + def rotate + authorize @webhook, :rotate_secret? + @webhook.rotate_secret! + redirect_to admin_webhook_path(@webhook) + end + + private + + def set_webhook + @webhook = Webhook.find(params[:webhook_id]) + end + end +end diff --git a/app/controllers/admin/webhooks_controller.rb b/app/controllers/admin/webhooks_controller.rb new file mode 100644 index 000000000..d6fb1a4ea --- /dev/null +++ b/app/controllers/admin/webhooks_controller.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module Admin + class WebhooksController < BaseController + before_action :set_webhook, except: [:index, :new, :create] + + def index + authorize :webhook, :index? + + @webhooks = Webhook.page(params[:page]) + end + + def new + authorize :webhook, :create? + + @webhook = Webhook.new + end + + def create + authorize :webhook, :create? + + @webhook = Webhook.new(resource_params) + + if @webhook.save + redirect_to admin_webhook_path(@webhook) + else + render :new + end + end + + def show + authorize @webhook, :show? + end + + def edit + authorize @webhook, :update? + end + + def update + authorize @webhook, :update? + + if @webhook.update(resource_params) + redirect_to admin_webhook_path(@webhook) + else + render :show + end + end + + def enable + authorize @webhook, :enable? + @webhook.enable! + redirect_to admin_webhook_path(@webhook) + end + + def disable + authorize @webhook, :disable? + @webhook.disable! + redirect_to admin_webhook_path(@webhook) + end + + def destroy + authorize @webhook, :destroy? + @webhook.destroy! + redirect_to admin_webhooks_path + end + + private + + def set_webhook + @webhook = Webhook.find(params[:id]) + end + + def resource_params + params.require(:webhook).permit(:url, events: []) + end + end +end diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 921c529d1..18638e18f 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -203,6 +203,14 @@ $content-width: 840px; } } + h2 small { + font-size: 12px; + display: block; + font-weight: 500; + color: $darker-text-color; + line-height: 18px; + } + @media screen and (max-width: $no-columns-breakpoint) { border-bottom: 0; padding-bottom: 0; diff --git a/app/models/admin/action_log.rb b/app/models/admin/action_log.rb index 852bff713..401bfd9ac 100644 --- a/app/models/admin/action_log.rb +++ b/app/models/admin/action_log.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # == Schema Information # # Table name: admin_action_logs diff --git a/app/models/report.rb b/app/models/report.rb index 6d4166540..2efb6d4a7 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -55,6 +55,8 @@ class Report < ApplicationRecord before_validation :set_uri, only: :create + after_create_commit :trigger_webhooks + def object_type :flag end @@ -143,4 +145,8 @@ class Report < ApplicationRecord errors.add(:rule_ids, I18n.t('reports.errors.invalid_rules')) unless rules.size == rule_ids&.size end + + def trigger_webhooks + TriggerWebhookWorker.perform_async('report.created', 'Report', id) + end end diff --git a/app/models/user.rb b/app/models/user.rb index 23febb6fe..81f6a58f6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -37,7 +37,6 @@ # sign_in_token_sent_at :datetime # webauthn_id :string # sign_up_ip :inet -# skip_sign_in_token :boolean # class User < ApplicationRecord @@ -120,6 +119,7 @@ class User < ApplicationRecord before_validation :sanitize_languages before_create :set_approved after_commit :send_pending_devise_notifications + after_create_commit :trigger_webhooks # This avoids a deprecation warning from Rails 5.1 # It seems possible that a future release of devise-two-factor will @@ -182,7 +182,9 @@ class User < ApplicationRecord end def update_sign_in!(new_sign_in: false) - old_current, new_current = current_sign_in_at, Time.now.utc + old_current = current_sign_in_at + new_current = Time.now.utc + self.last_sign_in_at = old_current || new_current self.current_sign_in_at = new_current @@ -472,4 +474,8 @@ class User < ApplicationRecord def invite_text_required? Setting.require_invite_text && !invited? && !external? && !bypass_invite_request_check? end + + def trigger_webhooks + TriggerWebhookWorker.perform_async('account.created', 'Account', account_id) + end end diff --git a/app/models/webhook.rb b/app/models/webhook.rb new file mode 100644 index 000000000..431edd75d --- /dev/null +++ b/app/models/webhook.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: webhooks +# +# id :bigint(8) not null, primary key +# url :string not null +# events :string default([]), not null, is an Array +# secret :string default(""), not null +# enabled :boolean default(TRUE), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class Webhook < ApplicationRecord + EVENTS = %w( + account.created + report.created + ).freeze + + scope :enabled, -> { where(enabled: true) } + + validates :url, presence: true, url: true + validates :secret, presence: true, length: { minimum: 12 } + validates :events, presence: true + + validate :validate_events + + before_validation :strip_events + before_validation :generate_secret + + def rotate_secret! + update!(secret: SecureRandom.hex(20)) + end + + def enable! + update!(enabled: true) + end + + def disable! + update!(enabled: false) + end + + private + + def validate_events + errors.add(:events, :invalid) if events.any? { |e| !EVENTS.include?(e) } + end + + def strip_events + self.events = events.map { |str| str.strip.presence }.compact if events.present? + end + + def generate_secret + self.secret = SecureRandom.hex(20) if secret.blank? + end +end diff --git a/app/policies/webhook_policy.rb b/app/policies/webhook_policy.rb new file mode 100644 index 000000000..2c55703a1 --- /dev/null +++ b/app/policies/webhook_policy.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class WebhookPolicy < ApplicationPolicy + def index? + admin? + end + + def create? + admin? + end + + def show? + admin? + end + + def update? + admin? + end + + def enable? + admin? + end + + def disable? + admin? + end + + def rotate_secret? + admin? + end + + def destroy? + admin? + end +end diff --git a/app/presenters/webhooks/event_presenter.rb b/app/presenters/webhooks/event_presenter.rb new file mode 100644 index 000000000..dac14a3f0 --- /dev/null +++ b/app/presenters/webhooks/event_presenter.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class Webhooks::EventPresenter < ActiveModelSerializers::Model + attributes :type, :created_at, :object + + def initialize(type, object) + super() + + @type = type + @created_at = Time.now.utc + @object = object + end +end diff --git a/app/serializers/rest/admin/report_serializer.rb b/app/serializers/rest/admin/report_serializer.rb index 74bc0c520..237f41d8e 100644 --- a/app/serializers/rest/admin/report_serializer.rb +++ b/app/serializers/rest/admin/report_serializer.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true class REST::Admin::ReportSerializer < ActiveModel::Serializer - attributes :id, :action_taken, :category, :comment, :created_at, :updated_at + attributes :id, :action_taken, :action_taken_at, :category, :comment, + :created_at, :updated_at has_one :account, serializer: REST::Admin::AccountSerializer has_one :target_account, serializer: REST::Admin::AccountSerializer diff --git a/app/serializers/rest/admin/webhook_event_serializer.rb b/app/serializers/rest/admin/webhook_event_serializer.rb new file mode 100644 index 000000000..fe0ac23f9 --- /dev/null +++ b/app/serializers/rest/admin/webhook_event_serializer.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class REST::Admin::WebhookEventSerializer < ActiveModel::Serializer + def self.serializer_for(model, options) + case model.class.name + when 'Account' + REST::Admin::AccountSerializer + when 'Report' + REST::Admin::ReportSerializer + else + super + end + end + + attributes :event, :created_at + + has_one :virtual_object, key: :object + + def virtual_object + object.object + end + + def event + object.type + end +end diff --git a/app/services/base_service.rb b/app/services/base_service.rb index 99e8c875f..b0c0f9ec4 100644 --- a/app/services/base_service.rb +++ b/app/services/base_service.rb @@ -5,4 +5,8 @@ class BaseService include ActionView::Helpers::SanitizeHelper include RoutingHelper + + def call(*) + raise NotImplementedError + end end diff --git a/app/services/webhook_service.rb b/app/services/webhook_service.rb new file mode 100644 index 000000000..aafa38318 --- /dev/null +++ b/app/services/webhook_service.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class WebhookService < BaseService + def call(event, object) + @event = Webhooks::EventPresenter.new(event, object) + @body = serialize_event + + webhooks_for_event.each do |webhook_id| + Webhooks::DeliveryWorker.perform_async(webhook_id, @body) + end + end + + private + + def webhooks_for_event + Webhook.enabled.where('? = ANY(events)', @event.type).pluck(:id) + end + + def serialize_event + Oj.dump(ActiveModelSerializers::SerializableResource.new(@event, serializer: REST::Admin::WebhookEventSerializer, scope: nil, scope_name: :current_user).as_json) + end +end diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb index f50abbe24..75d1edb87 100644 --- a/app/validators/url_validator.rb +++ b/app/validators/url_validator.rb @@ -2,7 +2,7 @@ class URLValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) - record.errors.add(attribute, I18n.t('applications.invalid_url')) unless compliant?(value) + record.errors.add(attribute, :invalid) unless compliant?(value) end private diff --git a/app/views/admin/webhooks/_form.html.haml b/app/views/admin/webhooks/_form.html.haml new file mode 100644 index 000000000..c1e8f8979 --- /dev/null +++ b/app/views/admin/webhooks/_form.html.haml @@ -0,0 +1,11 @@ += simple_form_for @webhook, url: @webhook.new_record? ? admin_webhooks_path : admin_webhook_path(@webhook) do |f| + = render 'shared/error_messages', object: @webhook + + .fields-group + = f.input :url, wrapper: :with_block_label, input_html: { placeholder: 'https://' } + + .fields-group + = f.input :events, collection: Webhook::EVENTS, wrapper: :with_block_label, include_blank: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + + .actions + = f.button :button, @webhook.new_record? ? t('admin.webhooks.add_new') : t('generic.save_changes'), type: :submit diff --git a/app/views/admin/webhooks/_webhook.html.haml b/app/views/admin/webhooks/_webhook.html.haml new file mode 100644 index 000000000..d94a41eb3 --- /dev/null +++ b/app/views/admin/webhooks/_webhook.html.haml @@ -0,0 +1,19 @@ +.applications-list__item + = link_to admin_webhook_path(webhook), class: 'announcements-list__item__title' do + = fa_icon 'inbox' + = webhook.url + + .announcements-list__item__action-bar + .announcements-list__item__meta + - if webhook.enabled? + %span.positive-hint= t('admin.webhooks.enabled') + - else + %span.negative-hint= t('admin.webhooks.disabled') + + • + + %abbr{ title: webhook.events.join(', ') }= t('admin.webhooks.enabled_events', count: webhook.events.size) + + %div + = table_link_to 'pencil', t('admin.webhooks.edit'), edit_admin_webhook_path(webhook) if can?(:update, webhook) + = table_link_to 'trash', t('admin.webhooks.delete'), admin_webhook_path(webhook), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, webhook) diff --git a/app/views/admin/webhooks/edit.html.haml b/app/views/admin/webhooks/edit.html.haml new file mode 100644 index 000000000..3dc0ace9b --- /dev/null +++ b/app/views/admin/webhooks/edit.html.haml @@ -0,0 +1,4 @@ +- content_for :page_title do + = t('admin.webhooks.edit') + += render partial: 'form' diff --git a/app/views/admin/webhooks/index.html.haml b/app/views/admin/webhooks/index.html.haml new file mode 100644 index 000000000..e4499e078 --- /dev/null +++ b/app/views/admin/webhooks/index.html.haml @@ -0,0 +1,18 @@ +- content_for :page_title do + = t('admin.webhooks.title') + +- content_for :heading_actions do + = link_to t('admin.webhooks.add_new'), new_admin_webhook_path, class: 'button' if can?(:create, :webhook) + +%p= t('admin.webhooks.description_html') + +%hr.spacer/ + +- if @webhooks.empty? + %div.muted-hint.center-text + = t 'admin.webhooks.empty' +- else + .applications-list + = render partial: 'webhook', collection: @webhooks + + = paginate @webhooks diff --git a/app/views/admin/webhooks/new.html.haml b/app/views/admin/webhooks/new.html.haml new file mode 100644 index 000000000..1258df74a --- /dev/null +++ b/app/views/admin/webhooks/new.html.haml @@ -0,0 +1,4 @@ +- content_for :page_title do + = t('admin.webhooks.new') + += render partial: 'form' diff --git a/app/views/admin/webhooks/show.html.haml b/app/views/admin/webhooks/show.html.haml new file mode 100644 index 000000000..cc450de26 --- /dev/null +++ b/app/views/admin/webhooks/show.html.haml @@ -0,0 +1,34 @@ +- content_for :page_title do + = t('admin.webhooks.title') + +- content_for :heading do + %h2 + %small + = fa_icon 'inbox' + = t('admin.webhooks.webhook') + = @webhook.url + +- content_for :heading_actions do + = link_to t('admin.webhooks.edit'), edit_admin_webhook_path, class: 'button' if can?(:update, @webhook) + +.table-wrapper + %table.table.horizontal-table + %tbody + %tr + %th= t('admin.webhooks.status') + %td + - if @webhook.enabled? + %span.positive-hint= t('admin.webhooks.enabled') + = table_link_to 'power-off', t('admin.webhooks.disable'), disable_admin_webhook_path(@webhook), method: :post if can?(:disable, @webhook) + - else + %span.negative-hint= t('admin.webhooks.disabled') + = table_link_to 'power-off', t('admin.webhooks.enable'), enable_admin_webhook_path(@webhook), method: :post if can?(:enable, @webhook) + %tr + %th= t('admin.webhooks.events') + %td + %abbr{ title: @webhook.events.join(', ') }= t('admin.webhooks.enabled_events', count: @webhook.events.size) + %tr + %th= t('admin.webhooks.secret') + %td + %samp= @webhook.secret + = table_link_to 'refresh', t('admin.webhooks.rotate_secret'), rotate_admin_webhook_secret_path(@webhook), method: :post if can?(:rotate_secret, @webhook) diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml index 62716ab1e..0f6433781 100644 --- a/app/views/layouts/admin.html.haml +++ b/app/views/layouts/admin.html.haml @@ -23,7 +23,10 @@ .content-wrapper .content .content-heading - %h2= yield :page_title + - if content_for?(:heading) + = yield :heading + - else + %h2= yield :page_title - if :heading_actions .content-heading-actions diff --git a/app/workers/trigger_webhook_worker.rb b/app/workers/trigger_webhook_worker.rb new file mode 100644 index 000000000..2ffb6246f --- /dev/null +++ b/app/workers/trigger_webhook_worker.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class TriggerWebhookWorker + include Sidekiq::Worker + + def perform(event, class_name, id) + object = class_name.constantize.find(id) + WebhookService.new.call(event, object) + rescue ActiveRecord::RecordNotFound + true + end +end diff --git a/app/workers/webhooks/delivery_worker.rb b/app/workers/webhooks/delivery_worker.rb new file mode 100644 index 000000000..b1e345c5e --- /dev/null +++ b/app/workers/webhooks/delivery_worker.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class Webhooks::DeliveryWorker + include Sidekiq::Worker + include JsonLdHelper + + sidekiq_options queue: 'push', retry: 16, dead: false + + def perform(webhook_id, body) + @webhook = Webhook.find(webhook_id) + @body = body + @response = nil + + perform_request + rescue ActiveRecord::RecordNotFound + true + end + + private + + def perform_request + request = Request.new(:post, @webhook.url, body: @body) + + request.add_headers( + 'Content-Type' => 'application/json', + 'X-Hub-Signature' => "sha256=#{signature}" + ) + + request.perform do |response| + raise Mastodon::UnexpectedResponseError, response unless response_successful?(response) || response_error_unsalvageable?(response) + end + end + + def signature + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), @webhook.secret, @body) + end +end diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index d5f19ca64..720b0f5e3 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -21,6 +21,14 @@ en: username: invalid: must contain only letters, numbers and underscores reserved: is reserved + admin/webhook: + attributes: + url: + invalid: is not a valid URL + doorkeeper/application: + attributes: + website: + invalid: is not a valid URL status: attributes: reblog: diff --git a/config/locales/en.yml b/config/locales/en.yml index 6bb0cc7ab..b73b352c7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -852,6 +852,26 @@ en: edit_preset: Edit warning preset empty: You haven't defined any warning presets yet. title: Manage warning presets + webhooks: + add_new: Add endpoint + delete: Delete + description_html: A webhook enables Mastodon to push real-time notifications about chosen events to your own application, so your application can automatically trigger reactions. + disable: Disable + disabled: Disabled + edit: Edit endpoint + empty: You don't have any webhook endpoints configured yet. + enable: Enable + enabled: Active + enabled_events: + one: 1 enabled event + other: "%{count} enabled events" + events: Events + new: New webhook + rotate_secret: Rotate secret + secret: Signing secret + status: Status + title: Webhooks + webhook: Webhook admin_mailer: new_appeal: actions: @@ -916,7 +936,6 @@ en: applications: created: Application successfully created destroyed: Application successfully deleted - invalid_url: The provided URL is invalid regenerate_token: Regenerate access token token_regenerated: Access token successfully regenerated warning: Be very careful with this data. Never share it with anyone! diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index b784b1da7..7e4f52849 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -91,6 +91,9 @@ en: name: You can only change the casing of the letters, for example, to make it more readable user: chosen_languages: When checked, only posts in selected languages will be displayed in public timelines + webhook: + events: Select events to send + url: Where events will be sent to labels: account: fields: @@ -219,6 +222,9 @@ en: name: Hashtag trendable: Allow this hashtag to appear under trends usable: Allow posts to use this hashtag + webhook: + events: Enabled events + url: Endpoint URL 'no': 'No' recommended: Recommended required: diff --git a/config/navigation.rb b/config/navigation.rb index 620f78c57..ec5719e3e 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -56,6 +56,7 @@ SimpleNavigation::Configuration.run do |navigation| s.item :rules, safe_join([fa_icon('gavel fw'), t('admin.rules.title')]), admin_rules_path, highlights_on: %r{/admin/rules} s.item :announcements, safe_join([fa_icon('bullhorn fw'), t('admin.announcements.title')]), admin_announcements_path, highlights_on: %r{/admin/announcements} s.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis} + s.item :webhooks, safe_join([fa_icon('inbox fw'), t('admin.webhooks.title')]), admin_webhooks_path, highlights_on: %r{/admin/webhooks} s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_url, if: -> { current_user.admin? && !whitelist_mode? }, highlights_on: %r{/admin/relays} s.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? } s.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? } diff --git a/config/routes.rb b/config/routes.rb index dfce94929..87833539f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -235,6 +235,17 @@ Rails.application.routes.draw do resources :rules + resources :webhooks do + member do + post :enable + post :disable + end + + resource :secret, only: [], controller: 'webhooks/secrets' do + post :rotate + end + end + resources :reports, only: [:index, :show] do resources :actions, only: [:create], controller: 'reports/actions' diff --git a/db/migrate/20220606044941_create_webhooks.rb b/db/migrate/20220606044941_create_webhooks.rb new file mode 100644 index 000000000..cca48fce6 --- /dev/null +++ b/db/migrate/20220606044941_create_webhooks.rb @@ -0,0 +1,12 @@ +class CreateWebhooks < ActiveRecord::Migration[6.1] + def change + create_table :webhooks do |t| + t.string :url, null: false, index: { unique: true } + t.string :events, array: true, null: false, default: [] + t.string :secret, null: false, default: '' + t.boolean :enabled, null: false, default: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 081955660..5d8aea601 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_05_27_114923) do +ActiveRecord::Schema.define(version: 2022_06_06_044941) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -1035,6 +1035,16 @@ ActiveRecord::Schema.define(version: 2022_05_27_114923) do t.index ["user_id"], name: "index_webauthn_credentials_on_user_id" end + create_table "webhooks", force: :cascade do |t| + t.string "url", null: false + t.string "events", default: [], null: false, array: true + t.string "secret", default: "", null: false + t.boolean "enabled", default: true, null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["url"], name: "index_webhooks_on_url", unique: true + end + add_foreign_key "account_aliases", "accounts", on_delete: :cascade add_foreign_key "account_conversations", "accounts", on_delete: :cascade add_foreign_key "account_conversations", "conversations", on_delete: :cascade diff --git a/spec/fabricators/webhook_fabricator.rb b/spec/fabricators/webhook_fabricator.rb new file mode 100644 index 000000000..fa4f17b55 --- /dev/null +++ b/spec/fabricators/webhook_fabricator.rb @@ -0,0 +1,5 @@ +Fabricator(:webhook) do + url { Faker::Internet.url } + secret { SecureRandom.hex } + events { Webhook::EVENTS } +end diff --git a/spec/models/webhook_spec.rb b/spec/models/webhook_spec.rb new file mode 100644 index 000000000..60c3d9524 --- /dev/null +++ b/spec/models/webhook_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +RSpec.describe Webhook, type: :model do + let(:webhook) { Fabricate(:webhook) } + + describe '#rotate_secret!' do + it 'changes the secret' do + previous_value = webhook.secret + webhook.rotate_secret! + expect(webhook.secret).to_not be_blank + expect(webhook.secret).to_not eq previous_value + end + end + + describe '#enable!' do + before do + webhook.disable! + end + + it 'enables the webhook' do + webhook.enable! + expect(webhook.enabled?).to be true + end + end + + describe '#disable!' do + it 'disables the webhook' do + webhook.disable! + expect(webhook.enabled?).to be false + end + end +end diff --git a/spec/validators/url_validator_spec.rb b/spec/validators/url_validator_spec.rb index a44878a44..85eadeb63 100644 --- a/spec/validators/url_validator_spec.rb +++ b/spec/validators/url_validator_spec.rb @@ -19,7 +19,7 @@ RSpec.describe URLValidator, type: :validator do let(:compliant) { false } it 'calls errors.add' do - expect(errors).to have_received(:add).with(attribute, I18n.t('applications.invalid_url')) + expect(errors).to have_received(:add).with(attribute, :invalid) end end -- cgit