diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml
index 99271b127b..34f65a02c2 100644
--- a/.github/workflows/crowdin-download.yml
+++ b/.github/workflows/crowdin-download.yml
@@ -53,7 +53,7 @@ jobs:
# Create or update the pull request
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v5.0.2
+ uses: peter-evans/create-pull-request@v6.0.0
with:
commit-message: 'New Crowdin translations'
title: 'New Crowdin Translations (automated)'
diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml
index 4275f59420..7fd259ae01 100644
--- a/.github/workflows/test-ruby.yml
+++ b/.github/workflows/test-ruby.yml
@@ -224,7 +224,7 @@ jobs:
if: failure()
with:
name: e2e-screenshots
- path: tmp/screenshots/
+ path: tmp/capybara/
test-search:
name: Elastic Search integration testing
@@ -328,4 +328,4 @@ jobs:
if: failure()
with:
name: test-search-screenshots
- path: tmp/screenshots/
+ path: tmp/capybara/
diff --git a/.rubocop.yml b/.rubocop.yml
index 330c40de1b..dce33eab30 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -96,12 +96,6 @@ Rails/FilePath:
Rails/HttpStatus:
EnforcedStyle: numeric
-# Reason: Allowed in boot ENV checker
-# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
-Rails/Exit:
- Exclude:
- - 'config/boot.rb'
-
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
Rails/LexicallyScopedActionFilter:
@@ -134,6 +128,11 @@ Rails/UnusedIgnoredColumns:
Rails/NegateInclude:
Enabled: false
+# Reason: Enforce default limit, but allow some elements to span lines
+# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecexamplelength
+RSpec/ExampleLength:
+ CountAsOne: ['array', 'heredoc', 'method_call']
+
# Reason: Deprecated cop, will be removed in 3.0, replaced by SpecFilePathFormat
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
RSpec/FilePath:
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 367393fc6d..e7d1d08011 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -36,7 +36,7 @@ Metrics/PerceivedComplexity:
# Configuration parameters: CountAsOne.
RSpec/ExampleLength:
- Max: 22
+ Max: 20 # Override default of 5
RSpec/MultipleExpectations:
Max: 7
diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb
index ba85e0a722..e8b0f47cde 100644
--- a/app/controllers/activitypub/inboxes_controller.rb
+++ b/app/controllers/activitypub/inboxes_controller.rb
@@ -62,11 +62,10 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
return if raw_params.blank? || ENV['DISABLE_FOLLOWERS_SYNCHRONIZATION'] == 'true' || signed_request_account.nil?
# Re-using the syntax for signature parameters
- tree = SignatureParamsParser.new.parse(raw_params)
- params = SignatureParamsTransformer.new.apply(tree)
+ params = SignatureParser.parse(raw_params)
ActivityPub::PrepareFollowersSynchronizationService.new.call(signed_request_account, params)
- rescue Parslet::ParseFailed
+ rescue SignatureParser::ParsingError
Rails.logger.warn 'Error parsing Collection-Synchronization header'
end
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index 41c8562363..67d369b859 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -188,7 +188,9 @@ class Auth::SessionsController < Devise::SessionsController
)
# Only send a notification email every hour at most
- return if redis.set("2fa_failure_notification:#{user.id}", '1', ex: 1.hour, get: true).present?
+ return if redis.get("2fa_failure_notification:#{user.id}").present?
+
+ redis.set("2fa_failure_notification:#{user.id}", '1', ex: 1.hour)
UserMailer.failed_2fa(user, request.remote_ip, request.user_agent, Time.now.utc).deliver_later!
end
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 92f1eb5a16..3155866271 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -12,39 +12,6 @@ module SignatureVerification
class SignatureVerificationError < StandardError; end
- class SignatureParamsParser < Parslet::Parser
- rule(:token) { match("[0-9a-zA-Z!#$%&'*+.^_`|~-]").repeat(1).as(:token) }
- rule(:quoted_string) { str('"') >> (qdtext | quoted_pair).repeat.as(:quoted_string) >> str('"') }
- # qdtext and quoted_pair are not exactly according to spec but meh
- rule(:qdtext) { match('[^\\\\"]') }
- rule(:quoted_pair) { str('\\') >> any }
- rule(:bws) { match('\s').repeat }
- rule(:param) { (token.as(:key) >> bws >> str('=') >> bws >> (token | quoted_string).as(:value)).as(:param) }
- rule(:comma) { bws >> str(',') >> bws }
- # Old versions of node-http-signature add an incorrect "Signature " prefix to the header
- rule(:buggy_prefix) { str('Signature ') }
- rule(:params) { buggy_prefix.maybe >> (param >> (comma >> param).repeat).as(:params) }
- root(:params)
- end
-
- class SignatureParamsTransformer < Parslet::Transform
- rule(params: subtree(:param)) do
- (param.is_a?(Array) ? param : [param]).each_with_object({}) { |(key, value), hash| hash[key] = value }
- end
-
- rule(param: { key: simple(:key), value: simple(:val) }) do
- [key, val]
- end
-
- rule(quoted_string: simple(:string)) do
- string.to_s
- end
-
- rule(token: simple(:string)) do
- string.to_s
- end
- end
-
def require_account_signature!
render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account
end
@@ -135,12 +102,8 @@ module SignatureVerification
end
def signature_params
- @signature_params ||= begin
- raw_signature = request.headers['Signature']
- tree = SignatureParamsParser.new.parse(raw_signature)
- SignatureParamsTransformer.new.apply(tree)
- end
- rescue Parslet::ParseFailed
+ @signature_params ||= SignatureParser.parse(request.headers['Signature'])
+ rescue SignatureParser::ParsingError
raise SignatureVerificationError, 'Error parsing signature parameters'
end
diff --git a/app/javascript/mastodon/features/compose/components/upload_button.jsx b/app/javascript/mastodon/features/compose/components/upload_button.jsx
index 3866f239d7..50c9ad6321 100644
--- a/app/javascript/mastodon/features/compose/components/upload_button.jsx
+++ b/app/javascript/mastodon/features/compose/components/upload_button.jsx
@@ -65,6 +65,7 @@ class UploadButton extends ImmutablePureComponent {
key={resetFileKey}
ref={this.setRef}
type='file'
+ name='file-upload-input'
multiple
accept={acceptContentTypes.toArray().join(',')}
onChange={this.handleChange}
diff --git a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx
index f76526e045..c39b43bade 100644
--- a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx
+++ b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx
@@ -21,6 +21,7 @@ import { DisplayName } from 'mastodon/components/display_name';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button';
import { VerifiedBadge } from 'mastodon/components/verified_badge';
+import { domain } from 'mastodon/initial_state';
const messages = defineMessages({
follow: { id: 'account.follow', defaultMessage: 'Follow' },
@@ -28,27 +29,43 @@ const messages = defineMessages({
previous: { id: 'lightbox.previous', defaultMessage: 'Previous' },
next: { id: 'lightbox.next', defaultMessage: 'Next' },
dismiss: { id: 'follow_suggestions.dismiss', defaultMessage: "Don't show again" },
+ friendsOfFriendsHint: { id: 'follow_suggestions.hints.friends_of_friends', defaultMessage: 'This profile is popular among the people you follow.' },
+ similarToRecentlyFollowedHint: { id: 'follow_suggestions.hints.similar_to_recently_followed', defaultMessage: 'This profile is similar to the profiles you have most recently followed.' },
+ featuredHint: { id: 'follow_suggestions.hints.featured', defaultMessage: 'This profile has been hand-picked by the {domain} team.' },
+ mostFollowedHint: { id: 'follow_suggestions.hints.most_followed', defaultMessage: 'This profile is one of the most followed on {domain}.'},
+ mostInteractionsHint: { id: 'follow_suggestions.hints.most_interactions', defaultMessage: 'This profile has been recently getting a lot of attention on {domain}.' },
});
const Source = ({ id }) => {
- let label;
+ const intl = useIntl();
+
+ let label, hint;
switch (id) {
case 'friends_of_friends':
+ hint = intl.formatMessage(messages.friendsOfFriendsHint);
+ label =
rel="me"
, která brání proti napodování vás na webových stránkách s obsahem vytvořeným uživatelem. Můžete dokonce použít odkaz
v záhlaví stránky místo a
, ale HTML musí být přístupné bez spuštění JavaScript.
here_is_how: Jak na to
+ hint_html: "Ověření Vaší identity na Mastodonu je pro každého výborné. Na základě otevřených webových standardů, nyní a navždy zdarma. Jediné, co potřebujete, je osobní webová stránka, na které vás lidé poznají. Když odkazujete na tuto stránku z vašeho profilu, zkontrolujeme, zda webové stránky odkazují na váš profil a zobrazí na něm vizuální indikátor."
instructions_html: Zkopírujte a vložte níže uvedený kód do HTML vašeho webu. Poté přidejte adresu vašeho webu do jednoho z extra políček na vašem profilu na záložce "Upravit profil" a uložte změny.
verification: Ověření
verified_links: Vaše ověřené odkazy
diff --git a/config/locales/de.yml b/config/locales/de.yml
index b77f415190..57ce5268a8 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -979,7 +979,7 @@ de:
next_steps: Du kannst dem Einspruch zustimmen, um die Moderationsentscheidung rückgängig zu machen, oder ihn ignorieren.
subject: "%{username} hat Einspruch gegen eine Moderationsentscheidung auf %{instance} erhoben"
new_critical_software_updates:
- body: Kritische Updates wurden für Mastodon veröffentlicht – du solltest so schnell wie möglich aktualisieren!
+ body: ein neues Sicherheitsupdate wurde veröffentlicht. Du solltest Mastodon so schnell wie möglich aktualisieren!
subject: Kritische Mastodon-Updates sind für %{instance} verfügbar!
new_pending_account:
body: Die Details von diesem neuem Konto sind unten. Du kannst die Anfrage akzeptieren oder ablehnen.
@@ -1023,7 +1023,7 @@ de:
salutation: "%{name},"
settings: 'E-Mail-Einstellungen ändern: %{link}'
unsubscribe: Abbestellen
- view: 'Hier überprüfen:'
+ view: 'Siehe:'
view_profile: Profil anzeigen
view_status: Beitrag anschauen
applications:
diff --git a/config/locales/devise.be.yml b/config/locales/devise.be.yml
index 18785d16ab..81f3120a88 100644
--- a/config/locales/devise.be.yml
+++ b/config/locales/devise.be.yml
@@ -12,6 +12,7 @@ be:
last_attempt: У вас ёсць яшчэ адна спроба, перш чым ваш рахунак будзе заблакаваны
locked: Ваш уліковы запіс заблакіраваны.
not_found_in_database: Няправільны %{authentication_keys} або пароль.
+ omniauth_user_creation_failure: Памылка пры стварэнні ўліковага запісу для гэтай асобы.
pending: Ваш уліковы запіс яшчэ разглядаецца.
timeout: Ваш сеанс скончыўся. Каб працягнуць, увайдзіце яшчэ раз.
unauthenticated: Вам патрэбна зайсьці альбо зарэгістравацца, каб працягнуць
diff --git a/config/locales/devise.bg.yml b/config/locales/devise.bg.yml
index f3586bcd85..116939762c 100644
--- a/config/locales/devise.bg.yml
+++ b/config/locales/devise.bg.yml
@@ -12,6 +12,7 @@ bg:
last_attempt: Разполагате с още един опит преди акаунтът ви да се заключи.
locked: Вашият акаунт е заключен.
not_found_in_database: Невалиден %{authentication_keys} или парола.
+ omniauth_user_creation_failure: Грешка, сътворявайки акаунт за тази самоличност.
pending: Вашият акаунт все още е в процес на проверка.
timeout: Заседанието ви изтече. Влезте пак, за да продължите.
unauthenticated: Преди да продължите, трябва да влезете или да се регистрирате.
diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml
index 3720d3c5f7..9b4ccccff7 100644
--- a/config/locales/devise.ca.yml
+++ b/config/locales/devise.ca.yml
@@ -14,6 +14,7 @@ ca:
last_attempt: Tens un intent més abans no es bloqui el teu compte.
locked: El teu compte s'ha blocat.
not_found_in_database: "%{authentication_keys} o contrasenya no són vàlids."
+ omniauth_user_creation_failure: S'ha produït un error en crear un compte per a aquesta identitat.
pending: El teu compte encara està en revisió.
timeout: La teva sessió ha expirat. Torna a iniciar-la per a continuar.
unauthenticated: Necessites iniciar sessió o registrar-te abans de continuar.
diff --git a/config/locales/devise.cs.yml b/config/locales/devise.cs.yml
index fb3893325c..4dbc2e08bf 100644
--- a/config/locales/devise.cs.yml
+++ b/config/locales/devise.cs.yml
@@ -12,6 +12,7 @@ cs:
last_attempt: Máte ještě jeden pokus, než bude váš účet uzamčen.
locked: Váš účet je uzamčen.
not_found_in_database: Neplatné %{authentication_keys} nebo heslo.
+ omniauth_user_creation_failure: Při vytvoření účtu pro tuto identitu se nastala chyba.
pending: Váš účet je stále posuzován.
timeout: Vaše relace vypršela. Pro pokračování se prosím přihlaste znovu.
unauthenticated: Před pokračováním se musíte přihlásit nebo zaregistrovat.
@@ -47,15 +48,20 @@ cs:
subject: 'Mastodon: Instrukce pro obnovení hesla'
title: Obnovení hesla
two_factor_disabled:
+ explanation: Přihlášení je nyní možné pouze pomocí emailové adresy a hesla.
subject: 'Mastodon: Dvoufázové ověření bylo vypnuto'
- title: 2FA bylo vypnuto
+ subtitle: Dvoufaktorové ověřování vašeho účtu bylo vypnuto.
+ title: Dvoufázové ověření bylo vypnuto
two_factor_enabled:
+ explanation: Pro přihlášení bude vyžadován token generovaný spárovanou TOTP aplikací.
subject: 'Mastodon: Dvoufázové ověření bylo zapnuto'
- title: 2FA bylo zapnuto
+ subtitle: Dvoufaktorové ověřování vašeho účtu bylo zapnuto.
+ title: Dvoufázové ověření bylo zapnuto
two_factor_recovery_codes_changed:
explanation: Předchozí záložní kódy byly zrušeny a byly vygenerovány nové.
- subject: 'Mastodon: Dvoufázové záložní kódy byly znovu vygenerovány'
- title: Záložní kódy pro 2FA byly změněny
+ subject: 'Mastodon: Záložní kódy pro dvoufázové ověření byly znovu vygenerovány'
+ subtitle: Předchozí záložní kódy byly zrušeny a byly vygenerovány nové.
+ title: Záložní kódy pro dvoufázové ověření byly změněny
unlock_instructions:
subject: 'Mastodon: Instrukce pro odemčení účtu'
webauthn_credential:
@@ -68,9 +74,13 @@ cs:
subject: 'Mastodon: Bezpečnostní klíč byl smazán'
title: Jeden z vašich bezpečnostních klíčů byl smazán
webauthn_disabled:
- subject: 'Mastodon: Přihlašování bezpečnostními klíči bylo vypnuto'
+ explanation: 'Mastodon: Přihlašování pomocí bezpečnostními klíčemi bylo pro váš účet vypnuto.'
+ extra: Přihlášení je nyní možné pouze pomocí tokenem vygenerovaný spárovanou TOTP aplikací.
+ subject: 'Mastodon: Přihlašování pomocí bezpečnostními klíčemi bylo vypnuto'
title: Bezpečnostní klíče byly zakázány
webauthn_enabled:
+ explanation: 'Mastodon: Přihlašování bezpečnostními klíči bylo pro váš účet povoleno.'
+ extra: Váš bezpečnostní klíč nyní může být použit pro přihlášení.
subject: 'Mastodon: Přihlašování bezpečnostními klíči bylo povoleno'
title: Bezpečnostní klíče byly povoleny
omniauth_callbacks:
diff --git a/config/locales/devise.cy.yml b/config/locales/devise.cy.yml
index d3eeb8eeb6..523ae70b04 100644
--- a/config/locales/devise.cy.yml
+++ b/config/locales/devise.cy.yml
@@ -12,6 +12,7 @@ cy:
last_attempt: Mae gennych un cyfle arall cyn i'ch cyfrif gael ei gloi.
locked: Mae eich cyfrif wedi ei gloi.
not_found_in_database: "%{authentication_keys} neu gyfrinair annilys."
+ omniauth_user_creation_failure: Gwall wrth greu cyfrif ar gyfer yr hunaniaeth hon.
pending: Mae eich cyfrif dal o dan adolygiad.
timeout: Mae eich sesiwn wedi dod i ben. Mewngofnodwch eto i barhau.
unauthenticated: Mae angen i chi fewngofnodi neu gofrestru cyn parhau.
diff --git a/config/locales/devise.da.yml b/config/locales/devise.da.yml
index daf802cdb7..c472242ba7 100644
--- a/config/locales/devise.da.yml
+++ b/config/locales/devise.da.yml
@@ -12,6 +12,7 @@ da:
last_attempt: Du har ét forsøg mere, før din konto bliver låst.
locked: Din konto er låst.
not_found_in_database: Ugyldig %{authentication_keys} eller adgangskode.
+ omniauth_user_creation_failure: Fejl under oprettelse af konto for denne identitet.
pending: Din konto er stadig under revision.
timeout: Session udløbet. Log ind igen for at fortsætte.
unauthenticated: Log ind eller tilmeld dig for at fortsætte.
diff --git a/config/locales/devise.de.yml b/config/locales/devise.de.yml
index cf05ddc16b..7982f8a743 100644
--- a/config/locales/devise.de.yml
+++ b/config/locales/devise.de.yml
@@ -12,6 +12,7 @@ de:
last_attempt: Du hast nur noch einen Versuch, bevor dein Zugang gesperrt wird.
locked: Dein Konto ist gesperrt.
not_found_in_database: "%{authentication_keys} oder Passwort ungültig."
+ omniauth_user_creation_failure: Fehler beim Erstellen eines Kontos für diese Identität.
pending: Dein Konto wird weiterhin überprüft.
timeout: Deine Sitzung ist abgelaufen. Bitte melde dich erneut an, um fortzufahren.
unauthenticated: Du musst dich anmelden oder registrieren, bevor du fortfahren kannst.
diff --git a/config/locales/devise.es-AR.yml b/config/locales/devise.es-AR.yml
index ca60ee5deb..6249294597 100644
--- a/config/locales/devise.es-AR.yml
+++ b/config/locales/devise.es-AR.yml
@@ -12,6 +12,7 @@ es-AR:
last_attempt: Tenés un intento más antes de que se bloquee tu cuenta.
locked: Se bloqueó tu cuenta.
not_found_in_database: "%{authentication_keys} o contraseña no válidas."
+ omniauth_user_creation_failure: Error al crear una cuenta para esta identidad.
pending: Tu cuenta todavía está bajo revisión.
timeout: Venció tu sesión. Por favor, volvé a iniciar sesión para continuar.
unauthenticated: Necesitás iniciar sesión o registrarte antes de continuar.
diff --git a/config/locales/devise.eu.yml b/config/locales/devise.eu.yml
index 624f9ee93d..3e675659fe 100644
--- a/config/locales/devise.eu.yml
+++ b/config/locales/devise.eu.yml
@@ -12,6 +12,7 @@ eu:
last_attempt: Saiakera bat geratzen zaizu zure kontua giltzapetu aurretik.
locked: Zure kontua giltzapetuta dago.
not_found_in_database: Baliogabeko %{authentication_keys} edo pasahitza.
+ omniauth_user_creation_failure: Errorea identitate honen kontu bat sortzean.
pending: Zure kontua oraindik berrikusteke dago.
timeout: Zure saioa iraungitu da. Hasi saioa berriro jarraitzeko.
unauthenticated: Saioa hasi edo izena eman behar duzu jarraitu aurretik.
diff --git a/config/locales/devise.fi.yml b/config/locales/devise.fi.yml
index 66616d16b1..003d48417b 100644
--- a/config/locales/devise.fi.yml
+++ b/config/locales/devise.fi.yml
@@ -12,6 +12,7 @@ fi:
last_attempt: Sinulla on vielä yksi yritys ennen kuin tilisi lukitaan.
locked: Tilisi on lukittu.
not_found_in_database: Virheellinen %{authentication_keys} tai salasana.
+ omniauth_user_creation_failure: Virhe luotaessa tiliä tälle henkilöllisyydelle.
pending: Tilisi on vielä tarkistamatta.
timeout: Istuntosi on vanhentunut. Jatkaaksesi käyttöä, kirjaudu uudelleen.
unauthenticated: Sinun on kirjauduttava tai rekisteröidyttävä ennen kuin voit jatkaa.
diff --git a/config/locales/devise.fo.yml b/config/locales/devise.fo.yml
index 1f7708bb44..30f83ba0da 100644
--- a/config/locales/devise.fo.yml
+++ b/config/locales/devise.fo.yml
@@ -12,6 +12,7 @@ fo:
last_attempt: Tú kanst royna einaferð afturat áðrenn kontan verður stongd.
locked: Kontan hjá tær er læst.
not_found_in_database: Ogyldigur %{authentication_keys} ella loyniorð.
+ omniauth_user_creation_failure: Feilur í sambandi við, at ein konta fyri hendan samleikan bleiv stovnað.
pending: Kontan hjá tær verður kannað enn.
timeout: Tín innritan er útgingin. Innrita av nýggjum, fyri at hada fram.
unauthenticated: Tú mást skriva teg inn aftur fyri at halda fram.
diff --git a/config/locales/devise.fy.yml b/config/locales/devise.fy.yml
index 05fd7b8071..c8a04a7405 100644
--- a/config/locales/devise.fy.yml
+++ b/config/locales/devise.fy.yml
@@ -12,6 +12,7 @@ fy:
last_attempt: Jo hawwe noch ien besykjen oer eardat jo account blokkearre wurdt.
locked: Jo account is blokkearre.
not_found_in_database: "%{authentication_keys} of wachtwurd ûnjildich."
+ omniauth_user_creation_failure: Flater by it oanmeitsjen fan in account foar dizze identiteit.
pending: Jo account moat noch hieltyd beoardiele wurde.
timeout: Jo sesje is ferrûn. Meld jo opnij oan om troch te gean.
unauthenticated: Jo moatte oanmelde of registrearje.
diff --git a/config/locales/devise.gl.yml b/config/locales/devise.gl.yml
index b9f4a0a005..00b1824808 100644
--- a/config/locales/devise.gl.yml
+++ b/config/locales/devise.gl.yml
@@ -12,6 +12,7 @@ gl:
last_attempt: Tes un intento máis antes de que a túa conta fique bloqueada.
locked: A túa conta está bloqueada.
not_found_in_database: "%{authentication_keys} ou contrasinal non válidos."
+ omniauth_user_creation_failure: Erro ao crear unha conta para esta identidade.
pending: A túa conta aínda está baixo revisión.
timeout: A túa sesión caducou. Accede outra vez para continuar.
unauthenticated: Precisas iniciar sesión ou rexistrarte antes de continuar.
diff --git a/config/locales/devise.he.yml b/config/locales/devise.he.yml
index f2ec3a6716..02e307ae1c 100644
--- a/config/locales/devise.he.yml
+++ b/config/locales/devise.he.yml
@@ -12,6 +12,7 @@ he:
last_attempt: יש לך עוד ניסיון אחד לפני נעילת החשבון.
locked: חשבון זה נעול.
not_found_in_database: "%{authentication_keys} או סיסמה לא נכונים."
+ omniauth_user_creation_failure: שגיאה ביצירת חשבון לזהות הזו.
pending: חשבונך נמצא עדיין בבדיקה.
timeout: פג תוקף השהיה בחשבון. נא להכנס מחדש על מנת להמשיך.
unauthenticated: יש להרשם או להכנס לחשבון על מנת להמשיך.
diff --git a/config/locales/devise.hu.yml b/config/locales/devise.hu.yml
index fea56ab24a..8c9fdf6a50 100644
--- a/config/locales/devise.hu.yml
+++ b/config/locales/devise.hu.yml
@@ -12,6 +12,7 @@ hu:
last_attempt: Már csak egy próbálkozásod maradt, mielőtt a fiókodat zároljuk.
locked: A fiókodat zároltuk.
not_found_in_database: Helytelen %{authentication_keys} vagy jelszó.
+ omniauth_user_creation_failure: Hiba történt a fiók létrehozása során ehhez az identitáshoz.
pending: A fiókod még engedélyezésre vár.
timeout: A munkameneted lejárt. A folytatáshoz jelentkezz be újra.
unauthenticated: A folytatás előtt be kell jelentkezned vagy regisztrálnod kell.
diff --git a/config/locales/devise.ia.yml b/config/locales/devise.ia.yml
index c07e75feff..4b4d1f441b 100644
--- a/config/locales/devise.ia.yml
+++ b/config/locales/devise.ia.yml
@@ -39,6 +39,8 @@ ia:
webauthn_enabled:
title: Claves de securitate activate
registrations:
+ destroyed: A revider! Tu conto esseva cancellate con successo. Nos spera vider te novemente tosto.
+ signed_up_but_pending: Un message con un ligamine de confirmation esseva inviate a tu conto de email. Post que tu clicca le ligamine, nos revidera tu application. Tu essera notificate si illo es approbate.
updated: Tu conto ha essite actualisate con successo.
unlocks:
unlocked: Tu conto ha essite disblocate con successo. Initia session a continuar.
diff --git a/config/locales/devise.ie.yml b/config/locales/devise.ie.yml
index 332c9da456..9c82bd4529 100644
--- a/config/locales/devise.ie.yml
+++ b/config/locales/devise.ie.yml
@@ -12,6 +12,7 @@ ie:
last_attempt: Hay solmen un prova ante que tui conto deveni serrat.
locked: Tui conto es serrat.
not_found_in_database: Ínvalid %{authentication_keys} o passa-parol.
+ omniauth_user_creation_failure: Errore in li creation de un conto por ti-ci identitá.
pending: Tui conto es ancor sub revision.
timeout: Tui session ha expirat. Ples reintrar denov por continuar.
unauthenticated: Tu deve intrar o registrar te ante continuar.
diff --git a/config/locales/devise.is.yml b/config/locales/devise.is.yml
index 12015fa29d..a045bdd80c 100644
--- a/config/locales/devise.is.yml
+++ b/config/locales/devise.is.yml
@@ -12,6 +12,7 @@ is:
last_attempt: Þú getur reynt einu sinni í viðbót áður en aðgangnum þínum verður læst.
locked: Notandaaðgangurinn þinn er læstur.
not_found_in_database: Ógilt %{authentication_keys} eða lykilorð.
+ omniauth_user_creation_failure: Villa við að útbúa aðgang fyrir þetta auðkenni.
pending: Notandaaðgangurinn þinn er enn til yfirferðar.
timeout: Setan þín er útrunnin. Skráðu þig aftur inn til að halda áfram.
unauthenticated: Þú þarft að skrá þig inn eða nýskrá þig áður en lengra er haldið.
diff --git a/config/locales/devise.it.yml b/config/locales/devise.it.yml
index 19bd999aad..8aaea3c15b 100644
--- a/config/locales/devise.it.yml
+++ b/config/locales/devise.it.yml
@@ -12,6 +12,7 @@ it:
last_attempt: Hai un altro tentativo, prima che il tuo profilo venga bloccato.
locked: Il tuo profilo è bloccato.
not_found_in_database: "%{authentication_keys} o password non valida."
+ omniauth_user_creation_failure: Errore nella creazione di un account per questa identità.
pending: Il tuo profilo è ancora in revisione.
timeout: La tua sessione è scaduta. Sei pregato di accedere nuovamente per continuare.
unauthenticated: Devi accedere o registrarti, per continuare.
diff --git a/config/locales/devise.kab.yml b/config/locales/devise.kab.yml
index 2f60629fd7..f878a5b503 100644
--- a/config/locales/devise.kab.yml
+++ b/config/locales/devise.kab.yml
@@ -13,13 +13,13 @@ kab:
locked: Amiḍan-ik yettwargel.
not_found_in_database: Tella tuccḍa deg %{authentication_keys} neγ deg wawal uffir.
pending: Amiḍan-inek mazal-it deg ɛiwed n tmuγli.
- timeout: Tiγimit n tuqqna tezri. Ma ulac aγilif ɛiwed tuqqna akken ad tkemmleḍ.
- unauthenticated: Ilaq ad teqqneḍ neγ ad tjerrḍeḍ akken ad tkemmelḍ.
+ timeout: Tiɣimit n tuqqna tezri. Ma ulac aɣilif ɛiwed tuqqna akken ad tkemmleḍ.
+ unauthenticated: Ilaq ad teqqneḍ neɣ ad tjerrḍeḍ akken ad tkemmelḍ.
unconfirmed: Ilaq ad wekdeḍ tansa-inek imayl akken ad tkemmelḍ.
mailer:
confirmation_instructions:
action: Senqed tansa-inek imayl
- action_with_app: Wekked sakkin uγal γer %{app}
+ action_with_app: Sentem sakkin uɣal ɣer %{app}
explanation: Aqla-k terniḍ amiḍan deg %{host} s tansa imayl-agi. Mazal-ak yiwen utekki akken ad t-tremdeḍ. Ma mačči d kečč i yessutren ay-agi, ttxil-k ssinef izen-a.
explanation_when_pending: Tsutreḍ-d ajerred deg %{host} s tansa-agi imayl. Ad nγeṛ asuter-ik ticki tsentmeḍ tansa-ik imayl. Send asentem, ur tezmireḍ ara ad teqqneḍ γer umiḍan-ik. Ma yella nugi asuter-ik, isefka-ik ad ttwakksen seg uqeddac, ihi ulac tigawt-nniḍen ara k-d-yettuqeblen. Ma mačči d kečč i yellan deffir n usuter-agi, ttxil-k ssinef izen-agi.
extra_html: Ttxil-k ẓer daγen ilugan n uqeddac akked twetlin n useqdec-nneγ.
@@ -87,7 +87,7 @@ kab:
unlocks:
send_instructions: Deg kra n tesdatin, ad teṭṭfeḍ imayl deg-s iwellihen i yilaqen i userreḥ n umiḍan-ik·im. Ma yella ur tufiḍ ara izen-agi, ttxil-k·m ẓer deg ukaram spam.
send_paranoid_instructions: Ma yella umiḍan-ik·im yella, ad teṭṭfeḍ imayl deg tesdatin i d-iteddun, deg-s iwellihen i yilaqen i userreḥ n umiḍan-ik·im. Ma yella ur tufiḍ ara izen-agi, ttxil-k·m ẓer deg ukaram spam.
- unlocked: Iserreḥ umiḍan-ik·im akken iwata. ttxil qqen akken ad tkemleḍ.
+ unlocked: Iserreḥ umiḍan-ik·im akken iwata. Ttxil qqen akken ad tkemleḍ.
errors:
messages:
already_confirmed: ittwasentem yakan, ttxil εreḍ ad teqneḍ
diff --git a/config/locales/devise.ko.yml b/config/locales/devise.ko.yml
index 0c848e4bac..198d44a4f7 100644
--- a/config/locales/devise.ko.yml
+++ b/config/locales/devise.ko.yml
@@ -12,6 +12,7 @@ ko:
last_attempt: 계정이 잠기기까지 한 번의 시도가 남았습니다.
locked: 계정이 잠겼습니다.
not_found_in_database: 올바르지 않은 %{authentication_keys} 혹은 암호입니다.
+ omniauth_user_creation_failure: 이 신원으로 계정을 만드는데 실패했습니다.
pending: 이 계정은 아직 검토 중입니다.
timeout: 세션이 만료되었습니다. 다시 로그인 하세요.
unauthenticated: 계속 하려면 로그인을 해야 합니다.
diff --git a/config/locales/devise.lad.yml b/config/locales/devise.lad.yml
index 88099f48c4..7d447140f4 100644
--- a/config/locales/devise.lad.yml
+++ b/config/locales/devise.lad.yml
@@ -12,6 +12,7 @@ lad:
last_attempt: Aprova una vez mas antes de ke tu kuento sea blokado.
locked: Tu kuento esta blokado.
not_found_in_database: Inkorekto %{authentication_keys} o kod.
+ omniauth_user_creation_failure: Ay un error en kriyar un kuento para esta identita.
pending: Tu kuento ainda esta basho revizyon.
timeout: Tu sesyon tiene kadukado. Por favor konektate kon tu kuento de muevo para kontinuar.
unauthenticated: Kale konektarte kon tu kuento o enregistrarte antes de kontinuar.
@@ -89,25 +90,25 @@ lad:
no_token: No puedes akseder a esta pajina si no vienes dizde una posta elektronika de restablesimyento de kod. Si vienes dizde una posta elektronika de restablesimyento de kod, por favor asigurate de utilizar el URL kompleto embiado.
send_instructions: Si tu adreso de posta elektronika existe en muestra baza de datos, risiviras un atadijo de rekuperasyon de kod en tu adreso de posta elektronika en pokos minutos. Por favor, komprova tu kuti de posta spam si no risives akeya posta elektronika.
send_paranoid_instructions: Si tu adreso de posta elektronika existe en muestra baza de datos, risiviras un atadijo de rekuperasyon de kod en tu adreso de posta elektronika en pokos minutos. Por favor, komprova tu kuti de posta no deseado si no risives akeya posta elektronika.
- updated: Tu kod a sido trokado kon reusho. Tyenes entrado en kuento.
- updated_not_active: Tu kod se tiene trokado kon reusho.
+ updated: Tu kod a sido trokado kon reushita. Tyenes entrado en kuento.
+ updated_not_active: Tu kod se tiene trokado kon reushita.
registrations:
- destroyed: Tu kuento a sido efasado kon reusho. Asperamos verte de muevo pronto.
+ destroyed: Tu kuento a sido efasado kon reushita. Asperamos verte de muevo pronto.
signed_up: Bienvenido! Te tienes enrejistrado djustamente.
- signed_up_but_inactive: Te tienes enrejistrado kon reusho. Entanto, no se pudio inisyar sesyon porke tu kuento ainda no esta aktivado.
- signed_up_but_locked: Te tienes enrejistrado kon reusho. Entanto, no pudites konektarte kon tu kuento porke tu kuento esta blokado.
+ signed_up_but_inactive: Te tienes enrejistrado kon reushita. Entanto, no se pudio inisyar sesyon porke tu kuento ainda no esta aktivado.
+ signed_up_but_locked: Te tienes enrejistrado kon reushita. Entanto, no pudites konektarte kon tu kuento porke tu kuento esta blokado.
signed_up_but_pending: Un mesaj kon un atadijo de konfirmasyon a sido enviado a tu adreso de posta elektronika. Dempues de klikar en el atadijo, revizaremos tu solisitud. Seras avizado si se acheta.
signed_up_but_unconfirmed: Un mesaj kon un atadijo de konfirmasyon a sido enviado a tu adreso de posta elektronika. Por favor, sigue el atadijo para aktivar tu kuento. Por favor, komprova tu kuti de posta spam si no risives akeya posta elektronika.
- update_needs_confirmation: Tienes aktualizado tu kuento kon reusho, pero kale verifikar tu muevo adreso de posta elektronika. Por favor, komprova tu posta elektronika i sige el atadijo de konfirmasyon para konfirmar tu muevo adreso de posta elektronika. Por favor, komprova tu kuti de posta spam si no risives akeya posta elektronika.
- updated: Tu kuento se aktualizo kon reusho.
+ update_needs_confirmation: Tienes aktualizado tu kuento kon reushita, pero kale verifikar tu muevo adreso de posta elektronika. Por favor, komprova tu posta elektronika i sige el atadijo de konfirmasyon para konfirmar tu muevo adreso de posta elektronika. Por favor, komprova tu kuti de posta spam si no risives akeya posta elektronika.
+ updated: Tu kuento se aktualizo kon reushita.
sessions:
- already_signed_out: Salites del kuento kon reusho.
- signed_in: Konektates kon tu kuento kon reusho.
- signed_out: Salites del kuento kon reusho.
+ already_signed_out: Salites del kuento kon reushita.
+ signed_in: Konektates kon tu kuento kon reushita.
+ signed_out: Salites del kuento kon reushita.
unlocks:
send_instructions: En unos minutos risiviras una posta elektronika kon instruksyones para dezblokar tu kuento. Por favor, komprova tu kuti de posta spam si no risives akeya posta elektronika.
send_paranoid_instructions: Si tu kuento existe, en unos minutos risiviras una posta elektronika kon instruksyones para dezblokarlo. Por favor, reviza tu kuti de posta spam si no risives akeya posta elektronika.
- unlocked: Tu kuento fue dezblokado kon reusho. Por favor, konektate kon tu kuento para kontinuar.
+ unlocked: Tu kuento fue dezblokado kon reushita. Por favor, konektate kon tu kuento para kontinuar.
errors:
messages:
already_confirmed: ya estaba konfirmado, por favor aprova konektarte kon tu kuento
diff --git a/config/locales/devise.lt.yml b/config/locales/devise.lt.yml
index 3fba5ed08e..548894cca0 100644
--- a/config/locales/devise.lt.yml
+++ b/config/locales/devise.lt.yml
@@ -12,6 +12,7 @@ lt:
last_attempt: Turi dar vieną bandymą, kol tavo paskyra bus užrakinta.
locked: Tavo paskyra užrakinta.
not_found_in_database: Netinkami %{authentication_keys} arba slaptažodis.
+ omniauth_user_creation_failure: Klaida kuriant šios tapatybės paskyrą.
pending: Tavo paskyra vis dar peržiūrima.
timeout: Tavo seansas baigėsi. Norėdamas (-a) tęsti, prisijunk dar kartą.
unauthenticated: Prieš tęsdamas (-a) turi prisijungti arba užsiregistruoti.
diff --git a/config/locales/devise.nl.yml b/config/locales/devise.nl.yml
index 0aaf376f7f..ab6ae84db4 100644
--- a/config/locales/devise.nl.yml
+++ b/config/locales/devise.nl.yml
@@ -12,6 +12,7 @@ nl:
last_attempt: Je hebt nog één poging over voordat jouw account wordt opgeschort.
locked: Jouw account is opgeschort.
not_found_in_database: "%{authentication_keys} of wachtwoord ongeldig."
+ omniauth_user_creation_failure: Fout bij het aanmaken van een account voor deze identiteit.
pending: Jouw account moet nog steeds worden beoordeeld.
timeout: Jouw sessie is verlopen, log opnieuw in.
unauthenticated: Je dient in te loggen of te registreren.
diff --git a/config/locales/devise.pl.yml b/config/locales/devise.pl.yml
index a6d48f11ef..f34fd04633 100644
--- a/config/locales/devise.pl.yml
+++ b/config/locales/devise.pl.yml
@@ -12,6 +12,7 @@ pl:
last_attempt: Masz jeszcze jedną próbę; Twoje konto zostanie zablokowane jeśli się nie powiedzie.
locked: Twoje konto zostało zablokowane.
not_found_in_database: Nieprawidłowy %{authentication_keys} lub hasło.
+ omniauth_user_creation_failure: Błąd przy tworzeniu konta dla tej tożsamości.
pending: Twoje konto oczekuje na przegląd.
timeout: Twoja sesja wygasła. Zaloguj się ponownie, aby kontynuować..
unauthenticated: Zapisz się lub zaloguj, aby kontynuować.
diff --git a/config/locales/devise.pt-PT.yml b/config/locales/devise.pt-PT.yml
index c169ddeb97..c66181fc5b 100644
--- a/config/locales/devise.pt-PT.yml
+++ b/config/locales/devise.pt-PT.yml
@@ -12,6 +12,7 @@ pt-PT:
last_attempt: Tem só mais uma tentativa antes da sua conta ser bloqueada.
locked: A tua conta está bloqueada.
not_found_in_database: "%{authentication_keys} ou palavra-passe inválida."
+ omniauth_user_creation_failure: Erro ao criar uma conta para esta identidade.
pending: A sua conta está ainda a aguardar revisão.
timeout: A tua sessão expirou. Por favor, entra de novo para continuares.
unauthenticated: Precisas de entrar na tua conta ou de te registares antes de continuar.
diff --git a/config/locales/devise.ro.yml b/config/locales/devise.ro.yml
index 1a6a3ecd77..868bb4b3a1 100644
--- a/config/locales/devise.ro.yml
+++ b/config/locales/devise.ro.yml
@@ -47,14 +47,19 @@ ro:
subject: Instrucțiuni pentru resetarea parolei
title: Resetare parolă
two_factor_disabled:
+ explanation: Conectarea este acum posibilă folosind doar adresa de e-mail și parola.
subject: Autentificare cu doi factori dezactivată
+ subtitle: Autentificarea cu doi factori pentru contul dvs. a fost dezactivată.
title: 2FA dezactivat
two_factor_enabled:
+ explanation: Pentru autentificare va fi necesar un token generat de aplicația TOTP asociată.
subject: Autentificare în doi pași activată
+ subtitle: Autentificarea cu doi factori a fost activată pentru contul dvs.
title: 2FA activat
two_factor_recovery_codes_changed:
explanation: Codurile anterioare de recuperare au fost invalidate și unele noi generate.
subject: Recuperare în doi factori
+ subtitle: Codurile de recuperare anterioare au fost invalidate și s-au generat altele noi.
title: Coduri de recuperare 2FA modificate
unlock_instructions:
subject: Instrucțiuni de deblocare
@@ -68,9 +73,13 @@ ro:
subject: 'Mastodon: Cheie de securitate ștearsă'
title: Una dintre cheile tale de securitate a fost ștearsă
webauthn_disabled:
+ explanation: Autentificarea cu chei de securitate a fost dezactivată pentru contul dvs.
+ extra: Conectarea este acum posibilă folosind doar token-ul generat de aplicația TOTP asociată.
subject: 'Mastodon: Autentificarea cu chei de securitate dezactivată'
title: Chei de securitate dezactivate
webauthn_enabled:
+ explanation: Autentificarea cu cheie de securitate a fost activată pentru contul dvs.
+ extra: Cheia ta de securitate poate fi acum folosită pentru conectare.
subject: 'Mastodon: Autentificarea cheii de securitate activată'
title: Chei de securitate activate
omniauth_callbacks:
diff --git a/config/locales/devise.sk.yml b/config/locales/devise.sk.yml
index 3eb4b5304c..bc01b73ccf 100644
--- a/config/locales/devise.sk.yml
+++ b/config/locales/devise.sk.yml
@@ -12,6 +12,7 @@ sk:
last_attempt: Máš posledný pokus pred zamknutím tvojho účtu.
locked: Tvoj účet je zamknutý.
not_found_in_database: Nesprávny %{authentication_keys}, alebo heslo.
+ omniauth_user_creation_failure: Chyba pri vytváraní účtu pre túto identitu.
pending: Tvoj účet je stále prehodnocovaný.
timeout: Tvoja aktívna sezóna vypršala. Pre pokračovanie sa prosím prihlás znovu.
unauthenticated: K pokračovaniu sa musíš zaregistrovať alebo prihlásiť.
diff --git a/config/locales/devise.sl.yml b/config/locales/devise.sl.yml
index 2d567e63f4..0eb9b6330a 100644
--- a/config/locales/devise.sl.yml
+++ b/config/locales/devise.sl.yml
@@ -12,6 +12,7 @@ sl:
last_attempt: Pred zaklepom računa imate še en poskus.
locked: Vaš račun je zaklenjen.
not_found_in_database: Neveljavno %{authentication_keys} ali geslo.
+ omniauth_user_creation_failure: Napaka pri ustvarjanju računa za to identiteto.
pending: Vaš račun je še vedno pod drobnogledom.
timeout: Vaša seja je potekla. Če želite nadaljevati, se znova prijavite.
unauthenticated: Pred nadaljevanjem se morate prijaviti ali vpisati.
diff --git a/config/locales/devise.sq.yml b/config/locales/devise.sq.yml
index 32136a0baa..76dd493245 100644
--- a/config/locales/devise.sq.yml
+++ b/config/locales/devise.sq.yml
@@ -12,6 +12,7 @@ sq:
last_attempt: Mund të provoni edhe një herë, përpara se llogaria juaj të kyçet.
locked: Llogaria juaj është e kyçur.
not_found_in_database: "%{authentication_keys} ose fjalëkalim i pavlefshëm."
+ omniauth_user_creation_failure: Gabim në krijim llogarie për këtë identitet.
pending: Llogaria juaj është ende nën shqyrtim.
timeout: Sesioni juaj ka skaduar. Ju lutemi, që të vazhdohet, ribëni hyrjen.
unauthenticated: Përpara se të vazhdohet më tej, lypset të bëni hyrjen ose të regjistroheni.
diff --git a/config/locales/devise.sr-Latn.yml b/config/locales/devise.sr-Latn.yml
index c48ed87dca..3947b2d84f 100644
--- a/config/locales/devise.sr-Latn.yml
+++ b/config/locales/devise.sr-Latn.yml
@@ -12,6 +12,7 @@ sr-Latn:
last_attempt: Imate još jedan pokušaj pre nego što Vaš nalog bude zaključan.
locked: Vaš nalog je zaključan.
not_found_in_database: Neispravna %{authentication_keys} ili lozinka.
+ omniauth_user_creation_failure: Greška pri kreiranju naloga za ovaj identitet.
pending: Vaš račun je još uvek u pregledu.
timeout: Vreme trajanja Vaše sesije je isteklo. Za nastavak prijavite se ponovo.
unauthenticated: Za nastavak se morate prijaviti ili registrovati.
diff --git a/config/locales/devise.sr.yml b/config/locales/devise.sr.yml
index 3e49cf97ee..a4c08dfaf0 100644
--- a/config/locales/devise.sr.yml
+++ b/config/locales/devise.sr.yml
@@ -12,6 +12,7 @@ sr:
last_attempt: Имате још један покушај пре него што Ваш налог буде закључан.
locked: Ваш налог је закључан.
not_found_in_database: Неисправна %{authentication_keys} или лозинка.
+ omniauth_user_creation_failure: Грешка при креирању налога за овај идентитет.
pending: Ваш налог се још увек прегледа.
timeout: Ваша сесија је истекла. Пријавите се поново да бисте наставили.
unauthenticated: Морате да се пријавите или региструјете пре него што наставите.
diff --git a/config/locales/devise.th.yml b/config/locales/devise.th.yml
index 40baabcf75..50e2e4b29e 100644
--- a/config/locales/devise.th.yml
+++ b/config/locales/devise.th.yml
@@ -12,6 +12,7 @@ th:
last_attempt: คุณลองได้อีกหนึ่งครั้งก่อนที่จะมีการล็อคบัญชีของคุณ
locked: มีการล็อคบัญชีของคุณอยู่
not_found_in_database: "%{authentication_keys} หรือรหัสผ่านไม่ถูกต้อง"
+ omniauth_user_creation_failure: เกิดข้อผิดพลาดในการสร้างบัญชีสำหรับข้อมูลประจำตัวนี้
pending: บัญชีของคุณยังคงอยู่ระหว่างการตรวจทาน
timeout: เซสชันของคุณหมดอายุแล้ว โปรดเข้าสู่ระบบอีกครั้งเพื่อดำเนินการต่อ
unauthenticated: คุณจำเป็นต้องเข้าสู่ระบบหรือลงทะเบียนก่อนดำเนินการต่อ
diff --git a/config/locales/devise.tok.yml b/config/locales/devise.tok.yml
new file mode 100644
index 0000000000..d15ecd21b2
--- /dev/null
+++ b/config/locales/devise.tok.yml
@@ -0,0 +1 @@
+tok:
diff --git a/config/locales/devise.tr.yml b/config/locales/devise.tr.yml
index 66ca9b2816..e709d3fff1 100644
--- a/config/locales/devise.tr.yml
+++ b/config/locales/devise.tr.yml
@@ -12,6 +12,7 @@ tr:
last_attempt: Hesabınız kilitlenmeden önce bir kez daha denemeniz gerekir.
locked: Hesabınız kilitlendi.
not_found_in_database: Geçersiz %{authentication_keys} ya da parola.
+ omniauth_user_creation_failure: Bu kimlik için hesap oluşturmada hata.
pending: Hesabınız hala inceleniyor.
timeout: Oturum süreniz sona erdi. Lütfen devam etmek için tekrar giriş yapınız.
unauthenticated: Devam etmeden önce oturum açmanız veya kayıt olmanız gerek.
diff --git a/config/locales/devise.uk.yml b/config/locales/devise.uk.yml
index 3b3883fa9c..65e89a274f 100644
--- a/config/locales/devise.uk.yml
+++ b/config/locales/devise.uk.yml
@@ -12,6 +12,7 @@ uk:
last_attempt: У вас залишилась ще одна спроба, після якої ваш обліковий запис буде заблоковано.
locked: Ваш обліковий запис заблоковано.
not_found_in_database: Неправильний %{authentication_keys} або пароль.
+ omniauth_user_creation_failure: Помилка створення облікового запису для цієї особи.
pending: Ваш обліковий запис ще перебуває на розгляді.
timeout: Час сеансу минув. Будь ласка, увійдіть знову, щоб продовжити.
unauthenticated: Щоб продовжити, увійдіть або зареєструйтеся.
diff --git a/config/locales/devise.vi.yml b/config/locales/devise.vi.yml
index 190f7282c4..6ae78f83cc 100644
--- a/config/locales/devise.vi.yml
+++ b/config/locales/devise.vi.yml
@@ -12,6 +12,7 @@ vi:
last_attempt: Nếu thử sai lần nữa, tài khoản của bạn sẽ bị khóa.
locked: Tài khoản của bạn bị khóa.
not_found_in_database: "%{authentication_keys} không có trong dữ liệu."
+ omniauth_user_creation_failure: Xảy ra lỗi khi tạo tài khoản này.
pending: Tài khoản của bạn vẫn đang được xem xét.
timeout: Phiên của bạn đã hết hạn. Vui lòng đăng nhập lại để tiếp tục.
unauthenticated: Bạn cần đăng nhập để tiếp tục.
diff --git a/config/locales/devise.zh-CN.yml b/config/locales/devise.zh-CN.yml
index 9b4b3ae203..3eb722b961 100644
--- a/config/locales/devise.zh-CN.yml
+++ b/config/locales/devise.zh-CN.yml
@@ -12,6 +12,7 @@ zh-CN:
last_attempt: 你只有最后一次尝试机会,若未通过,帐号将被锁定。
locked: 你的账户已被锁定。
not_found_in_database: "%{authentication_keys}或密码错误。"
+ omniauth_user_creation_failure: 为此身份创建账户时出错。
pending: 你的账号仍在审核中。
timeout: 你的会话已过期。请重新登录再继续操作。
unauthenticated: 继续操作前请注册或者登录。
diff --git a/config/locales/devise.zh-HK.yml b/config/locales/devise.zh-HK.yml
index 7f728bf0ad..a2620a8e4a 100644
--- a/config/locales/devise.zh-HK.yml
+++ b/config/locales/devise.zh-HK.yml
@@ -12,6 +12,7 @@ zh-HK:
last_attempt: 若你再一次嘗試失敗,我們將鎖定你的帳號,以策安全。
locked: 你的帳號已被鎖定。
not_found_in_database: 不正確的%{authentication_keys}或密碼。
+ omniauth_user_creation_failure: 為此身份建立帳號時出錯。
pending: 你的帳號仍在審核中
timeout: 你的登入階段已經過期,請重新登入以繼續使用。
unauthenticated: 你必須先登入或登記,以繼續使用。
diff --git a/config/locales/devise.zh-TW.yml b/config/locales/devise.zh-TW.yml
index 06438971a7..7ead831e4f 100644
--- a/config/locales/devise.zh-TW.yml
+++ b/config/locales/devise.zh-TW.yml
@@ -12,6 +12,7 @@ zh-TW:
last_attempt: 帳號鎖定前,您還有最後一次嘗試機會。
locked: 已鎖定您的帳號。
not_found_in_database: 無效的 %{authentication_keys} 或密碼。
+ omniauth_user_creation_failure: 以此身分新增帳號時發生錯誤。
pending: 您的帳號仍在審核中。
timeout: 登入階段逾時。請重新登入以繼續。
unauthenticated: 您必須先登入或註冊才能繼續使用。
diff --git a/config/locales/doorkeeper.cs.yml b/config/locales/doorkeeper.cs.yml
index ba2100edfd..be2a4d971a 100644
--- a/config/locales/doorkeeper.cs.yml
+++ b/config/locales/doorkeeper.cs.yml
@@ -84,7 +84,7 @@ cs:
credential_flow_not_configured: Proud Resource Owner Password Credentials selhal, protože Doorkeeper.configure.resource_owner_from_credentials nebylo nakonfigurováno.
invalid_client: Ověření klienta selhalo kvůli neznámému klientovi, chybějící klientské autentizaci či nepodporované autentizační metodě.
invalid_grant: Poskytnuté oprávnění je neplatné, vypršela jeho platnost, bylo odvoláno, neshoduje se s URI přesměrování použitým v požadavku o autorizaci, nebo bylo uděleno jinému klientu.
- invalid_redirect_uri: URI pro přesměrování není platné.
+ invalid_redirect_uri: Zahrnutá přesměrovací URI není platná.
invalid_request:
missing_param: 'Chybí potřebný parametr: %{value}.'
request_not_authorized: Požadavek musí být autorizován. Potřebný parametr pro autorizaci požadavku chybí nebo není platný.
diff --git a/config/locales/doorkeeper.ia.yml b/config/locales/doorkeeper.ia.yml
index e7e6f03cdb..443342b404 100644
--- a/config/locales/doorkeeper.ia.yml
+++ b/config/locales/doorkeeper.ia.yml
@@ -34,6 +34,7 @@ ia:
confirmations:
revoke: Es tu secur?
index:
+ last_used_at: Ultime uso in %{date}
never_used: Nunquam usate
scopes: Permissiones
title: Tu applicationes autorisate
diff --git a/config/locales/doorkeeper.kab.yml b/config/locales/doorkeeper.kab.yml
index fe1a8d9c50..d7f8904a35 100644
--- a/config/locales/doorkeeper.kab.yml
+++ b/config/locales/doorkeeper.kab.yml
@@ -36,7 +36,7 @@ kab:
application: Asnas
callback_url: URL n tririt n wawal
delete: Kkes
- empty: Ulac γur-ek·em isnasen.
+ empty: Ulac ɣur-k·m isnasen.
name: Isem
new: Asnas amaynut
show: Ẓer
@@ -57,7 +57,7 @@ kab:
new:
title: Tlaq tsiregt
show:
- title: Nγel tangalt n wurag sakkin senteḍ-itt deg usnas.
+ title: Nɣel tangalt n wurag sakkin senteḍ-itt deg usnas.
authorized_applications:
buttons:
revoke: Ḥwi
@@ -113,13 +113,13 @@ kab:
read:notifications: ẓer tilγa-ik
read:reports: ẓer ineqqisen-ik·im
read:search: anadi deg umkan-ik·im
- read:statuses: ẓer meṛṛa tisuffaγ
+ read:statuses: ẓer meṛṛa tisuffaɣ
write: beddel meṛṛa isefka n umiḍan-ik
write:accounts: ẓreg amaγnu-ik
write:blocks: seḥbes imiḍanen d tγula
- write:bookmarks: ad yernu tisuffγin γer ticraḍ
+ write:bookmarks: ad yernu tisuffaɣ ɣer ticraḍ
write:filters: rnu-d imsizedgen
write:follows: ḍfeṛ imdanen
write:lists: ad yesnulfu tibdarin
- write:media: ad yessali ifayluyen n teγwalt
+ write:media: ad yessali ifuyla n umidya
write:notifications: sfeḍ tilɣa-k·m
diff --git a/config/locales/doorkeeper.tok.yml b/config/locales/doorkeeper.tok.yml
new file mode 100644
index 0000000000..6aef4fb34b
--- /dev/null
+++ b/config/locales/doorkeeper.tok.yml
@@ -0,0 +1,51 @@
+---
+tok:
+ doorkeeper:
+ applications:
+ buttons:
+ cancel: o pini
+ destroy: o weka
+ edit: o ante
+ submit: o awen
+ confirmations:
+ destroy: ni li pona ala pona?
+ edit:
+ title: o ante e ilo nanpa
+ form:
+ error: 'pakala a! o lukin e ni: lipu sina li jo ala jo e pakala.'
+ index:
+ delete: o weka
+ empty: sina li jo e ilo nanpa ala.
+ name: nimi
+ new: o pali e ilo nanpa sin
+ title: ilo nanpa sina
+ new:
+ title: o pali e ilo nanpa sin
+ show:
+ title: ilo nanpa pi nimi %{name}
+ authorizations:
+ error:
+ title: pakala li lon.
+ authorized_applications:
+ confirmations:
+ revoke: ni li pona ala pona?
+ index:
+ scopes: ken
+ errors:
+ messages:
+ invalid_request:
+ missing_param: o pana e sona "%{value}".
+ flash:
+ applications:
+ create:
+ notice: sina pali e ilo nanpa.
+ destroy:
+ notice: sina weka e ilo nanpa.
+ update:
+ notice: sina ante e ilo nanpa.
+ authorized_applications:
+ destroy:
+ notice: sina weka e ilo nanpa tawa sina.
+ grouped_scopes:
+ access:
+ read: lukin taso
diff --git a/config/locales/ia.yml b/config/locales/ia.yml
index bf7da9a314..a85af012f3 100644
--- a/config/locales/ia.yml
+++ b/config/locales/ia.yml
@@ -236,6 +236,8 @@ ia:
migrations:
errors:
not_found: non poterea esser trovate
+ preferences:
+ public_timelines: Chronologias public
statuses_cleanup:
min_age:
'1209600': 2 septimanas
@@ -254,6 +256,7 @@ ia:
disable: Disactivar 2FA
user_mailer:
welcome:
+ final_step: 'Comencia a publicar! Mesmo sin sequitores, tu messages public poterea esser reguardate per alteres, per exemplo in le chronologia local o in hashtags. Tu poterea voler introducer te con le hashtag #introductiones.'
subject: Benvenite in Mastodon
webauthn_credentials:
delete: Deler
diff --git a/config/locales/ie.yml b/config/locales/ie.yml
index a8287da533..7ab7f953be 100644
--- a/config/locales/ie.yml
+++ b/config/locales/ie.yml
@@ -1793,6 +1793,12 @@ ie:
extra: It es ja pret a descargar!
subject: Tui archive es pret por descargar
title: Descargar archive
+ failed_2fa:
+ details: 'Vi li detallies del prova de intrar:'
+ explanation: Alqui provat accesser tui conto ma usat un ínvalid duesim factor de autentication.
+ further_actions_html: Si it ne esset tu, noi recomanda que tu strax %{action} nam li conto posse esser compromisset.
+ subject: Falliment de autentication de duesim factor
+ title: Fallit autentication de duesim factor
suspicious_sign_in:
change_password: changear tui passa-parol
details: 'Vi li detallies del apertion de session:'
diff --git a/config/locales/kab.yml b/config/locales/kab.yml
index 66aeafde60..bd73b4ce0f 100644
--- a/config/locales/kab.yml
+++ b/config/locales/kab.yml
@@ -5,7 +5,7 @@ kab:
contact_missing: Ur yettusbadu ara
contact_unavailable: Wlac
hosted_on: Maṣṭudun yersen deg %{domain}
- title: Γef
+ title: Ɣef
accounts:
follow: Ḍfeṛ
followers:
@@ -15,9 +15,9 @@ kab:
last_active: armud aneggaru
nothing_here: Ulac kra da!
posts:
- one: Tajewwiqt
- other: Tijewwiqin
- posts_tab_heading: Tijewwiqin
+ one: Tasuffeɣt
+ other: Tisuffaɣ
+ posts_tab_heading: Tisuffaɣ
admin:
account_actions:
action: Eg tigawt
@@ -47,7 +47,7 @@ kab:
disable_two_factor_authentication: Gdel 2FA
disabled: Yensa
display_name: Isem ara d-yettwaskanen
- domain: Taγult
+ domain: Taɣult
edit: Ẓreg
email: Imayl
email_status: Addad n imayl
@@ -111,7 +111,7 @@ kab:
targeted_reports: Yettwazen uneqqis sɣur wiyaḍ
silence: Sgugem
silenced: Yettwasgugem
- statuses: Tisuffɣin
+ statuses: Tisuffaɣ
subscribe: Jerred
suspended: Yeḥbes
title: Imiḍanen
@@ -203,22 +203,22 @@ kab:
announcements:
destroyed_msg: Tamselɣut tettwakkes akken iwata!
edit:
- title: Ẓreg ulγu
- empty: Ulac kra n ulγuyen.
+ title: Ẓreg ulɣu
+ empty: Ulac kra n yilɣa yettwafen.
live: Srid
new:
- create: Rnu-d ulγu
- title: Ulγu amaynut
+ create: Snlufu-d ulɣu
+ title: Ulɣu amaynut
publish: Sufeɣ
published_msg: Tamselɣut tettwasufeɣ-d akken iwata!
scheduled_for: Yettusɣiwsen i %{time}
scheduled_msg: Tamselɣut tettusɣiwes i usufeɣ!
- title: Ulγuyen
+ title: Ilɣa
custom_emojis:
assign_category: Efk taggayt
- by_domain: Taγult
+ by_domain: Taɣult
copied_msg: Takna tadigant n imuji yettwarna-d mebla ugur
- copy: Nγel
+ copy: Nɣel
create_new_category: Rnu-d taggayt tamaynut
created_msg: Imuji yettwarna-d mebla ugur!
delete: Kkes
@@ -229,7 +229,7 @@ kab:
enable: Rmed
enabled: Yermed
enabled_msg: Imuji yermed mebla ugur
- list: Umuγ
+ list: Tabdart
new:
title: Timerna n imuji udmawan amaynut
overwrite: Semselsi
@@ -256,7 +256,7 @@ kab:
add_new: Rni iḥder amaynut n taɣult
confirm_suspension:
cancel: Sefsex
- domain: Taγult
+ domain: Taɣult
export: Sifeḍ
import: Kter
new:
@@ -274,9 +274,9 @@ kab:
email_domain_blocks:
add_new: Rnu amaynut
delete: Kkes
- domain: Taγult
+ domain: Taɣult
new:
- create: Rnu taγult
+ create: Rnu taɣult
title: Timerna n taɣult tamaynut n imayl ɣer tebdart taberkant
title: Tabdart taberkant n imayl
follow_recommendations:
@@ -286,8 +286,8 @@ kab:
instances:
back_to_all: Akk
back_to_limited: Ɣur-s talast
- back_to_warning: Γur-wat
- by_domain: Taγult
+ back_to_warning: Ɣur-wat
+ by_domain: Taɣult
content_policies:
policy: Tasertit
delivery:
@@ -306,7 +306,7 @@ kab:
private_comment: Awennit uslig
public_comment: Awennit azayez
title: Tamatut
- total_blocked_by_us: Ttwasḥebsen sγur-neγ
+ total_blocked_by_us: Ttwasḥebsen sɣur-neɣ
total_followed_by_them: Ṭtafaṛen-t
total_followed_by_us: Neṭṭafaṛ-it
total_reported: Ineqqisen fell-asen
@@ -354,12 +354,15 @@ kab:
other: "%{count} n timawin"
action_taken_by: Tigawt yettwaṭṭfen sɣur
are_you_sure: Tetḥaq-eḍ?
+ cancel: Sefsex
category: Taggayt
comment:
none: Ula yiwen
confirm: Sentem
+ delete_and_resolve: Kkes tisuffaɣ
mark_as_resolved: Creḍ-it yefra
mark_as_unresolved: Creḍ-it ur yefra ara
+ no_one_assigned: Ula yiwen
notes:
create: Rnu tazmilt
create_and_resolve: Fru s tamawt
@@ -390,16 +393,16 @@ kab:
title: Ilugan n uqeddac
settings:
about:
- title: Γef
+ title: Ɣef
appearance:
title: Udem
discovery:
- profile_directory: Akaram n imaγnuten
+ profile_directory: Akaram n imaɣnuten
trends: Ayen mucaɛen
domain_blocks:
all: I medden akk
- disabled: Γef ula yiwen
- users: Γef yimseqdacen idiganen i yeqqnen
+ disabled: Ɣef ula yiwen
+ users: Ɣef yimseqdacen idiganen i yeqqnen
registrations:
title: Ajerred
registrations_mode:
@@ -408,19 +411,26 @@ kab:
open: Zemren akk ad jerden
site_uploads:
delete: Kkes afaylu yulin
+ software_updates:
+ documentation_link: Issin ugar
statuses:
application: Asnas
- back_to_account: Tuγalin γer usebter n umiḍan
+ back_to_account: Tuɣalin ɣer usebter n umiḍan
deleted: Yettwakkes
favourites: Imenyafen
language: Tutlayt
media:
- title: Taγwalt
- title: Tisuffiγin n umiḍan
- with_media: S taγwalt
+ title: Amidya
+ title: Tisuffaɣ n umiḍan
+ trending: Ayen mucaɛen
+ visibility: Abani
+ with_media: S umidya
title: Tadbelt
trends:
allow: Sireg
+ statuses:
+ title: Tisuffaɣ mucaɛen
+ trending: Ayen mucaɛen
warning_presets:
add_new: Rnu amaynut
delete: Kkes
@@ -431,7 +441,11 @@ kab:
new_report:
body: "%{reporter} yettwazen ɣef %{target}"
subject: Aneqqis amaynut i %{instance} (#%{id})
+ new_trends:
+ new_trending_statuses:
+ title: Tisuffaɣ mucaɛen
appearance:
+ advanced_web_interface: Agrudem n web leqqayen
discovery: Asnirem
localization:
guide_link: https://crowdin.com/project/mastodon
@@ -448,6 +462,8 @@ kab:
your_token: Ajiṭun-ik·im n unekcum
auth:
apply_for_account: Suter amiḍan
+ confirmations:
+ welcome_title: Ansuf yessek·em, %{name}!
delete_account: Kkes amiḍan
description:
prefix_invited_by_user: "@%{name} inced-ik·ikem ad ternuḍ ɣer uqeddac-a n Mastodon!"
@@ -455,9 +471,11 @@ kab:
forgot_password: Tettud awal-ik uffir?
log_in_with: Qqen s
login: Qqen
- logout: Ffeγ
- migrate_account: Gujj γer umiḍan nniḍen
- or_log_in_with: Neγ eqqen s
+ logout: Ffeɣ
+ migrate_account: Gujj ɣer umiḍan nniḍen
+ or_log_in_with: Neɣ eqqen s
+ progress:
+ confirm: Sentem imayl
providers:
cas: CAS
saml: SAML
@@ -466,8 +484,11 @@ kab:
reset_password: Wennez awal uffir
rules:
back: Tuɣalin
- security: Taγellist
+ security: Taɣellist
set_new_password: Egr-d awal uffir amaynut
+ sign_in:
+ preamble_html: Kcem ar %{domain} s inekcam-inek n tuqqna. Ma yella yezga-d umiḍan-ik deg uqeddac-nniḍen, ur tezmireḍ ara ad tkecmeḍ sya.
+ title: Akeččum ɣer %{domain}
status:
account_status: Addad n umiḍan
use_security_key: Seqdec tasarut n teɣlist
@@ -498,16 +519,21 @@ kab:
warning:
username_available: Isem-ik·im n useqdac ad yuɣal yella i tikkelt-nniḍen
username_unavailable: Isem-ik·im n useqdac ad yeqqim ulac-it
+ disputes:
+ strikes:
+ status: 'Tasuffeɣt #%{id}'
+ title_actions:
+ none: Ɣur-wat
errors:
'500':
- title: Asebter-ayi d arameγtu
+ title: Asebter-ayi d arameɣtu
existing_username_validator:
not_found_multiple: ur yezmir ara ad yaf %{usernames}
exports:
archive_takeout:
date: Azemz
download: Sider-d aḥraz-ik·im
- size: Teγzi
+ size: Teɣzi
bookmarks: Ticraḍ
csv: CSV
lists: Tibdarin
@@ -516,8 +542,8 @@ kab:
add_new: Rnu amaynut
filters:
contexts:
- account: Imuγna
- notifications: Tilγa
+ account: Imuɣna
+ notifications: Ilɣa
thread: Idiwenniyen
edit:
title: Ẓreg amzizdig
@@ -534,8 +560,10 @@ kab:
remove: Kkes seg umsizdeg
generic:
all: Akk
+ cancel: Sefsex
changes_saved_msg: Ttwaskelsen ibelliden-ik·im akken ilaq!
- copy: Nγel
+ confirm: Sentem
+ copy: Nɣel
delete: Kkes
order_by: Sizwer s
save_changes: Sekles ibeddilen
@@ -575,7 +603,7 @@ kab:
sign_in_token: tangalt n tɣellist n tansa imayl
webauthn: tisura n tɣellist
migrations:
- acct: Ibeddel γer
+ acct: Ibeddel ɣer
incoming_migrations: Tusiḍ-d seg umiḍan nniḍen
proceed_with_move: Awid imeḍfaṛen-ik
moderation:
@@ -597,7 +625,7 @@ kab:
reblog:
subject: "%{name} yesselha addad-ik·im"
notifications:
- other_settings: Iγewwaṛen nniḍen n tilγa
+ other_settings: Iɣewwaṛen nniḍen n yilɣa
number:
human:
decimal_units:
@@ -611,11 +639,14 @@ kab:
setup: Sbadu
pagination:
newer: Amaynut
- next: Γer zdat
+ next: Ɣer zdat
older: Aqbuṛ
prev: Win iɛeddan
preferences:
other: Wiyaḍ
+ privacy:
+ privacy: Tabaḍnit
+ search: Anadi
privacy_policy:
title: Tasertit tabaḍnit
relationships:
@@ -634,6 +665,7 @@ kab:
browser: Iminig
browsers:
alipay: Alipay
+ blackberry: BlackBerry
chrome: Chrome
edge: Microsoft Edge
electron: Electron
@@ -648,37 +680,41 @@ kab:
qq: Iminig QQ
safari: Safari
weibo: Weibo
- current_session: Tiγimit tamirant
+ current_session: Tiɣimit tamirant
+ date: Azemz
description: "%{browser} s %{platform}"
ip: IP
platforms:
adobe_air: Adobe Air
android: Android
+ blackberry: BlackBerry
+ chrome_os: ChromeOS
firefox_os: Firefox OS
ios: iOS
+ kai_os: KaiOS
linux: Linux
mac: macOS
windows: Windows
windows_mobile: Windows Mobile
- windows_phone: Tiliγri Windows Phone
+ windows_phone: Tiliɣri Windows Phone
revoke: Ḥwi
title: Tiɣimiyin
settings:
account: Amiḍan
- account_settings: Iγewwaṛen n umiḍan
+ account_settings: Iɣewwaṛen n umiḍan
appearance: Udem
authorized_apps: Isnasen yettussirgen
- back: Uγal γer Maṣṭudun
+ back: Uɣal ɣer Maṣṭudun
delete: Tukksa n umiḍan
development: Taneflit
- edit_profile: Ẓreg amaγnu
+ edit_profile: Ẓreg amaɣnu
export: Taktert n yisefka
import: Kter
import_and_export: Taktert d usifeḍ
migrate: Tunigin n umiḍan
- notifications: Tilγa
+ notifications: Ilɣa
preferences: Imenyafen
- profile: Ameγnu
+ profile: Ameɣnu
relationships: Imeḍfaṛen akked wid i teṭṭafaṛeḍ
statuses_cleanup: Tukksa tawurmant n tsuffaɣ
two_factor_authentication: Asesteb s snat n tarrayin
@@ -745,22 +781,25 @@ kab:
otp: Asnas n usesteb
webauthn: Tisura n teɣlist
user_mailer:
+ appeal_approved:
+ action: Iɣewwaṛen n umiḍan
warning:
categories:
spam: Aspam
title:
disable: Amiḍan i igersen
- none: Γur-wat
+ none: Ɣur-wat
silence: Amiḍan yesɛa talast
suspend: Amiḍan yettwaḥbas
welcome:
final_action: Bdu asuffeɣ
full_handle: Tansa umiḍan-ik takemmalit
- subject: Ansuf γer Maṣṭudun
+ subject: Ansuf ɣer Maṣṭudun
title: Ansuf yessek·em, %{name}!
users:
signed_in_as: 'Teqqneḍ amzun d:'
verification:
+ here_is_how: Ha-t-a amek
verification: Asenqed
webauthn_credentials:
add: Rnu tasarut n teɣlist tamaynut
diff --git a/config/locales/lad.yml b/config/locales/lad.yml
index d4f772095e..77501e3b32 100644
--- a/config/locales/lad.yml
+++ b/config/locales/lad.yml
@@ -1146,7 +1146,7 @@ lad:
confirm_password: Eskrive tu kod aktual para demostrar tu identita
confirm_username: Eskrive tu nombre de utilizador para konfirmar
proceed: Efasa kuento
- success_msg: Tu kuento fue efasado kon reusho
+ success_msg: Tu kuento fue efasado kon reushita
warning:
before: 'Antes de kontinuar, por favor melda kon atensyon las sigientes notas:'
caches: El kontenido ke tiene sido magazinado en kashe por otros sirvidores puede persistir
@@ -1283,7 +1283,7 @@ lad:
one: "%{count} elemento ke koenside con tu bushkeda esta eskojido."
other: Todos los %{count} elementos ke koensiden con tu bushkeda estan eskojidos.
cancel: Anula
- changes_saved_msg: Trokamientos guadrados kon reusho!
+ changes_saved_msg: Trokamientos guadrados kon reushita!
confirm: Konfirma
copy: Kopia
delete: Efasa
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 1c31ed9e2b..ea811400a6 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -1843,7 +1843,7 @@ nl:
explanation: Hier zijn enkele tips om je op weg te helpen
final_action: Begin berichten te plaatsen
final_step: 'Begin berichten te plaatsen! Zelfs zonder volgers kunnen jouw openbare berichten door anderen bekeken worden, bijvoorbeeld op de lokale tijdlijn en onder hashtags. Je kunt jezelf voorstellen met het gebruik van de hashtag #introductions.'
- full_handle: Jouw volledige Mastodonadres
+ full_handle: Jouw volledige Mastodon-adres
full_handle_hint: Dit geef je aan jouw vrienden, zodat ze jou berichten kunnen sturen of (vanaf een andere Mastodonserver) kunnen volgen.
subject: Welkom op Mastodon
title: Welkom aan boord %{name}!
diff --git a/config/locales/simple_form.bg.yml b/config/locales/simple_form.bg.yml
index 68e45ef47b..a4637a6810 100644
--- a/config/locales/simple_form.bg.yml
+++ b/config/locales/simple_form.bg.yml
@@ -261,7 +261,7 @@ bg:
status_page_url: URL адрес на страница със състоянието
theme: Стандартна тема
thumbnail: Образче на сървъра
- timeline_preview: Позволяване на неупълномощен достъп до публични часови оси
+ timeline_preview: Позволяване на неудостоверен достъп до публични инфопотоци
trendable_by_default: Без преглед на налагащото се
trends: Включване на налагащи се
trends_as_landing_page: Употреба на налагащото се като целева страница
diff --git a/config/locales/simple_form.cs.yml b/config/locales/simple_form.cs.yml
index dff9378098..9da377ae9c 100644
--- a/config/locales/simple_form.cs.yml
+++ b/config/locales/simple_form.cs.yml
@@ -3,9 +3,13 @@ cs:
simple_form:
hints:
account:
+ discoverable: Vaše veřejné příspěvky a profil mohou být zobrazeny nebo doporučeny v různých oblastech Mastodonu a váš profil může být navrhován ostatním uživatelům.
display_name: Vaše celé jméno nebo přezdívka.
fields: Vaše domovská stránka, zájmena, věk, cokoliv chcete.
+ indexable: Vaše veřejné příspěvky se mohou objevit ve výsledcích vyhledávání na Mastodonu. Lidé, kteří s vašimi příspěvky interagovaly, je mohou stále vyhledávat.
note: 'Můžete @zmínit jiné osoby nebo #hashtagy.'
+ show_collections: Lidé budou moci procházet skrz sledující. Lidé, které sledujete, uvidí, že je sledujete bezohledně.
+ unlocked: Lidé vás budou moci sledovat, aniž by vás žádali o schválení. Zrušte zaškrtnutí, pokud chcete zkontrolovat požadavky a zvolte, zda přijmete nebo odmítněte nové následovníky.
account_alias:
acct: Zadejte svůj účet, ze kterého se chcete přesunout jinam, ve formátu přezdívka@doména
account_migration:
@@ -34,7 +38,7 @@ cs:
appeal:
text: Proti prohřešku se můžete odvolat jen jednou
defaults:
- autofollow: Lidé, kteří se zaregistrují na základě pozvánky, vás budou automaticky sledovat
+ autofollow: Lidé, kteří se zaregistrují skrz pozvánky, vás budou automaticky sledovat
avatar: PNG, GIF či JPG. Maximálně %{size}. Bude zmenšen na %{dimensions} px
bot: Signalizovat ostatním, že účet převážně vykonává automatizované akce a nemusí být monitorován
context: Jeden či více kontextů, ve kterých má být filtr uplatněn
@@ -72,7 +76,7 @@ cs:
hide: Úplně schovat filtrovaný obsah tak, jako by neexistoval
warn: Schovat filtrovaný obsah za varováním zmiňujicím název filtru
form_admin_settings:
- activity_api_enabled: Počty lokálně publikovaných příspěvků, aktivních uživatelů a nových registrací v týdenních intervalech
+ activity_api_enabled: Počty lokálně zveřejnělých příspěvků, aktivních uživatelů a nových registrací v týdenních intervalech
backups_retention_period: Zachovat generované uživatelské archivy pro zadaný počet dní.
bootstrap_timeline_accounts: Tyto účty budou připnuty na vrchol nových uživatelů podle doporučení.
closed_registrations_message: Zobrazeno při zavření registrace
@@ -116,6 +120,9 @@ cs:
sessions:
otp: 'Zadejte kód pro dvoufázové ověření vygenerovaný vaší mobilní aplikací, nebo použijte jeden z vašich záložních kódů:'
webauthn: Pokud jde o USB klíč, vložte jej a případně se dotkněte jeho tlačítka.
+ settings:
+ indexable: Vaše profilová stránka se může objevit ve výsledcích vyhledávání na Google, Bingu a ostatních vyhledávačích.
+ show_application: I tak budete vždy moci vidět, která aplikace zveřejnila váš příspěvek.
tag:
name: Můžete měnit pouze velikost písmen, například kvůli lepší čitelnosti
user:
@@ -133,9 +140,13 @@ cs:
url: Kam budou události odesílány
labels:
account:
+ discoverable: Zobrazovat profil a příspěvky ve vyhledávacích algoritmech
fields:
name: Označení
value: Obsah
+ indexable: Zahrnout veřejné příspěvky do výsledků hledání
+ show_collections: Zobrazit koho sledujete a kdo vás sleduje v profilu
+ unlocked: Automaticky přijímat nové sledující
account_alias:
acct: Adresa starého účtu
account_migration:
@@ -280,9 +291,18 @@ cs:
pending_account: Je třeba posoudit nový účet
reblog: Někdo boostnul váš příspěvek
report: Je odesláno nové hlášení
+ software_updates:
+ all: Upozornit na všechny aktualizace
+ critical: Upozornit pouze na kritické aktualizace
+ label: Nová verze Mastodonu k dispozici
+ none: Nikdy neoznamovat aktualizace (nedoporučeno)
+ patch: Upozornit na aktualizace chyb
trending_tag: Nový trend vyžaduje posouzení
rule:
text: Pravidlo
+ settings:
+ indexable: Zahrnout stránku profilu do vyhledávačů
+ show_application: Zobrazit aplikaci, ze které jste odeslali příspěvek
tag:
listable: Povolit zobrazení tohoto hashtagu ve vyhledávání a návrzích
name: Hashtag
@@ -303,6 +323,7 @@ cs:
url: URL koncového bodu
'no': Ne
not_recommended: Nedoporučuje se
+ overridden: Přepsáno
recommended: Doporučeno
required:
mark: "*"
diff --git a/config/locales/simple_form.ia.yml b/config/locales/simple_form.ia.yml
index 552abb2550..af198d932a 100644
--- a/config/locales/simple_form.ia.yml
+++ b/config/locales/simple_form.ia.yml
@@ -26,6 +26,7 @@ ia:
username: Nomine de usator
username_or_email: Nomine de usator o e-mail
form_admin_settings:
+ bootstrap_timeline_accounts: Recommenda sempre iste contos a nove usatores
custom_css: CSS personalisate
profile_directory: Activar directorio de profilos
site_contact_email: Adresse de e-mail de contacto
diff --git a/config/locales/simple_form.kab.yml b/config/locales/simple_form.kab.yml
index 1e1c52da24..546336660c 100644
--- a/config/locales/simple_form.kab.yml
+++ b/config/locales/simple_form.kab.yml
@@ -12,7 +12,7 @@ kab:
defaults:
autofollow: Imdanen ara ijerrden s usnebgi-inek, ad k-ḍefṛen s wudem awurman
email: Ad n-teṭṭfeḍ imayl i usentem
- irreversible: Tijewwaqin i tessazedgeḍ ad ttwakksent i lebda, ula ma tekkseḍ imsizdeg-nni ar zdat
+ irreversible: Tisuffaɣ i tessazedgeḍ ad ttwakksent i lebda, ula ma tekkseḍ imsizdeg-nni ar zdat
locale: Tutlayt n ugrudem, imaylen d tilγa
password: Seqdec ma drus 8 n yisekkilen
setting_display_media_default: Ffer teywalt yettwacreḍ d tanafrit
@@ -69,12 +69,12 @@ kab:
setting_display_media_show_all: Ssken kullec
setting_hide_network: Ffer azetta-k·m
setting_theme: Asental n wesmel
- setting_use_pending_items: Askar aleγwayan
+ setting_use_pending_items: Askar aleɣwayan
sign_in_token_attempt: Tangalt n tɣellist
title: Azwel
type: Anaw n uktar
username: Isem n useqdac
- username_or_email: Isem n useqdac neγ imal
+ username_or_email: Isem n useqdac neɣ imal
whole_word: Awal akk
featured_tag:
name: Ahacṭag
@@ -84,7 +84,7 @@ kab:
invite:
comment: Awennit
invite_request:
- text: Acimi tebγiḍ ad ternuḍ iman-ik?
+ text: Acimi tebɣiḍ ad ternuḍ iman-ik?
ip_block:
comment: Awennit
ip: IP
diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml
index b0b695745b..f7e917ac3c 100644
--- a/config/locales/simple_form.nl.yml
+++ b/config/locales/simple_form.nl.yml
@@ -148,9 +148,9 @@ nl:
show_collections: Accounts die jij volgt en die jou volgen op je profiel tonen
unlocked: Automatisch nieuwe volgers accepteren
account_alias:
- acct: Mastodonadres van het oude account
+ acct: Mastodon-adres van het oude account
account_migration:
- acct: Mastodonadres van het nieuwe account
+ acct: Mastodon-adres van het nieuwe account
account_warning_preset:
text: Tekst van preset
title: Titel
diff --git a/config/locales/simple_form.tok.yml b/config/locales/simple_form.tok.yml
new file mode 100644
index 0000000000..37b0ee765a
--- /dev/null
+++ b/config/locales/simple_form.tok.yml
@@ -0,0 +1,17 @@
+---
+tok:
+ simple_form:
+ hints:
+ account:
+ display_name: nimi sina ale anu nimi sina musi.
+ defaults:
+ setting_display_media_hide_all: sitelen ale li len
+ setting_display_media_show_all: sitelen ale li len ala
+ labels:
+ defaults:
+ expires_in: ona o moli lon
+ setting_theme: kule lipu
+ user_role:
+ name: nimi
+ required:
+ text: ni li ken ala lon ala
diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml
index a31ad5eb11..696fd5fed9 100644
--- a/config/locales/simple_form.zh-TW.yml
+++ b/config/locales/simple_form.zh-TW.yml
@@ -200,12 +200,12 @@ zh-TW:
password: 密碼
phrase: 關鍵字或片語
setting_advanced_layout: 啟用進階網頁介面
- setting_aggregate_reblogs: 時間軸中的群組轉嘟
+ setting_aggregate_reblogs: 於時間軸中不重複顯示轉嘟
setting_always_send_emails: 總是發送電子郵件通知
setting_auto_play_gif: 自動播放 GIF 動畫
setting_boost_modal: 轉嘟前先詢問我
setting_default_language: 嘟文語言
- setting_default_privacy: 嘟文可見範圍
+ setting_default_privacy: 嘟文隱私設定
setting_default_sensitive: 總是將媒體標記為敏感內容
setting_delete_modal: 刪除嘟文前先詢問我
setting_disable_swiping: 停用滑動手勢
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 5ffbf45bde..90f8144ea8 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -88,7 +88,7 @@ sk:
remote: Federované
title: Umiestnenie
login_status: Stav prihlásenia
- media_attachments: Prílohy
+ media_attachments: Mediálne prílohy
memorialize: Zmeň na "Navždy budeme spomínať"
memorialized: Spomienka na
memorialized_msg: Úspešne zmenené %{username} na spomienkové konto
@@ -175,6 +175,7 @@ sk:
approve_user: Odobri užívateľa
assigned_to_self_report: Priraď hlásenie
change_email_user: Zmeň email pre užívateľa
+ change_role_user: Zmeň užívateľskú rolu
confirm_user: Potvrď užívateľa
create_account_warning: Vytvor výstrahu
create_announcement: Vytvor oboznámenie
@@ -251,15 +252,22 @@ sk:
enable_user_html: "%{name} povolil/a prihlásenie pre používateľa %{target}"
memorialize_account_html: "%{name} zmenil/a účet %{target} na pamätnú stránku"
reject_appeal_html: "%{name} zamietol/la námietku moderovacieho rozhodnutia od %{target}"
+ remove_avatar_user_html: "%{name} vymazal/a %{target}/ov/in avatar"
reopen_report_html: "%{name} znovu otvoril/a nahlásenie %{target}"
resend_user_html: "%{name} znovu odoslal/a potvrdzovací email pre %{target}"
reset_password_user_html: "%{name} resetoval/a heslo používateľa %{target}"
resolve_report_html: "%{name} vyriešil/a nahlásenie %{target}"
- sensitive_account_html: "%{name} označil médium od %{target} za chúlostivé"
+ sensitive_account_html: "%{name} označil/a médium od %{target} za chúlostivé"
silence_account_html: "%{name} obmedzil/a účet %{target}"
suspend_account_html: "%{name} zablokoval/a účet používateľa %{target}"
unassigned_report_html: "%{name} odobral/a report od %{target}"
+ unsensitive_account_html: "%{name} odznačil/a médium od %{target} ako chúlostivé"
unsuspend_account_html: "%{name} spojazdnil/a účet %{target}"
+ update_announcement_html: "%{name} aktualizoval/a oboznámenie %{target}"
+ update_custom_emoji_html: "%{name} aktualizoval/a emotikonu %{target}"
+ update_domain_block_html: "%{name} aktualizoval/a blokovanie domény pre %{target}"
+ update_ip_block_html: "%{name} zmenil/a pravidlo pre IP %{target}"
+ update_status_html: "%{name} aktualizoval/a príspevok od %{target}"
update_user_role_html: "%{name} zmenil/a rolu pre %{target}"
deleted_account: zmazaný účet
empty: Žiadne záznamy nenájdené.
@@ -784,6 +792,7 @@ sk:
captcha_confirmation:
title: Bezpečnostná kontrola
confirmations:
+ clicking_this_link: kliknutím na tento odkaz
login_link: prihlás sa
welcome_title: Vitaj, %{name}!
delete_account: Vymaž účet
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index 3dd4731209..460fd82dc0 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -188,7 +188,7 @@ sq:
create_user_role: Krijoni Rol
demote_user: Zhgradoje Përdoruesin
destroy_announcement: Fshije Lajmërimin
- destroy_canonical_email_block: Fshi Bllokim El-esh
+ destroy_canonical_email_block: Fshi Bllokim Email-esh
destroy_custom_emoji: Fshi Emotikon Vetjak
destroy_domain_allow: Fshi Lejim Përkatësie
destroy_domain_block: Fshi Bllokim Përkatësie
@@ -283,7 +283,7 @@ sq:
unsuspend_account_html: "%{name} hoqi pezullimin për llogarinë e %{target}"
update_announcement_html: "%{name} përditësoi lajmërimin %{target}"
update_custom_emoji_html: "%{name} përditësoi emoxhin %{target}"
- update_domain_block_html: "%{name} përditësoi bllokimin e përkatësish për %{target}"
+ update_domain_block_html: "%{name} përditësoi bllokim përkatësish për %{target}"
update_ip_block_html: "%{name} ndryshoi rregull për IP-në %{target}"
update_status_html: "%{name} përditësoi gjendjen me %{target}"
update_user_role_html: "%{name} ndryshoi rolin për %{target}"
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 74fc1b26b7..b76f6992ad 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -452,7 +452,7 @@ th:
title: นำเข้าการปิดกั้นโดเมน
no_file: ไม่ได้เลือกไฟล์
follow_recommendations:
- description_html: "คำแนะนำการติดตามช่วยให้ผู้ใช้ใหม่ค้นหาเนื้อหาที่น่าสนใจได้อย่างรวดเร็ว เมื่อผู้ใช้ไม่ได้โต้ตอบกับผู้อื่นมากพอที่จะสร้างคำแนะนำการติดตามส่วนบุคคล จะแนะนำบัญชีเหล่านี้แทน จะคำนวณคำแนะนำใหม่เป็นประจำทุกวันจากบัญชีต่าง ๆ ที่มีการมีส่วนร่วมล่าสุดสูงสุดและจำนวนผู้ติดตามในเซิร์ฟเวอร์สูงสุดสำหรับภาษาที่กำหนด"
+ description_html: "คำแนะนำการติดตามช่วยให้ผู้ใช้ใหม่ค้นหาเนื้อหาที่น่าสนใจได้อย่างรวดเร็ว เมื่อผู้ใช้ไม่ได้โต้ตอบกับผู้อื่นมากพอที่จะสร้างคำแนะนำการติดตามเฉพาะบุคคล จะแนะนำบัญชีเหล่านี้แทน จะคำนวณคำแนะนำใหม่เป็นประจำทุกวันจากบัญชีต่าง ๆ ที่มีการมีส่วนร่วมล่าสุดสูงสุดและจำนวนผู้ติดตามในเซิร์ฟเวอร์สูงสุดสำหรับภาษาที่กำหนด"
language: สำหรับภาษา
status: สถานะ
suppress: ระงับคำแนะนำการติดตาม
diff --git a/config/locales/tok.yml b/config/locales/tok.yml
new file mode 100644
index 0000000000..9f962d2b53
--- /dev/null
+++ b/config/locales/tok.yml
@@ -0,0 +1,5 @@
+---
+tok:
+ admin:
+ accounts:
+ are_you_sure: ni li pona ala pona?
diff --git a/db/migrate/20190715164535_add_instance_actor.rb b/db/migrate/20190715164535_add_instance_actor.rb
index 3785dc2553..6871b37bdf 100644
--- a/db/migrate/20190715164535_add_instance_actor.rb
+++ b/db/migrate/20190715164535_add_instance_actor.rb
@@ -5,6 +5,8 @@ class AddInstanceActor < ActiveRecord::Migration[5.2]
# Dummy class, to make migration possible across version changes
validates :username, uniqueness: { scope: :domain, case_sensitive: false }
+ INSTANCE_ACTOR_ID = -99
+
before_create :generate_keys
def generate_keys
@@ -15,10 +17,10 @@ class AddInstanceActor < ActiveRecord::Migration[5.2]
end
def up
- Account.create!(id: -99, actor_type: 'Application', locked: true, username: Rails.configuration.x.local_domain)
+ Account.create!(id: Account::INSTANCE_ACTOR_ID, actor_type: 'Application', locked: true, username: Rails.configuration.x.local_domain)
end
def down
- Account.find_by(id: -99, actor_type: 'Application').destroy!
+ Account.find_by(id: Account::INSTANCE_ACTOR_ID, actor_type: 'Application').destroy!
end
end
diff --git a/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb b/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb
index 00afee26d0..42dc37f08b 100644
--- a/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb
+++ b/db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb
@@ -3,7 +3,9 @@
class MigrateSettingsToUserRoles < ActiveRecord::Migration[6.1]
disable_ddl_transaction!
- class UserRole < ApplicationRecord; end
+ class UserRole < ApplicationRecord
+ EVERYONE_ROLE_ID = -99
+ end
def up
process_role_everyone
@@ -17,7 +19,7 @@ class MigrateSettingsToUserRoles < ActiveRecord::Migration[6.1]
private
def process_role_everyone
- everyone_role = UserRole.find_by(id: -99)
+ everyone_role = UserRole.find_by(id: UserRole::EVERYONE_ROLE_ID)
return unless everyone_role
everyone_role.permissions &= ~::UserRole::FLAGS[:invite_users] unless min_invite_role == 'user'
diff --git a/db/seeds/02_instance_actor.rb b/db/seeds/02_instance_actor.rb
index 55e83e8a08..2b6befec0d 100644
--- a/db/seeds/02_instance_actor.rb
+++ b/db/seeds/02_instance_actor.rb
@@ -1,3 +1,3 @@
# frozen_string_literal: true
-Account.create_with(actor_type: 'Application', locked: true, username: 'mastodon.internal').find_or_create_by(id: -99)
+Account.create_with(actor_type: 'Application', locked: true, username: 'mastodon.internal').find_or_create_by(id: Account::INSTANCE_ACTOR_ID)
diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake
index 885be79f41..935f6d24a3 100644
--- a/lib/tasks/tests.rake
+++ b/lib/tasks/tests.rake
@@ -50,7 +50,7 @@ namespace :tests do
exit(1)
end
- if Account.find(-99).private_key.blank?
+ if Account.find(Account::INSTANCE_ACTOR_ID).private_key.blank?
puts 'Instance actor does not have a private key'
exit(1)
end
diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb
index ef3053b6b3..b90bb414b0 100644
--- a/spec/controllers/admin/accounts_controller_spec.rb
+++ b/spec/controllers/admin/accounts_controller_spec.rb
@@ -9,18 +9,8 @@ RSpec.describe Admin::AccountsController do
describe 'GET #index' do
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
-
- around do |example|
- default_per_page = Account.default_per_page
- Account.paginates_per 1
- example.run
- Account.paginates_per default_per_page
- end
-
- it 'filters with parameters' do
- account_filter = instance_double(AccountFilter, results: Account.all)
- allow(AccountFilter).to receive(:new).and_return(account_filter)
- params = {
+ let(:params) do
+ {
origin: 'local',
by_domain: 'domain',
status: 'active',
@@ -29,25 +19,35 @@ RSpec.describe Admin::AccountsController do
email: 'local-part@domain',
ip: '0.0.0.42',
}
-
- get :index, params: params
-
- expect(AccountFilter).to have_received(:new).with(hash_including(params))
end
- it 'paginates accounts' do
+ around do |example|
+ default_per_page = Account.default_per_page
+ Account.paginates_per 1
+ example.run
+ Account.paginates_per default_per_page
+ end
+
+ before do
Fabricate(:account)
- get :index, params: { page: 2 }
-
- accounts = assigns(:accounts)
- expect(accounts.count).to eq 1
- expect(accounts.klass).to be Account
+ account_filter = instance_double(AccountFilter, results: Account.all)
+ allow(AccountFilter).to receive(:new).and_return(account_filter)
end
- it 'returns http success' do
- get :index
- expect(response).to have_http_status(200)
+ it 'returns success and paginates and filters with parameters' do
+ get :index, params: params.merge(page: 2)
+
+ expect(response)
+ .to have_http_status(200)
+ expect(assigns(:accounts))
+ .to have_attributes(
+ count: eq(1),
+ klass: be(Account)
+ )
+ expect(AccountFilter)
+ .to have_received(:new)
+ .with(hash_including(params))
end
end
diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb
index f830c3b95c..d365233167 100644
--- a/spec/controllers/admin/disputes/appeals_controller_spec.rb
+++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb
@@ -30,21 +30,19 @@ RSpec.describe Admin::Disputes::AppealsController do
end
describe 'POST #approve' do
+ subject { post :approve, params: { id: appeal.id } }
+
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
- before do
- post :approve, params: { id: appeal.id }
- end
+ it 'redirects back to the strike page and notifies target account about approved appeal', :sidekiq_inline do
+ subject
- it 'unsuspends a suspended account' do
- expect(target_account.reload.suspended?).to be false
- end
+ expect(response)
+ .to redirect_to(disputes_strike_path(appeal.strike))
- it 'redirects back to the strike page' do
- expect(response).to redirect_to(disputes_strike_path(appeal.strike))
- end
+ expect(target_account.reload)
+ .to_not be_suspended
- it 'notifies target account about approved appeal', :sidekiq_inline do
expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at)))
@@ -52,17 +50,16 @@ RSpec.describe Admin::Disputes::AppealsController do
end
describe 'POST #reject' do
+ subject { post :reject, params: { id: appeal.id } }
+
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
- before do
- post :reject, params: { id: appeal.id }
- end
+ it 'redirects back to the strike page and notifies target account about rejected appeal', :sidekiq_inline do
+ subject
- it 'redirects back to the strike page' do
- expect(response).to redirect_to(disputes_strike_path(appeal.strike))
- end
+ expect(response)
+ .to redirect_to(disputes_strike_path(appeal.strike))
- it 'notifies target account about rejected appeal', :sidekiq_inline do
expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at)))
diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb
index b663f55afa..dcbaf1fcbb 100644
--- a/spec/controllers/auth/sessions_controller_spec.rb
+++ b/spec/controllers/auth/sessions_controller_spec.rb
@@ -57,11 +57,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { email: 'pam_user1', password: '123456' } }
end
- it 'redirects to home' do
+ it 'redirects to home and logs the user in' do
expect(response).to redirect_to(root_path)
- end
- it 'logs the user in' do
expect(controller.current_user).to be_instance_of(User)
end
end
@@ -71,11 +69,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { email: 'pam_user1', password: 'WRONGPW' } }
end
- it 'shows a login error' do
+ it 'shows a login error and does not log the user in' do
expect(flash[:alert]).to match I18n.t('devise.failure.invalid', authentication_keys: I18n.t('activerecord.attributes.user.email'))
- end
- it "doesn't log the user in" do
expect(controller.current_user).to be_nil
end
end
@@ -92,11 +88,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { email: user.email, password: '123456' } }
end
- it 'redirects to home' do
+ it 'redirects to home and logs the user in' do
expect(response).to redirect_to(root_path)
- end
- it 'logs the user in' do
expect(controller.current_user).to eq user
end
end
@@ -110,16 +104,16 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { email: user.email, password: user.password } }
end
- it 'redirects to home' do
+ it 'redirects to home and logs the user in' do
expect(response).to redirect_to(root_path)
- end
- it 'logs the user in' do
expect(controller.current_user).to eq user
end
end
context 'when using a valid password on a previously-used account with a new IP address' do
+ subject { post :create, params: { user: { email: user.email, password: user.password } } }
+
let(:previous_ip) { '1.2.3.4' }
let(:current_ip) { '4.3.2.1' }
@@ -127,18 +121,17 @@ RSpec.describe Auth::SessionsController do
Fabricate(:login_activity, user: user, ip: previous_ip)
allow(controller.request).to receive(:remote_ip).and_return(current_ip)
user.update(current_sign_in_at: 1.month.ago)
- post :create, params: { user: { email: user.email, password: user.password } }
end
- it 'redirects to home' do
- expect(response).to redirect_to(root_path)
- end
+ it 'logs the user in and sends suspicious email and redirects home', :sidekiq_inline do
+ subject
- it 'logs the user in' do
- expect(controller.current_user).to eq user
- end
+ expect(response)
+ .to redirect_to(root_path)
+
+ expect(controller.current_user)
+ .to eq user
- it 'sends a suspicious sign-in mail', :sidekiq_inline do
expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.suspicious_sign_in.subject'))
@@ -150,11 +143,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { email: user.email.upcase, password: user.password } }
end
- it 'redirects to home' do
+ it 'redirects to home and logs the user in' do
expect(response).to redirect_to(root_path)
- end
- it 'logs the user in' do
expect(controller.current_user).to eq user
end
end
@@ -164,11 +155,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { email: user.email, password: 'wrongpw' } }
end
- it 'shows a login error' do
+ it 'shows a login error and does not log the user in' do
expect(flash[:alert]).to match I18n.t('devise.failure.invalid', authentication_keys: I18n.t('activerecord.attributes.user.email'))
- end
- it "doesn't log the user in" do
expect(controller.current_user).to be_nil
end
end
@@ -270,7 +259,7 @@ RSpec.describe Auth::SessionsController do
travel_to '2023-12-20T10:00:00Z'
end
- it 'does not log the user in' do
+ it 'does not log the user in, sets a flash message, and sends a suspicious sign in email', :sidekiq_inline do
Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR.times do
post :create, params: { user: { otp_attempt: '1234' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
expect(controller.current_user).to be_nil
@@ -278,17 +267,10 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
- expect(controller.current_user).to be_nil
- expect(flash[:alert]).to match I18n.t('users.rate_limited')
- end
-
- it 'sends a suspicious sign-in mail', :sidekiq_inline do
- Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR.times do
- post :create, params: { user: { otp_attempt: '1234' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
- expect(controller.current_user).to be_nil
- end
-
- post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
+ expect(controller.current_user)
+ .to be_nil
+ expect(flash[:alert])
+ .to match I18n.t('users.rate_limited')
expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(user.email)
@@ -301,11 +283,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end
- it 'redirects to home' do
+ it 'redirects to home and logs the user in' do
expect(response).to redirect_to(root_path)
- end
- it 'logs the user in' do
expect(controller.current_user).to eq user
end
end
@@ -318,11 +298,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end
- it 'shows a login error' do
+ it 'shows a login error and does not log the user in' do
expect(flash[:alert]).to match I18n.t('users.invalid_otp_token')
- end
- it "doesn't log the user in" do
expect(controller.current_user).to be_nil
end
end
@@ -332,11 +310,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { otp_attempt: recovery_codes.first } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end
- it 'redirects to home' do
+ it 'redirects to home and logs the user in' do
expect(response).to redirect_to(root_path)
- end
- it 'logs the user in' do
expect(controller.current_user).to eq user
end
end
@@ -346,11 +322,9 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { otp_attempt: 'wrongotp' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end
- it 'shows a login error' do
+ it 'shows a login error and does not log the user in' do
expect(flash[:alert]).to match I18n.t('users.invalid_otp_token')
- end
- it "doesn't log the user in" do
expect(controller.current_user).to be_nil
end
end
@@ -417,15 +391,11 @@ RSpec.describe Auth::SessionsController do
post :create, params: { user: { credential: fake_credential } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end
- it 'instructs the browser to redirect to home' do
+ it 'instructs the browser to redirect to home, logs the user in, and updates the sign count' do
expect(body_as_json[:redirect_path]).to eq(root_path)
- end
- it 'logs the user in' do
expect(controller.current_user).to eq user
- end
- it 'updates the sign count' do
expect(webauthn_credential.reload.sign_count).to eq(sign_count)
end
end
diff --git a/spec/controllers/disputes/appeals_controller_spec.rb b/spec/controllers/disputes/appeals_controller_spec.rb
index da2f86ade5..d763068ebe 100644
--- a/spec/controllers/disputes/appeals_controller_spec.rb
+++ b/spec/controllers/disputes/appeals_controller_spec.rb
@@ -10,19 +10,17 @@ RSpec.describe Disputes::AppealsController do
let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
describe '#create' do
+ subject { post :create, params: params }
+
context 'with valid params' do
let(:current_user) { Fabricate(:user) }
let(:strike) { Fabricate(:account_warning, target_account: current_user.account) }
+ let(:params) { { strike_id: strike.id, appeal: { text: 'Foo' } } }
- before do
- post :create, params: { strike_id: strike.id, appeal: { text: 'Foo' } }
- end
+ it 'notifies staff about new appeal and redirects back to strike page', :sidekiq_inline do
+ subject
- it 'notifies staff about new appeal', :sidekiq_inline do
expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email])
- end
-
- it 'redirects back to the strike page' do
expect(response).to redirect_to(disputes_strike_path(strike.id))
end
end
@@ -30,16 +28,12 @@ RSpec.describe Disputes::AppealsController do
context 'with invalid params' do
let(:current_user) { Fabricate(:user) }
let(:strike) { Fabricate(:account_warning, target_account: current_user.account) }
+ let(:params) { { strike_id: strike.id, appeal: { text: '' } } }
- before do
- post :create, params: { strike_id: strike.id, appeal: { text: '' } }
- end
+ it 'does not send email and renders strike show page', :sidekiq_inline do
+ subject
- it 'does not send email', :sidekiq_inline do
expect(ActionMailer::Base.deliveries.size).to eq(0)
- end
-
- it 'renders the strike show page' do
expect(response).to render_template('disputes/strikes/show')
end
end
diff --git a/spec/controllers/instance_actors_controller_spec.rb b/spec/controllers/instance_actors_controller_spec.rb
index 36b9049fbc..be1eefa7b2 100644
--- a/spec/controllers/instance_actors_controller_spec.rb
+++ b/spec/controllers/instance_actors_controller_spec.rb
@@ -13,17 +13,19 @@ RSpec.describe InstanceActorsController do
end
it 'returns http success with correct media type, headers, and session values' do
- expect(response).to have_http_status(200)
+ expect(response)
+ .to have_http_status(200)
+ .and have_attributes(
+ media_type: eq('application/activity+json'),
+ cookies: be_empty
+ )
- expect(response.media_type).to eq 'application/activity+json'
-
- expect(response.cookies).to be_empty
- expect(response.headers['Set-Cookies']).to be_nil
+ expect(response.headers)
+ .to include('Cache-Control' => include('public'))
+ .and not_include('Set-Cookies')
expect(session).to be_empty
- expect(response.headers['Cache-Control']).to include 'public'
-
expect(body_as_json)
.to include(:id, :type, :preferredUsername, :inbox, :publicKey, :inbox, :outbox, :url)
end
diff --git a/spec/features/admin/domain_blocks_spec.rb b/spec/features/admin/domain_blocks_spec.rb
index 6a1405cdf6..99aa7cf1a7 100644
--- a/spec/features/admin/domain_blocks_spec.rb
+++ b/spec/features/admin/domain_blocks_spec.rb
@@ -12,9 +12,7 @@ describe 'blocking domains through the moderation interface' do
it 'adds a new domain block' do
visit new_admin_domain_block_path
- fill_in 'domain_block_domain', with: 'example.com'
- select I18n.t('admin.domain_blocks.new.severity.silence'), from: 'domain_block_severity'
- click_on I18n.t('admin.domain_blocks.new.create')
+ submit_domain_block('example.com', 'silence')
expect(DomainBlock.exists?(domain: 'example.com', severity: 'silence')).to be true
expect(DomainBlockWorker).to have_received(:perform_async)
@@ -25,9 +23,7 @@ describe 'blocking domains through the moderation interface' do
it 'presents a confirmation screen before suspending the domain' do
visit new_admin_domain_block_path
- fill_in 'domain_block_domain', with: 'example.com'
- select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity'
- click_on I18n.t('admin.domain_blocks.new.create')
+ submit_domain_block('example.com', 'suspend')
# It doesn't immediately block but presents a confirmation screen
expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com'))
@@ -47,9 +43,7 @@ describe 'blocking domains through the moderation interface' do
visit new_admin_domain_block_path
- fill_in 'domain_block_domain', with: 'example.com'
- select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity'
- click_on I18n.t('admin.domain_blocks.new.create')
+ submit_domain_block('example.com', 'suspend')
# It doesn't immediately block but presents a confirmation screen
expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com'))
@@ -69,9 +63,7 @@ describe 'blocking domains through the moderation interface' do
visit new_admin_domain_block_path
- fill_in 'domain_block_domain', with: 'subdomain.example.com'
- select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity'
- click_on I18n.t('admin.domain_blocks.new.create')
+ submit_domain_block('subdomain.example.com', 'suspend')
# It doesn't immediately block but presents a confirmation screen
expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'subdomain.example.com'))
@@ -84,8 +76,11 @@ describe 'blocking domains through the moderation interface' do
expect(DomainBlockWorker).to have_received(:perform_async)
# And leaves the previous block alone
- expect(domain_block.reload.severity).to eq 'silence'
- expect(domain_block.reload.domain).to eq 'example.com'
+ expect(domain_block.reload)
+ .to have_attributes(
+ severity: eq('silence'),
+ domain: eq('example.com')
+ )
end
end
@@ -109,4 +104,12 @@ describe 'blocking domains through the moderation interface' do
expect(domain_block.reload.severity).to eq 'suspend'
end
end
+
+ private
+
+ def submit_domain_block(domain, severity)
+ fill_in 'domain_block_domain', with: domain
+ select I18n.t("admin.domain_blocks.new.severity.#{severity}"), from: 'domain_block_severity'
+ click_on I18n.t('admin.domain_blocks.new.create')
+ end
end
diff --git a/spec/features/captcha_spec.rb b/spec/features/captcha_spec.rb
index 15c37eb463..06c823adf2 100644
--- a/spec/features/captcha_spec.rb
+++ b/spec/features/captcha_spec.rb
@@ -19,12 +19,10 @@ describe 'email confirmation flow when captcha is enabled' do
# It presents the user with a captcha form
expect(page).to have_title(I18n.t('auth.captcha_confirmation.title'))
- # It does not confirm the user just yet
- expect(user.reload.confirmed?).to be false
-
# It redirects to app and confirms user
- click_on I18n.t('challenge.confirm')
- expect(user.reload.confirmed?).to be true
+ expect { click_on I18n.t('challenge.confirm') }
+ .to change { user.reload.confirmed? }.from(false).to(true)
+
expect(page).to have_current_path(/\A#{client_app.confirmation_redirect_uri}/, url: true)
# Browsers will generally reload the original page upon redirection
@@ -32,8 +30,9 @@ describe 'email confirmation flow when captcha is enabled' do
visit "/auth/confirmation?confirmation_token=#{user.confirmation_token}&redirect_to_app=true"
# It presents a page with a link to the app callback
- expect(page).to have_content(I18n.t('auth.confirmations.registration_complete', domain: 'cb6e6126.ngrok.io'))
- expect(page).to have_link(I18n.t('auth.confirmations.clicking_this_link'), href: client_app.confirmation_redirect_uri)
+ expect(page)
+ .to have_content(I18n.t('auth.confirmations.registration_complete', domain: 'cb6e6126.ngrok.io'))
+ .and have_link(I18n.t('auth.confirmations.clicking_this_link'), href: client_app.confirmation_redirect_uri)
end
end
diff --git a/spec/fixtures/files/text.png b/spec/fixtures/files/text.png
new file mode 100644
index 0000000000..7463b54fd5
Binary files /dev/null and b/spec/fixtures/files/text.png differ
diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb
index 5af3615c78..fbaf672b5a 100644
--- a/spec/lib/activitypub/activity/create_spec.rb
+++ b/spec/lib/activitypub/activity/create_spec.rb
@@ -1016,12 +1016,15 @@ RSpec.describe ActivityPub::Activity::Create do
it 'creates an encrypted message' do
encrypted_message = target_device.encrypted_messages.reload.first
- expect(encrypted_message).to_not be_nil
- expect(encrypted_message.from_device_id).to eq '1234'
- expect(encrypted_message.from_account).to eq sender
- expect(encrypted_message.type).to eq 1
- expect(encrypted_message.body).to eq 'Foo'
- expect(encrypted_message.digest).to eq 'Foo123'
+ expect(encrypted_message)
+ .to be_present
+ .and have_attributes(
+ from_device_id: eq('1234'),
+ from_account: eq(sender),
+ type: eq(1),
+ body: eq('Foo'),
+ digest: eq('Foo123')
+ )
end
it 'creates a message franking' do
diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb
index 55e9b4bb51..05d2609b0d 100644
--- a/spec/lib/activitypub/tag_manager_spec.rb
+++ b/spec/lib/activitypub/tag_manager_spec.rb
@@ -52,20 +52,27 @@ RSpec.describe ActivityPub::TagManager do
expect(subject.to(status)).to include(subject.followers_uri_for(mentioned))
end
- it "returns URIs of mentions for direct silenced author's status only if they are followers or requesting to be" do
- bob = Fabricate(:account, username: 'bob')
- alice = Fabricate(:account, username: 'alice')
- foo = Fabricate(:account)
- author = Fabricate(:account, username: 'author', silenced: true)
- status = Fabricate(:status, visibility: :direct, account: author)
- bob.follow!(author)
- FollowRequest.create!(account: foo, target_account: author)
- status.mentions.create(account: alice)
- status.mentions.create(account: bob)
- status.mentions.create(account: foo)
- expect(subject.to(status)).to include(subject.uri_for(bob))
- expect(subject.to(status)).to include(subject.uri_for(foo))
- expect(subject.to(status)).to_not include(subject.uri_for(alice))
+ context 'with followers and requested followers' do
+ let!(:bob) { Fabricate(:account, username: 'bob') }
+ let!(:alice) { Fabricate(:account, username: 'alice') }
+ let!(:foo) { Fabricate(:account) }
+ let!(:author) { Fabricate(:account, username: 'author', silenced: true) }
+ let!(:status) { Fabricate(:status, visibility: :direct, account: author) }
+
+ before do
+ bob.follow!(author)
+ FollowRequest.create!(account: foo, target_account: author)
+ status.mentions.create(account: alice)
+ status.mentions.create(account: bob)
+ status.mentions.create(account: foo)
+ end
+
+ it "returns URIs of mentions for direct silenced author's status only if they are followers or requesting to be" do
+ expect(subject.to(status))
+ .to include(subject.uri_for(bob))
+ .and include(subject.uri_for(foo))
+ .and not_include(subject.uri_for(alice))
+ end
end
end
@@ -97,20 +104,27 @@ RSpec.describe ActivityPub::TagManager do
expect(subject.cc(status)).to include(subject.uri_for(mentioned))
end
- it "returns URIs of mentions for silenced author's non-direct status only if they are followers or requesting to be" do
- bob = Fabricate(:account, username: 'bob')
- alice = Fabricate(:account, username: 'alice')
- foo = Fabricate(:account)
- author = Fabricate(:account, username: 'author', silenced: true)
- status = Fabricate(:status, visibility: :public, account: author)
- bob.follow!(author)
- FollowRequest.create!(account: foo, target_account: author)
- status.mentions.create(account: alice)
- status.mentions.create(account: bob)
- status.mentions.create(account: foo)
- expect(subject.cc(status)).to include(subject.uri_for(bob))
- expect(subject.cc(status)).to include(subject.uri_for(foo))
- expect(subject.cc(status)).to_not include(subject.uri_for(alice))
+ context 'with followers and requested followers' do
+ let!(:bob) { Fabricate(:account, username: 'bob') }
+ let!(:alice) { Fabricate(:account, username: 'alice') }
+ let!(:foo) { Fabricate(:account) }
+ let!(:author) { Fabricate(:account, username: 'author', silenced: true) }
+ let!(:status) { Fabricate(:status, visibility: :public, account: author) }
+
+ before do
+ bob.follow!(author)
+ FollowRequest.create!(account: foo, target_account: author)
+ status.mentions.create(account: alice)
+ status.mentions.create(account: bob)
+ status.mentions.create(account: foo)
+ end
+
+ it "returns URIs of mentions for silenced author's non-direct status only if they are followers or requesting to be" do
+ expect(subject.cc(status))
+ .to include(subject.uri_for(bob))
+ .and include(subject.uri_for(foo))
+ .and not_include(subject.uri_for(alice))
+ end
end
it 'returns poster of reblogged post, if reblog' do
diff --git a/spec/lib/request_pool_spec.rb b/spec/lib/request_pool_spec.rb
index a31d078327..a82eb5a188 100644
--- a/spec/lib/request_pool_spec.rb
+++ b/spec/lib/request_pool_spec.rb
@@ -33,18 +33,14 @@ describe RequestPool do
subject
- threads = Array.new(5) do
- Thread.new do
- subject.with('http://example.com') do |http_client|
- http_client.get('/').flush
- # Nudge scheduler to yield and exercise the full pool
- sleep(0.01)
- end
+ multi_threaded_execution(5) do
+ subject.with('http://example.com') do |http_client|
+ http_client.get('/').flush
+ # Nudge scheduler to yield and exercise the full pool
+ sleep(0.01)
end
end
- threads.map(&:join)
-
expect(subject.size).to be > 1
end
diff --git a/spec/lib/signature_parser_spec.rb b/spec/lib/signature_parser_spec.rb
new file mode 100644
index 0000000000..08e9bea66c
--- /dev/null
+++ b/spec/lib/signature_parser_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe SignatureParser do
+ describe '.parse' do
+ subject { described_class.parse(header) }
+
+ context 'with Signature headers conforming to draft-cavage-http-signatures-12' do
+ let(:header) do
+ # This example signature string deliberately mixes uneven spacing
+ # and quoting styles to ensure everything is covered
+ 'keyId = "https://remote.domain/users/bob#main-key,",algorithm= rsa-sha256 , headers="host date digest (request-target)",signature="gmhMjgMROGElJU3fpehV2acD5kMHeELi8EFP2UPHOdQ54H0r55AxIpji+J3lPe+N2qSb/4H1KXIh6f0lRu8TGSsu12OQmg5hiO8VA9flcA/mh9Lpk+qwlQZIPRqKP9xUEfqD+Z7ti5wPzDKrWAUK/7FIqWgcT/mlqB1R1MGkpMFc/q4CIs2OSNiWgA4K+Kp21oQxzC2kUuYob04gAZ7cyE/FTia5t08uv6lVYFdRsn4XNPn1MsHgFBwBMRG79ng3SyhoG4PrqBEi5q2IdLq3zfre/M6He3wlCpyO2VJNdGVoTIzeZ0Zz8jUscPV3XtWUchpGclLGSaKaq/JyNZeiYQ=="' # rubocop:disable Layout/LineLength
+ end
+
+ it 'correctly parses the header' do
+ expect(subject).to eq({
+ 'keyId' => 'https://remote.domain/users/bob#main-key,',
+ 'algorithm' => 'rsa-sha256',
+ 'headers' => 'host date digest (request-target)',
+ 'signature' => 'gmhMjgMROGElJU3fpehV2acD5kMHeELi8EFP2UPHOdQ54H0r55AxIpji+J3lPe+N2qSb/4H1KXIh6f0lRu8TGSsu12OQmg5hiO8VA9flcA/mh9Lpk+qwlQZIPRqKP9xUEfqD+Z7ti5wPzDKrWAUK/7FIqWgcT/mlqB1R1MGkpMFc/q4CIs2OSNiWgA4K+Kp21oQxzC2kUuYob04gAZ7cyE/FTia5t08uv6lVYFdRsn4XNPn1MsHgFBwBMRG79ng3SyhoG4PrqBEi5q2IdLq3zfre/M6He3wlCpyO2VJNdGVoTIzeZ0Zz8jUscPV3XtWUchpGclLGSaKaq/JyNZeiYQ==', # rubocop:disable Layout/LineLength
+ })
+ end
+ end
+
+ context 'with a malformed Signature header' do
+ let(:header) { 'hello this is malformed!' }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(SignatureParser::ParsingError)
+ end
+ end
+ end
+end
diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb
index 7ef5ca94cc..f6376eb36e 100644
--- a/spec/models/account_spec.rb
+++ b/spec/models/account_spec.rb
@@ -746,13 +746,13 @@ RSpec.describe Account do
end
it 'is valid if we are creating an instance actor account with a period' do
- account = Fabricate.build(:account, id: -99, actor_type: 'Application', locked: true, username: 'example.com')
+ account = Fabricate.build(:account, id: described_class::INSTANCE_ACTOR_ID, actor_type: 'Application', locked: true, username: 'example.com')
expect(account.valid?).to be true
end
it 'is valid if we are creating a possibly-conflicting instance actor account' do
_account = Fabricate(:account, username: 'examplecom')
- instance_account = Fabricate.build(:account, id: -99, actor_type: 'Application', locked: true, username: 'example.com')
+ instance_account = Fabricate.build(:account, id: described_class::INSTANCE_ACTOR_ID, actor_type: 'Application', locked: true, username: 'example.com')
expect(instance_account.valid?).to be true
end
@@ -1035,19 +1035,10 @@ RSpec.describe Account do
it 'increments the count in multi-threaded an environment when account_stat is not yet initialized' do
subject
- increment_by = 15
- wait_for_start = true
-
- threads = Array.new(increment_by) do
- Thread.new do
- true while wait_for_start
- described_class.find(subject.id).increment_count!(:followers_count)
- end
+ multi_threaded_execution(15) do
+ described_class.find(subject.id).increment_count!(:followers_count)
end
- wait_for_start = false
- threads.each(&:join)
-
expect(subject.reload.followers_count).to eq 15
end
end
diff --git a/spec/models/concerns/account/counters_spec.rb b/spec/models/concerns/account/counters_spec.rb
index 2e1cd700bc..3c063a2fa2 100644
--- a/spec/models/concerns/account/counters_spec.rb
+++ b/spec/models/concerns/account/counters_spec.rb
@@ -6,6 +6,8 @@ describe Account::Counters do
let!(:account) { Fabricate(:account) }
describe '#increment_count!' do
+ let(:increment_by) { 15 }
+
it 'increments the count' do
expect(account.followers_count).to eq 0
account.increment_count!(:followers_count)
@@ -13,24 +15,17 @@ describe Account::Counters do
end
it 'increments the count in multi-threaded an environment' do
- increment_by = 15
- wait_for_start = true
-
- threads = Array.new(increment_by) do
- Thread.new do
- true while wait_for_start
- account.increment_count!(:statuses_count)
- end
+ multi_threaded_execution(increment_by) do
+ account.increment_count!(:statuses_count)
end
- wait_for_start = false
- threads.each(&:join)
-
expect(account.statuses_count).to eq increment_by
end
end
describe '#decrement_count!' do
+ let(:decrement_by) { 10 }
+
it 'decrements the count' do
account.followers_count = 15
account.save!
@@ -40,22 +35,13 @@ describe Account::Counters do
end
it 'decrements the count in multi-threaded an environment' do
- decrement_by = 10
- wait_for_start = true
-
account.statuses_count = 15
account.save!
- threads = Array.new(decrement_by) do
- Thread.new do
- true while wait_for_start
- account.decrement_count!(:statuses_count)
- end
+ multi_threaded_execution(decrement_by) do
+ account.decrement_count!(:statuses_count)
end
- wait_for_start = false
- threads.each(&:join)
-
expect(account.statuses_count).to eq 5
end
end
diff --git a/spec/models/media_attachment_spec.rb b/spec/models/media_attachment_spec.rb
index 89916f9f50..1b9a13c38c 100644
--- a/spec/models/media_attachment_spec.rb
+++ b/spec/models/media_attachment_spec.rb
@@ -91,20 +91,15 @@ RSpec.describe MediaAttachment, :paperclip_processing do
end
it 'saves media attachment with correct file metadata' do
- expect(media.persisted?).to be true
- expect(media.file).to_not be_nil
-
- # completes processing
- expect(media.processing_complete?).to be true
-
- # sets type
- expect(media.type).to eq 'image'
-
- # sets content type
- expect(media.file_content_type).to eq content_type
-
- # sets file extension
- expect(media.file_file_name).to end_with extension
+ expect(media)
+ .to be_persisted
+ .and be_processing_complete
+ .and have_attributes(
+ file: be_present,
+ type: eq('image'),
+ file_content_type: eq(content_type),
+ file_file_name: end_with(extension)
+ )
# Rack::Mime (used by PublicFileServerMiddleware) recognizes file extension
expect(Rack::Mime.mime_type(extension, nil)).to eq content_type
@@ -112,17 +107,23 @@ RSpec.describe MediaAttachment, :paperclip_processing do
it 'saves media attachment with correct size metadata' do
# strips original file name
- expect(media.file_file_name).to_not start_with '600x400'
+ expect(media.file_file_name)
+ .to_not start_with '600x400'
- # sets meta for original
- expect(media.file.meta['original']['width']).to eq 600
- expect(media.file.meta['original']['height']).to eq 400
- expect(media.file.meta['original']['aspect']).to eq 1.5
-
- # sets meta for thumbnail
- expect(media.file.meta['small']['width']).to eq 588
- expect(media.file.meta['small']['height']).to eq 392
- expect(media.file.meta['small']['aspect']).to eq 1.5
+ # sets meta for original and thumbnail
+ expect(media.file.meta.deep_symbolize_keys)
+ .to include(
+ original: include(
+ width: eq(600),
+ height: eq(400),
+ aspect: eq(1.5)
+ ),
+ small: include(
+ width: eq(588),
+ height: eq(392),
+ aspect: eq(1.5)
+ )
+ )
end
end
diff --git a/spec/models/user_role_spec.rb b/spec/models/user_role_spec.rb
index d5234ebe8d..9dd04a8172 100644
--- a/spec/models/user_role_spec.rb
+++ b/spec/models/user_role_spec.rb
@@ -164,12 +164,12 @@ RSpec.describe UserRole do
end
describe '#everyone?' do
- it 'returns true when id is -99' do
- subject.id = -99
+ it 'returns true when id matches the everyone id' do
+ subject.id = described_class::EVERYONE_ROLE_ID
expect(subject.everyone?).to be true
end
- it 'returns false when id is not -99' do
+ it 'returns false when id does not match the everyone id' do
subject.id = 123
expect(subject.everyone?).to be false
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 845335e873..1baa3ccbf9 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -451,35 +451,32 @@ RSpec.describe User do
end
describe '#mark_email_as_confirmed!' do
- subject(:user) { Fabricate(:user, confirmed_at: confirmed_at) }
+ subject { user.mark_email_as_confirmed! }
- before do
- ActionMailer::Base.deliveries.clear
- user.mark_email_as_confirmed!
- end
+ let!(:user) { Fabricate(:user, confirmed_at: confirmed_at) }
+
+ before { ActionMailer::Base.deliveries.clear }
after { ActionMailer::Base.deliveries.clear }
context 'when user is new' do
let(:confirmed_at) { nil }
- it 'confirms user' do
- expect(user.confirmed_at).to be_present
- end
+ it 'confirms user and delivers welcome email', :sidekiq_inline do
+ subject
- it 'delivers mails', :sidekiq_inline do
- expect(ActionMailer::Base.deliveries.count).to eq 2
+ expect(user.confirmed_at).to be_present
+ expect(ActionMailer::Base.deliveries.count).to eq 1
end
end
context 'when user is not new' do
let(:confirmed_at) { Time.zone.now }
- it 'confirms user' do
- expect(user.confirmed_at).to be_present
- end
+ it 'confirms user but does not deliver welcome email' do
+ subject
- it 'does not deliver mail' do
+ expect(user.confirmed_at).to be_present
expect(ActionMailer::Base.deliveries.count).to eq 0
end
end
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
index 5125339096..cde5a439db 100644
--- a/spec/rails_helper.rb
+++ b/spec/rails_helper.rb
@@ -86,6 +86,7 @@ RSpec.configure do |config|
config.include ActiveSupport::Testing::TimeHelpers
config.include Chewy::Rspec::Helpers
config.include Redisable
+ config.include ThreadingHelpers
config.include SignedRequestHelpers, type: :request
config.include CommandLineHelpers, type: :cli
diff --git a/spec/services/activitypub/process_status_update_service_spec.rb b/spec/services/activitypub/process_status_update_service_spec.rb
index 53cbaf4cc1..67f2f27276 100644
--- a/spec/services/activitypub/process_status_update_service_spec.rb
+++ b/spec/services/activitypub/process_status_update_service_spec.rb
@@ -218,7 +218,8 @@ RSpec.describe ActivityPub::ProcessStatusUpdateService, type: :service do
end
it 'does not update the text, spoiler_text or edited_at' do
- expect { subject.call(status, json, json) }.to_not(change { s = status.reload; [s.text, s.spoiler_text, s.edited_at] })
+ expect { subject.call(status, json, json) }
+ .to_not(change { status.reload.attributes.slice('text', 'spoiler_text', 'edited_at').values })
end
end
diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb
index d10a82607e..acbebc5056 100644
--- a/spec/services/post_status_service_spec.rb
+++ b/spec/services/post_status_service_spec.rb
@@ -32,27 +32,27 @@ RSpec.describe PostStatusService, type: :service do
let!(:future) { Time.now.utc + 2.hours }
let!(:previous_status) { Fabricate(:status, account: account) }
- it 'schedules a status' do
- status = subject.call(account, text: 'Hi future!', scheduled_at: future)
- expect(status).to be_a ScheduledStatus
- expect(status.scheduled_at).to eq future
- expect(status.params['text']).to eq 'Hi future!'
- end
-
- it 'does not immediately create a status' do
+ it 'schedules a status for future creation and does not create one immediately' do
media = Fabricate(:media_attachment, account: account)
status = subject.call(account, text: 'Hi future!', media_ids: [media.id], scheduled_at: future)
- expect(status).to be_a ScheduledStatus
- expect(status.scheduled_at).to eq future
- expect(status.params['text']).to eq 'Hi future!'
- expect(status.params['media_ids']).to eq [media.id]
+ expect(status)
+ .to be_a(ScheduledStatus)
+ .and have_attributes(
+ scheduled_at: eq(future),
+ params: include(
+ 'text' => eq('Hi future!'),
+ 'media_ids' => contain_exactly(media.id)
+ )
+ )
expect(media.reload.status).to be_nil
expect(Status.where(text: 'Hi future!')).to_not exist
end
- it 'does not change statuses count' do
- expect { subject.call(account, text: 'Hi future!', scheduled_at: future, thread: previous_status) }.to_not(change { [account.statuses_count, previous_status.replies_count] })
+ it 'does not change statuses_count of account or replies_count of thread previous status' do
+ expect { subject.call(account, text: 'Hi future!', scheduled_at: future, thread: previous_status) }
+ .to not_change { account.statuses_count }
+ .and(not_change { previous_status.replies_count })
end
end
diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb
index 1c4c3b4016..b82e5b3865 100644
--- a/spec/services/resolve_account_service_spec.rb
+++ b/spec/services/resolve_account_service_spec.rb
@@ -219,27 +219,19 @@ RSpec.describe ResolveAccountService, type: :service do
end
it 'processes one remote account at a time using locks' do
- wait_for_start = true
fail_occurred = false
return_values = Concurrent::Array.new
- threads = Array.new(5) do
- Thread.new do
- true while wait_for_start
-
- begin
- return_values << described_class.new.call('foo@ap.example.com')
- rescue ActiveRecord::RecordNotUnique
- fail_occurred = true
- ensure
- RedisConfiguration.pool.checkin if Thread.current[:redis]
- end
+ multi_threaded_execution(5) do
+ begin
+ return_values << described_class.new.call('foo@ap.example.com')
+ rescue ActiveRecord::RecordNotUnique
+ fail_occurred = true
+ ensure
+ RedisConfiguration.pool.checkin if Thread.current[:redis]
end
end
- wait_for_start = false
- threads.each(&:join)
-
expect(fail_occurred).to be false
expect(return_values).to_not include(nil)
end
diff --git a/spec/support/threading_helpers.rb b/spec/support/threading_helpers.rb
new file mode 100644
index 0000000000..edf45822ca
--- /dev/null
+++ b/spec/support/threading_helpers.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module ThreadingHelpers
+ def multi_threaded_execution(thread_count)
+ wait_for_start = true
+
+ threads = Array.new(thread_count) do
+ Thread.new do
+ true while wait_for_start
+ yield
+ end
+ end
+
+ wait_for_start = false
+ threads.each(&:join)
+ end
+end
diff --git a/spec/system/ocr_spec.rb b/spec/system/ocr_spec.rb
new file mode 100644
index 0000000000..254efa7137
--- /dev/null
+++ b/spec/system/ocr_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'OCR', :paperclip_processing, :sidekiq_inline do
+ include ProfileStories
+
+ let(:email) { 'test@example.com' }
+ let(:password) { 'password' }
+ let(:confirmed_at) { Time.zone.now }
+ let(:finished_onboarding) { true }
+
+ before do
+ as_a_logged_in_user
+ visit root_path
+ end
+
+ it 'can recognize text in a media attachment' do
+ expect(page).to have_css('div.app-holder')
+
+ within('.compose-form') do
+ attach_file('file-upload-input', file_fixture('text.png'), make_visible: true)
+
+ within('.compose-form__upload') do
+ click_on('Edit')
+ end
+ end
+
+ click_on('Detect text from picture')
+
+ expect(page).to have_css('#upload-modal__description', text: /Hello Mastodon\s*/, wait: 10)
+ end
+end
diff --git a/spec/validators/blacklisted_email_validator_spec.rb b/spec/validators/blacklisted_email_validator_spec.rb
index 6292f0737e..86760df2e7 100644
--- a/spec/validators/blacklisted_email_validator_spec.rb
+++ b/spec/validators/blacklisted_email_validator_spec.rb
@@ -4,7 +4,7 @@ require 'rails_helper'
RSpec.describe BlacklistedEmailValidator do
describe '#validate' do
- subject { described_class.new.validate(user); errors }
+ subject { described_class.new.validate(user) }
let(:user) { instance_double(User, email: 'info@mail.com', sign_up_ip: '1.2.3.4', errors: errors) }
let(:errors) { instance_double(ActiveModel::Errors, add: nil) }
@@ -18,7 +18,8 @@ RSpec.describe BlacklistedEmailValidator do
let(:blocked_email) { true }
it 'adds error' do
- described_class.new.validate(user)
+ subject
+
expect(errors).to have_received(:add).with(:email, :blocked).once
end
end
@@ -27,7 +28,8 @@ RSpec.describe BlacklistedEmailValidator do
let(:blocked_email) { false }
it 'does not add errors' do
- described_class.new.validate(user)
+ subject
+
expect(errors).to_not have_received(:add)
end
@@ -39,7 +41,8 @@ RSpec.describe BlacklistedEmailValidator do
end
it 'adds error' do
- described_class.new.validate(user)
+ subject
+
expect(errors).to have_received(:add).with(:email, :taken).once
end
end
diff --git a/spec/validators/email_mx_validator_spec.rb b/spec/validators/email_mx_validator_spec.rb
index 21b1ad0a11..bc26be8729 100644
--- a/spec/validators/email_mx_validator_spec.rb
+++ b/spec/validators/email_mx_validator_spec.rb
@@ -5,6 +5,7 @@ require 'rails_helper'
describe EmailMxValidator do
describe '#validate' do
let(:user) { instance_double(User, email: 'foo@example.com', sign_up_ip: '1.2.3.4', errors: instance_double(ActiveModel::Errors, add: nil)) }
+ let(:resolv_dns_double) { instance_double(Resolv::DNS) }
context 'with an e-mail domain that is explicitly allowed' do
around do |block|
@@ -15,13 +16,7 @@ describe EmailMxValidator do
end
it 'does not add errors if there are no DNS records' do
- resolver = instance_double(Resolv::DNS)
-
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
- allow(resolver).to receive(:timeouts=).and_return(nil)
- allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+ configure_resolver('example.com')
subject.validate(user)
expect(user.errors).to_not have_received(:add)
@@ -29,13 +24,7 @@ describe EmailMxValidator do
end
it 'adds no error if there are DNS records for the e-mail domain' do
- resolver = instance_double(Resolv::DNS)
-
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([Resolv::DNS::Resource::IN::A.new('192.0.2.42')])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
- allow(resolver).to receive(:timeouts=).and_return(nil)
- allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+ configure_resolver('example.com', a: resolv_double_a('192.0.2.42'))
subject.validate(user)
expect(user.errors).to_not have_received(:add)
@@ -58,13 +47,7 @@ describe EmailMxValidator do
end
it 'adds an error if the email domain name contains empty labels' do
- resolver = instance_double(Resolv::DNS)
-
- allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::MX).and_return([])
- allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::A).and_return([Resolv::DNS::Resource::IN::A.new('192.0.2.42')])
- allow(resolver).to receive(:getresources).with('example..com', Resolv::DNS::Resource::IN::AAAA).and_return([])
- allow(resolver).to receive(:timeouts=).and_return(nil)
- allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+ configure_resolver('example..com', a: resolv_double_a('192.0.2.42'))
user = instance_double(User, email: 'foo@example..com', sign_up_ip: '1.2.3.4', errors: instance_double(ActiveModel::Errors, add: nil))
subject.validate(user)
@@ -72,30 +55,15 @@ describe EmailMxValidator do
end
it 'adds an error if there are no DNS records for the e-mail domain' do
- resolver = instance_double(Resolv::DNS)
-
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::MX).and_return([])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
- allow(resolver).to receive(:timeouts=).and_return(nil)
- allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+ configure_resolver('example.com')
subject.validate(user)
expect(user.errors).to have_received(:add)
end
it 'adds an error if a MX record does not lead to an IP' do
- resolver = instance_double(Resolv::DNS)
-
- allow(resolver).to receive(:getresources)
- .with('example.com', Resolv::DNS::Resource::IN::MX)
- .and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'mail.example.com')])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
- allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([])
- allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
- allow(resolver).to receive(:timeouts=).and_return(nil)
- allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+ configure_resolver('example.com', mx: resolv_double_mx('mail.example.com'))
+ configure_resolver('mail.example.com')
subject.validate(user)
expect(user.errors).to have_received(:add)
@@ -103,20 +71,48 @@ describe EmailMxValidator do
it 'adds an error if the MX record is blacklisted' do
EmailDomainBlock.create!(domain: 'mail.example.com')
- resolver = instance_double(Resolv::DNS)
- allow(resolver).to receive(:getresources)
- .with('example.com', Resolv::DNS::Resource::IN::MX)
- .and_return([instance_double(Resolv::DNS::Resource::MX, exchange: 'mail.example.com')])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::A).and_return([])
- allow(resolver).to receive(:getresources).with('example.com', Resolv::DNS::Resource::IN::AAAA).and_return([])
- allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::A).and_return([instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5')])
- allow(resolver).to receive(:getresources).with('mail.example.com', Resolv::DNS::Resource::IN::AAAA).and_return([instance_double(Resolv::DNS::Resource::IN::AAAA, address: 'fd00::2')])
- allow(resolver).to receive(:timeouts=).and_return(nil)
- allow(Resolv::DNS).to receive(:open).and_yield(resolver)
+ configure_resolver(
+ 'example.com',
+ mx: resolv_double_mx('mail.example.com')
+ )
+ configure_resolver(
+ 'mail.example.com',
+ a: instance_double(Resolv::DNS::Resource::IN::A, address: '2.3.4.5'),
+ aaaa: instance_double(Resolv::DNS::Resource::IN::AAAA, address: 'fd00::2')
+ )
subject.validate(user)
expect(user.errors).to have_received(:add)
end
end
+
+ def configure_resolver(domain, options = {})
+ allow(resolv_dns_double)
+ .to receive(:getresources)
+ .with(domain, Resolv::DNS::Resource::IN::MX)
+ .and_return(Array(options[:mx]))
+ allow(resolv_dns_double)
+ .to receive(:getresources)
+ .with(domain, Resolv::DNS::Resource::IN::A)
+ .and_return(Array(options[:a]))
+ allow(resolv_dns_double)
+ .to receive(:getresources)
+ .with(domain, Resolv::DNS::Resource::IN::AAAA)
+ .and_return(Array(options[:aaaa]))
+ allow(resolv_dns_double)
+ .to receive(:timeouts=)
+ .and_return(nil)
+ allow(Resolv::DNS)
+ .to receive(:open)
+ .and_yield(resolv_dns_double)
+ end
+
+ def resolv_double_mx(domain)
+ instance_double(Resolv::DNS::Resource::MX, exchange: domain)
+ end
+
+ def resolv_double_a(domain)
+ Resolv::DNS::Resource::IN::A.new(domain)
+ end
end
diff --git a/yarn.lock b/yarn.lock
index aa44efdf6f..771a06927b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1697,14 +1697,14 @@ __metadata:
languageName: node
linkType: hard
-"@es-joy/jsdoccomment@npm:~0.41.0":
- version: 0.41.0
- resolution: "@es-joy/jsdoccomment@npm:0.41.0"
+"@es-joy/jsdoccomment@npm:~0.42.0":
+ version: 0.42.0
+ resolution: "@es-joy/jsdoccomment@npm:0.42.0"
dependencies:
comment-parser: "npm:1.4.1"
esquery: "npm:^1.5.0"
jsdoc-type-pratt-parser: "npm:~4.0.0"
- checksum: 1fa27531eba32e4699664da53a0865aeeda1f7e83ac156fe53b7a6b09d2f3816baa94a34845ff019c10289b09572bda5519ec917e3e241088975477fa880f72d
+ checksum: a8122762d2df3c6501a9c459e2822315a23c0078c4aeb0b40fb3c84b99e21a78e85e67f962d6b5dde5eb751792a1c67c6a170b619573db7151098a19950abe35
languageName: node
linkType: hard
@@ -2611,11 +2611,11 @@ __metadata:
linkType: hard
"@reduxjs/toolkit@npm:^2.0.1":
- version: 2.0.1
- resolution: "@reduxjs/toolkit@npm:2.0.1"
+ version: 2.1.0
+ resolution: "@reduxjs/toolkit@npm:2.1.0"
dependencies:
immer: "npm:^10.0.3"
- redux: "npm:^5.0.0"
+ redux: "npm:^5.0.1"
redux-thunk: "npm:^3.1.0"
reselect: "npm:^5.0.1"
peerDependencies:
@@ -2626,7 +2626,7 @@ __metadata:
optional: true
react-redux:
optional: true
- checksum: 161b9b8e11d9688890ab97b604a4c10c0d41b1369425a5fa821586932db4cd5a391d15799732b3612e6120a6336458ff577ff254219315c05ecd68da5d15fd79
+ checksum: 4ea9e9ea8cc2cab1c997127dc332c165cebc55bf8e95812ba4dc40d48dd87d5ee4bf3316b9eab49b5cce056eda6bdcb4b2a7dc3a15f056f64f76134f148f9f10
languageName: node
linkType: hard
@@ -3662,14 +3662,14 @@ __metadata:
linkType: hard
"@typescript-eslint/eslint-plugin@npm:^6.0.0":
- version: 6.20.0
- resolution: "@typescript-eslint/eslint-plugin@npm:6.20.0"
+ version: 6.21.0
+ resolution: "@typescript-eslint/eslint-plugin@npm:6.21.0"
dependencies:
"@eslint-community/regexpp": "npm:^4.5.1"
- "@typescript-eslint/scope-manager": "npm:6.20.0"
- "@typescript-eslint/type-utils": "npm:6.20.0"
- "@typescript-eslint/utils": "npm:6.20.0"
- "@typescript-eslint/visitor-keys": "npm:6.20.0"
+ "@typescript-eslint/scope-manager": "npm:6.21.0"
+ "@typescript-eslint/type-utils": "npm:6.21.0"
+ "@typescript-eslint/utils": "npm:6.21.0"
+ "@typescript-eslint/visitor-keys": "npm:6.21.0"
debug: "npm:^4.3.4"
graphemer: "npm:^1.4.0"
ignore: "npm:^5.2.4"
@@ -3682,44 +3682,44 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 5020faac39be476de056342f58f2bf68bb788f230e2fa4a2e27ceab8a5187dc450beba7333b0aa741a43aeaff45a117558132953f9390b5eca4c2cc004fde716
+ checksum: f911a79ee64d642f814a3b6cdb0d324b5f45d9ef955c5033e78903f626b7239b4aa773e464a38c3e667519066169d983538f2bf8e5d00228af587c9d438fb344
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:^6.17.0":
- version: 6.20.0
- resolution: "@typescript-eslint/parser@npm:6.20.0"
+ version: 6.21.0
+ resolution: "@typescript-eslint/parser@npm:6.21.0"
dependencies:
- "@typescript-eslint/scope-manager": "npm:6.20.0"
- "@typescript-eslint/types": "npm:6.20.0"
- "@typescript-eslint/typescript-estree": "npm:6.20.0"
- "@typescript-eslint/visitor-keys": "npm:6.20.0"
+ "@typescript-eslint/scope-manager": "npm:6.21.0"
+ "@typescript-eslint/types": "npm:6.21.0"
+ "@typescript-eslint/typescript-estree": "npm:6.21.0"
+ "@typescript-eslint/visitor-keys": "npm:6.21.0"
debug: "npm:^4.3.4"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
peerDependenciesMeta:
typescript:
optional: true
- checksum: d84ad5e2282b1096c80dedb903c83ecc31eaf7be1aafcb14c18d9ec2d4a319f2fd1e5a9038b944d9f42c36c1c57add5e4292d4026ca7d3d5441d41286700d402
+ checksum: a8f99820679decd0d115c0af61903fb1de3b1b5bec412dc72b67670bf636de77ab07f2a68ee65d6da7976039bbf636907f9d5ca546db3f0b98a31ffbc225bc7d
languageName: node
linkType: hard
-"@typescript-eslint/scope-manager@npm:6.20.0":
- version: 6.20.0
- resolution: "@typescript-eslint/scope-manager@npm:6.20.0"
+"@typescript-eslint/scope-manager@npm:6.21.0":
+ version: 6.21.0
+ resolution: "@typescript-eslint/scope-manager@npm:6.21.0"
dependencies:
- "@typescript-eslint/types": "npm:6.20.0"
- "@typescript-eslint/visitor-keys": "npm:6.20.0"
- checksum: f6768ed2dcd2d1771d55ed567ff392a6569ffd683a26500067509dd41769f8838c43686460fe7337144f324fd063df33f5d5646d44e5df4998ceffb3ad1fb790
+ "@typescript-eslint/types": "npm:6.21.0"
+ "@typescript-eslint/visitor-keys": "npm:6.21.0"
+ checksum: eaf868938d811cbbea33e97e44ba7050d2b6892202cea6a9622c486b85ab1cf801979edf78036179a8ba4ac26f1dfdf7fcc83a68c1ff66be0b3a8e9a9989b526
languageName: node
linkType: hard
-"@typescript-eslint/type-utils@npm:6.20.0":
- version: 6.20.0
- resolution: "@typescript-eslint/type-utils@npm:6.20.0"
+"@typescript-eslint/type-utils@npm:6.21.0":
+ version: 6.21.0
+ resolution: "@typescript-eslint/type-utils@npm:6.21.0"
dependencies:
- "@typescript-eslint/typescript-estree": "npm:6.20.0"
- "@typescript-eslint/utils": "npm:6.20.0"
+ "@typescript-eslint/typescript-estree": "npm:6.21.0"
+ "@typescript-eslint/utils": "npm:6.21.0"
debug: "npm:^4.3.4"
ts-api-utils: "npm:^1.0.1"
peerDependencies:
@@ -3727,23 +3727,23 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 8f622fbb14268f1d00b2948f995b570f0ef82be02c12be41d90385290a56ea0dbd34d855d6a5aff100b57f3bdd300ff0c300f16c78f12d6064f7ae6e34fd71bf
+ checksum: 7409c97d1c4a4386b488962739c4f1b5b04dc60cf51f8cd88e6b12541f84d84c6b8b67e491a147a2c95f9ec486539bf4519fb9d418411aef6537b9c156468117
languageName: node
linkType: hard
-"@typescript-eslint/types@npm:6.20.0":
- version: 6.20.0
- resolution: "@typescript-eslint/types@npm:6.20.0"
- checksum: 37589003b0e06f83c1945e3748e91af85918cfd997766894642a08e6f355f611cfe11df4e7632dda96e3a9b3441406283fe834ab0906cf81ea97fd43ca2aebe3
+"@typescript-eslint/types@npm:6.21.0":
+ version: 6.21.0
+ resolution: "@typescript-eslint/types@npm:6.21.0"
+ checksum: 020631d3223bbcff8a0da3efbdf058220a8f48a3de221563996ad1dcc30d6c08dadc3f7608cc08830d21c0d565efd2db19b557b9528921c78aabb605eef2d74d
languageName: node
linkType: hard
-"@typescript-eslint/typescript-estree@npm:6.20.0":
- version: 6.20.0
- resolution: "@typescript-eslint/typescript-estree@npm:6.20.0"
+"@typescript-eslint/typescript-estree@npm:6.21.0":
+ version: 6.21.0
+ resolution: "@typescript-eslint/typescript-estree@npm:6.21.0"
dependencies:
- "@typescript-eslint/types": "npm:6.20.0"
- "@typescript-eslint/visitor-keys": "npm:6.20.0"
+ "@typescript-eslint/types": "npm:6.21.0"
+ "@typescript-eslint/visitor-keys": "npm:6.21.0"
debug: "npm:^4.3.4"
globby: "npm:^11.1.0"
is-glob: "npm:^4.0.3"
@@ -3753,34 +3753,34 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 551f13445a303882d9fc0fbe14ef8507eb8414253fd87a5f13d2e324b5280b626421a238b8ec038e628bc80128dc06c057757f668738e82e64d5b39a9083c27d
+ checksum: af1438c60f080045ebb330155a8c9bb90db345d5069cdd5d01b67de502abb7449d6c75500519df829f913a6b3f490ade3e8215279b6bdc63d0fb0ae61034df5f
languageName: node
linkType: hard
-"@typescript-eslint/utils@npm:6.20.0, @typescript-eslint/utils@npm:^6.18.1":
- version: 6.20.0
- resolution: "@typescript-eslint/utils@npm:6.20.0"
+"@typescript-eslint/utils@npm:6.21.0, @typescript-eslint/utils@npm:^6.18.1":
+ version: 6.21.0
+ resolution: "@typescript-eslint/utils@npm:6.21.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0"
"@types/json-schema": "npm:^7.0.12"
"@types/semver": "npm:^7.5.0"
- "@typescript-eslint/scope-manager": "npm:6.20.0"
- "@typescript-eslint/types": "npm:6.20.0"
- "@typescript-eslint/typescript-estree": "npm:6.20.0"
+ "@typescript-eslint/scope-manager": "npm:6.21.0"
+ "@typescript-eslint/types": "npm:6.21.0"
+ "@typescript-eslint/typescript-estree": "npm:6.21.0"
semver: "npm:^7.5.4"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
- checksum: 0a8ede3d80a365b52ae96d88e4a9f6e6abf3569c6b60ff9f42ff900cd843ae7c5493cd95f8f2029d90bb0acbf31030980206af98e581d760d6d41e0f80e9fb86
+ checksum: ab2df3833b2582d4e5467a484d08942b4f2f7208f8e09d67de510008eb8001a9b7460f2f9ba11c12086fd3cdcac0c626761c7995c2c6b5657d5fa6b82030a32d
languageName: node
linkType: hard
-"@typescript-eslint/visitor-keys@npm:6.20.0":
- version: 6.20.0
- resolution: "@typescript-eslint/visitor-keys@npm:6.20.0"
+"@typescript-eslint/visitor-keys@npm:6.21.0":
+ version: 6.21.0
+ resolution: "@typescript-eslint/visitor-keys@npm:6.21.0"
dependencies:
- "@typescript-eslint/types": "npm:6.20.0"
+ "@typescript-eslint/types": "npm:6.21.0"
eslint-visitor-keys: "npm:^3.4.1"
- checksum: 852d938f2e5d57200cf62733b42e73a369f797b097d17e8fd3fffd0f7315c3b9e1863eed60bb8d57d6535a3b7f1980f645f96ec6d513950f182bfa8107b33fab
+ checksum: 7395f69739cfa1cb83c1fb2fad30afa2a814756367302fb4facd5893eff66abc807e8d8f63eba94ed3b0fe0c1c996ac9a1680bcbf0f83717acedc3f2bb724fbf
languageName: node
linkType: hard
@@ -6850,9 +6850,9 @@ __metadata:
linkType: hard
"dotenv@npm:^16.0.3":
- version: 16.4.1
- resolution: "dotenv@npm:16.4.1"
- checksum: ef3d95f48f38146df0881a4b58447ae437d2da3f6d645074b84de4e64ef64ba75fc357c5ed66b3c2b813b5369fdeb6a4777d6ade2d50e54eed6aa06dddc98bc4
+ version: 16.4.3
+ resolution: "dotenv@npm:16.4.3"
+ checksum: c6a572b2dab5d71accb7064c90b38dfd4068c2487be859a0f053460fcaa685a7718e78db51d643b32e0736b318988c31f8c45cb4ab99cd620278f537177cb0ab
languageName: node
linkType: hard
@@ -7353,21 +7353,21 @@ __metadata:
linkType: hard
"eslint-plugin-jsdoc@npm:^48.0.0":
- version: 48.0.4
- resolution: "eslint-plugin-jsdoc@npm:48.0.4"
+ version: 48.1.0
+ resolution: "eslint-plugin-jsdoc@npm:48.1.0"
dependencies:
- "@es-joy/jsdoccomment": "npm:~0.41.0"
+ "@es-joy/jsdoccomment": "npm:~0.42.0"
are-docs-informative: "npm:^0.0.2"
comment-parser: "npm:1.4.1"
debug: "npm:^4.3.4"
escape-string-regexp: "npm:^4.0.0"
esquery: "npm:^1.5.0"
is-builtin-module: "npm:^3.2.1"
- semver: "npm:^7.5.4"
+ semver: "npm:^7.6.0"
spdx-expression-parse: "npm:^4.0.0"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
- checksum: c73063d26ca70d37ea00eea9750d1f889e5bfda64ca46dbfc6bf4842b892551c320368220cb46acc9d3d96a89fd5391486650284b82dc722f700e3b5df5c78db
+ checksum: e0fb3fb4479b6ee539b8c1b626de625ff5d24408f695fcbf648e214854fea9ea3e29b77f56b177bf38655e30a6c9a6eaaff93ef990f69c454c74e180747e39e5
languageName: node
linkType: hard
@@ -13155,13 +13155,13 @@ __metadata:
linkType: hard
"postcss@npm:^8.2.15, postcss@npm:^8.4.24, postcss@npm:^8.4.33":
- version: 8.4.34
- resolution: "postcss@npm:8.4.34"
+ version: 8.4.35
+ resolution: "postcss@npm:8.4.35"
dependencies:
nanoid: "npm:^3.3.7"
picocolors: "npm:^1.0.0"
source-map-js: "npm:^1.0.2"
- checksum: 4d6f072cdfdc1ced16b4336263d830f8b4397fc47b9b382e02f6448fda9386d881aa9d27fbe0dd124f59c76f3a5da4f360919d25dfc818eca50b48f042af35a8
+ checksum: e8dd04e48001eb5857abc9475365bf08f4e508ddf9bc0b8525449a95d190f10d025acebc5b56ac2e94b3c7146790e4ae78989bb9633cb7ee20d1cc9b7dc909b2
languageName: node
linkType: hard
@@ -14079,7 +14079,7 @@ __metadata:
languageName: node
linkType: hard
-"redux@npm:^5.0.0":
+"redux@npm:^5.0.1":
version: 5.0.1
resolution: "redux@npm:5.0.1"
checksum: b10c28357194f38e7d53b760ed5e64faa317cc63de1fb95bc5d9e127fab956392344368c357b8e7a9bedb0c35b111e7efa522210cfdc3b3c75e5074718e9069c
@@ -14732,14 +14732,14 @@ __metadata:
languageName: node
linkType: hard
-"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4":
- version: 7.5.4
- resolution: "semver@npm:7.5.4"
+"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0":
+ version: 7.6.0
+ resolution: "semver@npm:7.6.0"
dependencies:
lru-cache: "npm:^6.0.0"
bin:
semver: bin/semver.js
- checksum: 5160b06975a38b11c1ab55950cb5b8a23db78df88275d3d8a42ccf1f29e55112ac995b3a26a522c36e3b5f76b0445f1eef70d696b8c7862a2b4303d7b0e7609e
+ checksum: fbfe717094ace0aa8d6332d7ef5ce727259815bd8d8815700853f4faf23aacbd7192522f0dc5af6df52ef4fa85a355ebd2f5d39f554bd028200d6cf481ab9b53
languageName: node
linkType: hard