From e9dc30cdbaf97ffd802e6503fbacdadf5d95dadb Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 18 Oct 2023 10:18:34 +0200 Subject: [PATCH 01/13] Fix duplicate github annotations for rspec failures (#27450) --- .github/workflows/test-ruby.yml | 1 + spec/spec_helper.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index 0d0215bc0..f8280a22f 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -113,6 +113,7 @@ jobs: CAS_ENABLED: true BUNDLE_WITH: 'pam_authentication test' CI_JOBS: ${{ matrix.ci_job }}/4 + GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' }} strategy: fail-fast: false diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4d3c234a0..6ff0a8f84 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -38,7 +38,7 @@ RSpec.configure do |config| end # Use the GitHub Annotations formatter for CI - if ENV['GITHUB_ACTIONS'] == 'true' + if ENV['GITHUB_ACTIONS'] == 'true' && ENV['GITHUB_RSPEC'] == 'true' require 'rspec/github' config.add_formatter RSpec::Github::Formatter end From 091a21e1bc5e1e9933fc91d2dc8f6148f85f3a28 Mon Sep 17 00:00:00 2001 From: Daniel M Brasil Date: Wed, 18 Oct 2023 05:20:50 -0300 Subject: [PATCH 02/13] Add test coverage for `Mastodon::CLI::Accounts#prune` (#25204) --- spec/lib/mastodon/cli/accounts_spec.rb | 73 ++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb index 5ecea5ea1..6d6d81c41 100644 --- a/spec/lib/mastodon/cli/accounts_spec.rb +++ b/spec/lib/mastodon/cli/accounts_spec.rb @@ -1356,4 +1356,77 @@ describe Mastodon::CLI::Accounts do end end end + + describe '#prune' do + let!(:local_account) { Fabricate(:account) } + let!(:bot_account) { Fabricate(:account, bot: true, domain: 'example.com') } + let!(:group_account) { Fabricate(:account, actor_type: 'Group', domain: 'example.com') } + let!(:mentioned_account) { Fabricate(:account, domain: 'example.com') } + let!(:prunable_accounts) do + Fabricate.times(3, :account, domain: 'example.com', bot: false, suspended_at: nil, silenced_at: nil) + end + + before do + Fabricate(:mention, account: mentioned_account, status: Fabricate(:status, account: Fabricate(:account))) + stub_parallelize_with_progress! + end + + it 'prunes all remote accounts with no interactions with local users' do + cli.prune + + prunable_account_ids = prunable_accounts.pluck(:id) + + expect(Account.where(id: prunable_account_ids).count).to eq(0) + end + + it 'displays a successful message' do + expect { cli.prune }.to output( + a_string_including("OK, pruned #{prunable_accounts.size} accounts") + ).to_stdout + end + + it 'does not prune local accounts' do + cli.prune + + expect(Account.exists?(id: local_account.id)).to be(true) + end + + it 'does not prune bot accounts' do + cli.prune + + expect(Account.exists?(id: bot_account.id)).to be(true) + end + + it 'does not prune group accounts' do + cli.prune + + expect(Account.exists?(id: group_account.id)).to be(true) + end + + it 'does not prune accounts that have been mentioned' do + cli.prune + + expect(Account.exists?(id: mentioned_account.id)).to be true + end + + context 'with --dry-run option' do + before do + cli.options = { dry_run: true } + end + + it 'does not prune any account' do + cli.prune + + prunable_account_ids = prunable_accounts.pluck(:id) + + expect(Account.where(id: prunable_account_ids).count).to eq(prunable_accounts.size) + end + + it 'displays a successful message with (DRY RUN)' do + expect { cli.prune }.to output( + a_string_including("OK, pruned #{prunable_accounts.size} accounts (DRY RUN)") + ).to_stdout + end + end + end end From 63a2a4b074f09bc7b6fe1b5e7f50de18033e52a4 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 18 Oct 2023 04:32:09 -0400 Subject: [PATCH 03/13] Fix `Performance/DeletePrefix` cop (#27448) --- .rubocop_todo.yml | 6 ------ app/models/featured_tag.rb | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 980339f49..bee9e7155 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -100,12 +100,6 @@ Naming/VariableNumber: - 'spec/models/domain_block_spec.rb' - 'spec/models/user_spec.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: SafeMultiline. -Performance/DeletePrefix: - Exclude: - - 'app/models/featured_tag.rb' - Performance/MapMethodChain: Exclude: - 'app/models/feed.rb' diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb index 587dcf991..df23114a3 100644 --- a/app/models/featured_tag.rb +++ b/app/models/featured_tag.rb @@ -51,7 +51,7 @@ class FeaturedTag < ApplicationRecord private def strip_name - self.name = name&.strip&.gsub(/\A#/, '') + self.name = name&.strip&.delete_prefix('#') end def set_tag From 4612576c6828c6e24b8c3cdceff377e2135b384a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Oct 2023 11:08:10 +0200 Subject: [PATCH 04/13] New Crowdin Translations (automated) (#27454) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/fi.json | 22 +++++++++++----------- config/locales/activerecord.sk.yml | 4 ++++ config/locales/doorkeeper.sk.yml | 12 ++++++++++++ config/locales/fi.yml | 8 ++++---- config/locales/simple_form.fi.yml | 6 +++--- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index a7a68533d..aac4256ff 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -71,11 +71,11 @@ "account.unmute_notifications_short": "Poista ilmoitusten mykistys", "account.unmute_short": "Poista mykistys", "account_note.placeholder": "Lisää muistiinpano napsauttamalla", - "admin.dashboard.daily_retention": "Käyttäjän pysyminen rekisteröitymisen jälkeiseen päivään mennessä", - "admin.dashboard.monthly_retention": "Käyttäjän pysyminen rekisteröitymisen jälkeiseen kuukauteen mennessä", + "admin.dashboard.daily_retention": "Käyttäjien pysyvyys rekisteröitymisen jälkeen päivittäin", + "admin.dashboard.monthly_retention": "Käyttäjien pysyvyys rekisteröitymisen jälkeen kuukausittain", "admin.dashboard.retention.average": "Keskimäärin", - "admin.dashboard.retention.cohort": "Kirjautumiset", - "admin.dashboard.retention.cohort_size": "Uudet käyttäjät", + "admin.dashboard.retention.cohort": "Rekisteröitymis-kk.", + "admin.dashboard.retention.cohort_size": "Uusia käyttäjiä", "admin.impact_report.instance_accounts": "Tilien profiilit, jotka tämä poistaisi", "admin.impact_report.instance_followers": "Seuraajat, jotka käyttäjämme menettäisivät", "admin.impact_report.instance_follows": "Seuraajat, jotka heidän käyttäjänsä menettäisivät", @@ -114,7 +114,7 @@ "column.directory": "Selaa profiileja", "column.domain_blocks": "Estetyt verkkotunnukset", "column.favourites": "Suosikit", - "column.firehose": "Live-syötteet", + "column.firehose": "Livesyötteet", "column.follow_requests": "Seuraamispyynnöt", "column.home": "Koti", "column.lists": "Listat", @@ -135,7 +135,7 @@ "community.column_settings.remote_only": "Vain etätilit", "compose.language.change": "Vaihda kieli", "compose.language.search": "Hae kieliä...", - "compose.published.body": "Julkaisusi julkaistiin.", + "compose.published.body": "Julkaisu lähetetty.", "compose.published.open": "Avaa", "compose.saved.body": "Julkaisu tallennettu.", "compose_form.direct_message_warning_learn_more": "Lisätietoja", @@ -436,10 +436,10 @@ "notifications.clear": "Tyhjennä ilmoitukset", "notifications.clear_confirmation": "Haluatko varmasti poistaa kaikki ilmoitukset pysyvästi?", "notifications.column_settings.admin.report": "Uudet ilmoitukset:", - "notifications.column_settings.admin.sign_up": "Uudet kirjautumiset:", + "notifications.column_settings.admin.sign_up": "Uudet rekisteröitymiset:", "notifications.column_settings.alert": "Työpöytäilmoitukset", "notifications.column_settings.favourite": "Suosikit:", - "notifications.column_settings.filter_bar.advanced": "Näytä kaikki kategoriat", + "notifications.column_settings.filter_bar.advanced": "Näytä kaikki luokat", "notifications.column_settings.filter_bar.category": "Pikasuodatuspalkki", "notifications.column_settings.filter_bar.show_bar": "Näytä suodatinpalkki", "notifications.column_settings.follow": "Uudet seuraajat:", @@ -517,7 +517,7 @@ "privacy.private.short": "Vain seuraajat", "privacy.public.long": "Näkyy kaikille", "privacy.public.short": "Julkinen", - "privacy.unlisted.long": "Näkyy kaikille, mutta jää pois löytämisominaisuuksista", + "privacy.unlisted.long": "Näkyy kaikille mutta jää pois löytämisominaisuuksista", "privacy.unlisted.short": "Listaamaton", "privacy_policy.last_updated": "Viimeksi päivitetty {date}", "privacy_policy.title": "Tietosuojakäytäntö", @@ -589,13 +589,13 @@ "search.quick_action.go_to_hashtag": "Siirry aihetunnisteeseen {x}", "search.quick_action.open_url": "Avaa URL-osoite Mastodonissa", "search.quick_action.status_search": "Julkaisut haulla {x}", - "search.search_or_paste": "Hae tai kirjoita URL-osoite", + "search.search_or_paste": "Hae tai liitä URL-osoite", "search_popout.full_text_search_disabled_message": "Ei saatavilla palvelimella {domain}.", "search_popout.language_code": "ISO-kielikoodi", "search_popout.options": "Hakuvalinnat", "search_popout.quick_actions": "Pikatoiminnot", "search_popout.recent": "Viimeaikaiset haut", - "search_popout.specific_date": "tietty päivämäärä", + "search_popout.specific_date": "tarkka päiväys", "search_popout.user": "käyttäjä", "search_results.accounts": "Profiilit", "search_results.all": "Kaikki", diff --git a/config/locales/activerecord.sk.yml b/config/locales/activerecord.sk.yml index 33f53a88e..d13c416e5 100644 --- a/config/locales/activerecord.sk.yml +++ b/config/locales/activerecord.sk.yml @@ -53,3 +53,7 @@ sk: position: elevated: nemôže byť vyššia ako vaša súčasná rola own_role: nie je možné zmeniť s vašou aktuálnou rolou + webhook: + attributes: + events: + invalid_permissions: nemožno zahrnúť udalosti, ku ktorým nemáte práva diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml index acfd59b3e..91c9430b3 100644 --- a/config/locales/doorkeeper.sk.yml +++ b/config/locales/doorkeeper.sk.yml @@ -129,6 +129,7 @@ sk: crypto: Šifrovanie End-to-end favourites: Obľúbené filters: Filtre + follow: Sledovanie, stlmenie a blokovanie follows: Sledovania lists: Zoznamy media: Mediálne prílohy @@ -148,9 +149,19 @@ sk: scopes: admin:read: prezeraj všetky dáta na serveri admin:read:accounts: prezeraj chúlostivé informácie na všetkých účtoch + admin:read:canonical_email_blocks: čítať citlivé informácie všetkých kanonických e-mailových blokov + admin:read:domain_allows: čítať citlivé informácie zo všetkých povolených domén + admin:read:domain_blocks: čítať citlivé informácie zo všetkých blokov domén + admin:read:email_domain_blocks: čítať citlivé informácie zo všetkých blokov emailových domén + admin:read:ip_blocks: čítať citlivé informácie zo všetkých blokov IP admin:read:reports: čítaj chulostivé informácie o všetkých hláseniach a nahlásených účtoch admin:write: uprav všetky dáta na serveri admin:write:accounts: urob moderovacie úkony na účtoch + admin:write:canonical_email_blocks: vykonať akcie moderácie na kanonických emailových blokoch + admin:write:domain_allows: vykonať akcie moderácie na povolených doménach + admin:write:domain_blocks: vykonať akcie moderácie na doménových blokoch + admin:write:email_domain_blocks: vykonať akcie moderácie na blokoch emailových domén + admin:write:ip_blocks: vykonať akcie moderácie na blokoch IP admin:write:reports: urob moderovacie úkony voči hláseniam crypto: používať end-to-end šifrovanie follow: uprav vzťahy svojho účtu @@ -159,6 +170,7 @@ sk: read:accounts: prezri si informácie o účte read:blocks: prezri svoje bloky read:bookmarks: pozri svoje záložky + read:favourites: zobraziť vaše obľúbené read:filters: prezri svoje filtrovanie read:follows: prezri si svoje sledovania read:lists: prezri si svoje zoznamy diff --git a/config/locales/fi.yml b/config/locales/fi.yml index cdc5d1267..09d2a6877 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -33,7 +33,7 @@ fi: accounts: add_email_domain_block: Estä sähköpostiverkkotunnus approve: Hyväksy - approved_msg: Käyttäjän %{username} liittymishakemus hyväksyttiin + approved_msg: Käyttäjän %{username} rekisteröitymishakemus hyväksyttiin are_you_sure: Oletko varma? avatar: Profiilikuva by_domain: Verkkotunnus @@ -364,7 +364,7 @@ fi: other: "%{count} odottavaa käyttäjää" resolved_reports: ratkaistut raportit software: Ohjelmisto - sources: Rekisteröitymisen lähteet + sources: Rekisteröitymislähteet space: Tilankäyttö title: Hallintapaneeli top_languages: Aktiivisimmat kielet @@ -440,7 +440,7 @@ fi: title: Estä uusi sähköpostiverkkotunnus no_email_domain_block_selected: Sähköpostin verkkotunnuksia ei muutettu, koska yhtään ei ollut valittuna not_permitted: Ei sallittu - resolved_dns_records_hint_html: Verkkotunnuksen nimi määräytyy seuraaviin MX-verkkotunnuksiin, jotka ovat viime kädessä vastuussa sähköpostin vastaanottamisesta. MX-verkkotunnuksen estäminen estää kirjautumisen mistä tahansa sähköpostiosoitteesta, joka käyttää samaa MX-verkkotunnusta, vaikka näkyvä verkkotunnuksen nimi olisikin erilainen. Varo estämästä suuria sähköpostin palveluntarjoajia. + resolved_dns_records_hint_html: Verkkotunnuksen nimi määräytyy seuraaviin MX-verkkotunnuksiin, jotka ovat viime kädessä vastuussa sähköpostin vastaanottamisesta. MX-verkkotunnuksen estäminen estää rekisteröitymisen mistä tahansa sähköpostiosoitteesta, joka käyttää samaa MX-verkkotunnusta, vaikka näkyvä verkkotunnuksen nimi olisikin erilainen. Varo estämästä suuria sähköpostin palveluntarjoajia. resolved_through_html: Ratkaistu %{domain} kautta title: Estetyt sähköpostiverkkotunnukset export_domain_allows: @@ -1405,7 +1405,7 @@ fi: migrations: acct: Muuttanut tunnukselle cancel: Peruuta uudelleenohjaus - cancel_explanation: Uudelleenohjauksen peruuttaminen aktivoi uudelleen nykyisen tilisi, mutta ei palauta seuraajia, jotka on siirretty kyseiselle tilille. + cancel_explanation: Uudelleenohjauksen peruuttaminen aktivoi nykyisen tilisi uudelleen mutta ei palauta seuraajia, jotka on siirretty kyseiselle tilille. cancelled_msg: Uudelleenohjaus peruttu onnistuneesti. errors: already_moved: on sama tili, jonka olet jo siirtänyt diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index 6c8875327..403162b82 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -59,14 +59,14 @@ fi: setting_display_media_default: Piilota arkaluonteiseksi merkitty media setting_display_media_hide_all: Piilota media aina setting_display_media_show_all: Näytä media aina - setting_use_blurhash: Liukuvärit perustuvat piilotettujen kuvien väreihin, mutta sumentavat yksityiskohdat + setting_use_blurhash: Liukuvärit perustuvat piilotettujen kuvien väreihin mutta sumentavat yksityiskohdat setting_use_pending_items: Piilota aikajanan päivitykset napsautuksen taakse syötteen automaattisen vierityksen sijaan username: Voit käyttää kirjaimia, numeroita ja alaviivoja whole_word: Kun avainsana tai -fraasi on kokonaan aakkosnumeerinen, se on voimassa vain, jos se vastaa koko sanaa domain_allow: domain: Tämä verkkotunnus voi noutaa tietoja tältä palvelimelta ja sieltä saapuvat tiedot käsitellään ja tallennetaan email_domain_block: - domain: Tämä voi olla se verkkotunnus, joka näkyy sähköpostiosoitteessa tai MX tietueessa jota se käyttää. Ne tarkistetaan rekisteröitymisen yhteydessä. + domain: Tämä voi olla verkkotunnus, joka näkyy sähköpostiosoitteessa tai sen käyttämässä MX-tietueessa. Ne tarkistetaan rekisteröitymisen yhteydessä. with_dns_records: Annetun verkkotunnuksen DNS-tietueet yritetään ratkaista ja tulokset myös estetään featured_tag: name: 'Tässä muutamia hiljattain käyttämiäsi aihetunnisteita:' @@ -112,7 +112,7 @@ fi: ip: Kirjoita IPv4- tai IPv6-osoite. Voit estää kokonaisia alueita käyttämällä CIDR-syntaksia. Varo, että et lukitse itseäsi ulos! severities: no_access: Estä pääsy kaikkiin resursseihin - sign_up_block: Uudet kirjautumiset eivät ole mahdollisia + sign_up_block: Uudet rekisteröitymiset eivät ole mahdollisia sign_up_requires_approval: Uudet rekisteröitymiset edellyttävät hyväksyntääsi severity: Valitse, mitä tapahtuu tämän IP-osoitteen pyynnöille rule: From 7c3fea727583dd9bf482729cc87272e976a25b2d Mon Sep 17 00:00:00 2001 From: Emelia Smith Date: Wed, 18 Oct 2023 14:10:07 +0200 Subject: [PATCH 05/13] Feature: Allow token introspection without read scope (#27142) --- .../api/v1/apps/credentials_controller.rb | 6 +- .../rest/application_serializer.rb | 2 +- spec/requests/api/v1/apps/credentials_spec.rb | 77 ++++++++++++++++++- 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/apps/credentials_controller.rb b/app/controllers/api/v1/apps/credentials_controller.rb index 0475b2d4a..6256bed64 100644 --- a/app/controllers/api/v1/apps/credentials_controller.rb +++ b/app/controllers/api/v1/apps/credentials_controller.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true class Api::V1::Apps::CredentialsController < Api::BaseController - before_action -> { doorkeeper_authorize! :read } - def show - render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer, fields: %i(name website vapid_key) + return doorkeeper_render_error unless valid_doorkeeper_token? + + render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer, fields: %i(name website vapid_key client_id scopes) end end diff --git a/app/serializers/rest/application_serializer.rb b/app/serializers/rest/application_serializer.rb index ab68219ad..e4806a3c9 100644 --- a/app/serializers/rest/application_serializer.rb +++ b/app/serializers/rest/application_serializer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class REST::ApplicationSerializer < ActiveModel::Serializer - attributes :id, :name, :website, :redirect_uri, + attributes :id, :name, :website, :scopes, :redirect_uri, :client_id, :client_secret, :vapid_key def id diff --git a/spec/requests/api/v1/apps/credentials_spec.rb b/spec/requests/api/v1/apps/credentials_spec.rb index 1268b36f8..e1455fe79 100644 --- a/spec/requests/api/v1/apps/credentials_spec.rb +++ b/spec/requests/api/v1/apps/credentials_spec.rb @@ -9,7 +9,8 @@ describe 'Credentials' do end context 'with an oauth token' do - let(:token) { Fabricate(:accessible_access_token, scopes: 'read', application: Fabricate(:application)) } + let(:application) { Fabricate(:application, scopes: 'read') } + let(:token) { Fabricate(:accessible_access_token, application: application) } let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } it 'returns the app information correctly', :aggregate_failures do @@ -21,7 +22,35 @@ describe 'Credentials' do a_hash_including( name: token.application.name, website: token.application.website, - vapid_key: Rails.configuration.x.vapid_public_key + vapid_key: Rails.configuration.x.vapid_public_key, + scopes: token.application.scopes.map(&:to_s), + client_id: token.application.uid + ) + ) + end + end + + context 'with a non-read scoped oauth token' do + let(:application) { Fabricate(:application, scopes: 'admin:write') } + let(:token) { Fabricate(:accessible_access_token, application: application) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + it 'returns http success' do + subject + + expect(response).to have_http_status(200) + end + + it 'returns the app information correctly' do + subject + + expect(body_as_json).to match( + a_hash_including( + name: token.application.name, + website: token.application.website, + vapid_key: Rails.configuration.x.vapid_public_key, + scopes: token.application.scopes.map(&:to_s), + client_id: token.application.uid ) ) end @@ -36,5 +65,49 @@ describe 'Credentials' do expect(response).to have_http_status(401) end end + + context 'with a revoked oauth token' do + let(:application) { Fabricate(:application, scopes: 'read') } + let(:token) { Fabricate(:accessible_access_token, application: application, revoked_at: DateTime.now.utc) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + it 'returns http authorization error' do + subject + + expect(response).to have_http_status(401) + end + + it 'returns the error in the json response' do + subject + + expect(body_as_json).to match( + a_hash_including( + error: 'The access token was revoked' + ) + ) + end + end + + context 'with an invalid oauth token' do + let(:application) { Fabricate(:application, scopes: 'read') } + let(:token) { Fabricate(:accessible_access_token, application: application) } + let(:headers) { { 'Authorization' => "Bearer #{token.token}-invalid" } } + + it 'returns http authorization error' do + subject + + expect(response).to have_http_status(401) + end + + it 'returns the error in the json response' do + subject + + expect(body_as_json).to match( + a_hash_including( + error: 'The access token is invalid' + ) + ) + end + end end end From a1b27d8b6146e38f125a646fecfbf0a951d02f5f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 18 Oct 2023 08:26:22 -0400 Subject: [PATCH 06/13] Fix `Naming/VariableNumber` cop (#27447) --- .rubocop_todo.yml | 14 ------------ db/migrate/.rubocop.yml | 4 ++++ spec/models/account_spec.rb | 38 ++++++++++++++++---------------- spec/models/domain_block_spec.rb | 8 +++---- spec/models/user_spec.rb | 12 +++++----- 5 files changed, 33 insertions(+), 43 deletions(-) create mode 100644 db/migrate/.rubocop.yml diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index bee9e7155..fc5828d37 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -86,20 +86,6 @@ Metrics/CyclomaticComplexity: Metrics/PerceivedComplexity: Max: 27 -# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. -# SupportedStyles: snake_case, normalcase, non_integer -# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 -Naming/VariableNumber: - Exclude: - - 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb' - - 'db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb' - - 'db/migrate/20190820003045_update_statuses_index.rb' - - 'db/migrate/20190823221802_add_local_index_to_statuses.rb' - - 'db/migrate/20200119112504_add_public_index_to_statuses.rb' - - 'spec/models/account_spec.rb' - - 'spec/models/domain_block_spec.rb' - - 'spec/models/user_spec.rb' - Performance/MapMethodChain: Exclude: - 'app/models/feed.rb' diff --git a/db/migrate/.rubocop.yml b/db/migrate/.rubocop.yml new file mode 100644 index 000000000..4e23800dd --- /dev/null +++ b/db/migrate/.rubocop.yml @@ -0,0 +1,4 @@ +inherit_from: ../../.rubocop.yml + +Naming/VariableNumber: + CheckSymbols: false diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index fc7a43110..e8637e1b3 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -719,10 +719,10 @@ RSpec.describe Account do context 'when is local' do it 'is invalid if the username is not unique in case-insensitive comparison among local accounts' do - account_1 = Fabricate(:account, username: 'the_doctor') - account_2 = Fabricate.build(:account, username: 'the_Doctor') - account_2.valid? - expect(account_2).to model_have_error_on_field(:username) + _account = Fabricate(:account, username: 'the_doctor') + non_unique_account = Fabricate.build(:account, username: 'the_Doctor') + non_unique_account.valid? + expect(non_unique_account).to model_have_error_on_field(:username) end it 'is invalid if the username is reserved' do @@ -743,9 +743,9 @@ RSpec.describe Account do end it 'is valid if we are creating a possibly-conflicting instance actor account' do - account_1 = Fabricate(:account, username: 'examplecom') - account_2 = Fabricate.build(:account, id: -99, actor_type: 'Application', locked: true, username: 'example.com') - expect(account_2.valid?).to be true + _account = Fabricate(:account, username: 'examplecom') + instance_account = Fabricate.build(:account, id: -99, actor_type: 'Application', locked: true, username: 'example.com') + expect(instance_account.valid?).to be true end it 'is invalid if the username doesn\'t only contains letters, numbers and underscores' do @@ -877,17 +877,17 @@ RSpec.describe Account do describe 'remote' do it 'returns an array of accounts who have a domain' do - account_1 = Fabricate(:account, domain: nil) - account_2 = Fabricate(:account, domain: 'example.com') - expect(described_class.remote).to contain_exactly(account_2) + _account = Fabricate(:account, domain: nil) + account_with_domain = Fabricate(:account, domain: 'example.com') + expect(described_class.remote).to contain_exactly(account_with_domain) end end describe 'local' do it 'returns an array of accounts who do not have a domain' do - account_1 = Fabricate(:account, domain: nil) - account_2 = Fabricate(:account, domain: 'example.com') - expect(described_class.where('id > 0').local).to contain_exactly(account_1) + local_account = Fabricate(:account, domain: nil) + _account_with_domain = Fabricate(:account, domain: 'example.com') + expect(described_class.where('id > 0').local).to contain_exactly(local_account) end end @@ -911,17 +911,17 @@ RSpec.describe Account do describe 'silenced' do it 'returns an array of accounts who are silenced' do - account_1 = Fabricate(:account, silenced: true) - account_2 = Fabricate(:account, silenced: false) - expect(described_class.silenced).to contain_exactly(account_1) + silenced_account = Fabricate(:account, silenced: true) + _account = Fabricate(:account, silenced: false) + expect(described_class.silenced).to contain_exactly(silenced_account) end end describe 'suspended' do it 'returns an array of accounts who are suspended' do - account_1 = Fabricate(:account, suspended: true) - account_2 = Fabricate(:account, suspended: false) - expect(described_class.suspended).to contain_exactly(account_1) + suspended_account = Fabricate(:account, suspended: true) + _account = Fabricate(:account, suspended: false) + expect(described_class.suspended).to contain_exactly(suspended_account) end end diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index 67f53fa78..d595441fd 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -11,10 +11,10 @@ RSpec.describe DomainBlock do end it 'is invalid if the same normalized domain already exists' do - domain_block_1 = Fabricate(:domain_block, domain: 'にゃん') - domain_block_2 = Fabricate.build(:domain_block, domain: 'xn--r9j5b5b') - domain_block_2.valid? - expect(domain_block_2).to model_have_error_on_field(:domain) + _domain_block = Fabricate(:domain_block, domain: 'にゃん') + domain_block_with_normalized_value = Fabricate.build(:domain_block, domain: 'xn--r9j5b5b') + domain_block_with_normalized_value.valid? + expect(domain_block_with_normalized_value).to model_have_error_on_field(:domain) end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index bb61c02a6..7485abe62 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -55,17 +55,17 @@ RSpec.describe User do describe 'scopes' do describe 'recent' do it 'returns an array of recent users ordered by id' do - user_1 = Fabricate(:user) - user_2 = Fabricate(:user) - expect(described_class.recent).to eq [user_2, user_1] + first_user = Fabricate(:user) + second_user = Fabricate(:user) + expect(described_class.recent).to eq [second_user, first_user] end end describe 'confirmed' do it 'returns an array of users who are confirmed' do - user_1 = Fabricate(:user, confirmed_at: nil) - user_2 = Fabricate(:user, confirmed_at: Time.zone.now) - expect(described_class.confirmed).to contain_exactly(user_2) + unconfirmed_user = Fabricate(:user, confirmed_at: nil) + confirmed_user = Fabricate(:user, confirmed_at: Time.zone.now) + expect(described_class.confirmed).to contain_exactly(confirmed_user) end end From 510845b6b98cd782ea60a0015f8695b12fb8ad74 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 18 Oct 2023 15:20:24 +0200 Subject: [PATCH 07/13] Only enable github-rspec for pull_request events (#27456) --- .github/workflows/test-ruby.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index f8280a22f..f2d2d02fc 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -113,7 +113,7 @@ jobs: CAS_ENABLED: true BUNDLE_WITH: 'pam_authentication test' CI_JOBS: ${{ matrix.ci_job }}/4 - GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' }} + GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' && github.event.pull_request && 'true' }} strategy: fail-fast: false From 10df97c54299bfdfd568c0681d180cc9c7058006 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Thu, 19 Oct 2023 13:22:44 +0200 Subject: [PATCH 08/13] The `class` props should be `className` (#27462) --- .../mastodon/features/ui/components/link_footer.jsx | 2 +- .../mastodon/features/ui/components/navigation_panel.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/link_footer.jsx b/app/javascript/mastodon/features/ui/components/link_footer.jsx index 9585df2ec..6b1555243 100644 --- a/app/javascript/mastodon/features/ui/components/link_footer.jsx +++ b/app/javascript/mastodon/features/ui/components/link_footer.jsx @@ -100,7 +100,7 @@ class LinkFooter extends PureComponent { {DividingCircle} {DividingCircle} - v{version} + v{version}

); diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx index 8006ca89a..22eee79c0 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx @@ -59,10 +59,10 @@ class NavigationPanel extends Component { {transientSingleColumn ? ( -
+
{intl.formatMessage(messages.openedInClassicInterface)} {" "} - + {intl.formatMessage(messages.advancedInterface)}
From f76e5111f08d891383169854bf146f60c1daa952 Mon Sep 17 00:00:00 2001 From: Brian Campbell Date: Thu, 19 Oct 2023 08:25:57 -0400 Subject: [PATCH 09/13] Consider shown and pending status in explore prompt calculation (#27466) Co-authored-by: Brian Campbell --- app/javascript/mastodon/features/home_timeline/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/home_timeline/index.jsx b/app/javascript/mastodon/features/home_timeline/index.jsx index 93f937628..f19eaf935 100644 --- a/app/javascript/mastodon/features/home_timeline/index.jsx +++ b/app/javascript/mastodon/features/home_timeline/index.jsx @@ -37,7 +37,7 @@ const getHomeFeedSpeed = createSelector([ state => state.getIn(['timelines', 'home', 'pendingItems'], ImmutableList()), state => state.get('statuses'), ], (statusIds, pendingStatusIds, statusMap) => { - const recentStatusIds = pendingStatusIds.size > 0 ? pendingStatusIds : statusIds; + const recentStatusIds = pendingStatusIds.concat(statusIds); const statuses = recentStatusIds.filter(id => id !== null).map(id => statusMap.get(id)).filter(status => status?.get('account') !== me).take(20); if (statuses.isEmpty()) { From 1ffd5a98a994c1798e0e2a16d93c60bb662ab36e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 14:31:25 +0200 Subject: [PATCH 10/13] New Crowdin Translations (automated) (#27465) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ja.json | 2 +- app/javascript/mastodon/locales/zh-TW.json | 2 +- config/locales/simple_form.zh-TW.yml | 4 ++-- config/locales/zh-TW.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index c5817c199..a01354463 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -137,7 +137,7 @@ "compose.language.search": "言語を検索...", "compose.published.body": "投稿されました!", "compose.published.open": "開く", - "compose.saved.body": "投稿が保存されました", + "compose.saved.body": "変更を保存しました。", "compose_form.direct_message_warning_learn_more": "もっと詳しく", "compose_form.encryption_warning": "Mastodonの投稿はエンドツーエンド暗号化に対応していません。安全に送受信されるべき情報をMastodonで共有しないでください。", "compose_form.hashtag_warning": "この投稿は公開設定ではないのでハッシュタグの一覧に表示されません。公開投稿だけがハッシュタグで検索できます。", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index b1cd0ca75..f8dcb6a89 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -114,7 +114,7 @@ "column.directory": "瀏覽個人檔案", "column.domain_blocks": "已封鎖網域", "column.favourites": "最愛", - "column.firehose": "即時內容", + "column.firehose": "即時河道", "column.follow_requests": "跟隨請求", "column.home": "首頁", "column.lists": "列表", diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml index c48c659fa..4580e772f 100644 --- a/config/locales/simple_form.zh-TW.yml +++ b/config/locales/simple_form.zh-TW.yml @@ -30,7 +30,7 @@ zh-TW: suspend: 禁止所有對該帳號任何互動,並且刪除其內容。三十天內可以撤銷此動作。關閉所有對此帳號之檢舉報告。 warning_preset_id: 選用。您仍可在預設的結尾新增自訂文字 announcement: - all_day: 核取後,只會顯示出時間範圍中的日期部分 + all_day: 當選取時,僅顯示出時間範圍中的日期部分 ends_at: 可選的,公告會於該時間點自動取消發布 scheduled_at: 空白則立即發布公告 starts_at: 可選的,讓公告在特定時間範圍內顯示 @@ -60,7 +60,7 @@ zh-TW: setting_display_media_hide_all: 總是隱藏所有媒體 setting_display_media_show_all: 總是顯示標為敏感內容的媒體 setting_use_blurhash: 彩色漸層圖樣是基於隱藏媒體內容顏色產生,所有細節將變得模糊 - setting_use_pending_items: 關閉自動捲動更新,時間軸只會於點擊後更新 + setting_use_pending_items: 關閉自動捲動更新,時間軸僅於點擊後更新 username: 您可以使用字幕、數字與底線 whole_word: 如果關鍵字或詞組僅有字母與數字,則其將只在符合整個單字的時候才會套用 domain_allow: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index e139742ff..fd9348150 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -578,7 +578,7 @@ zh-TW: mark_as_sensitive_description_html: 被檢舉的嘟文中的媒體將會被標記為敏感內容,並將會記錄一次警告,以協助您升級同一帳號未來的違規行為。 other_description_html: 檢視更多控制帳號行為以及自訂檢舉帳號通知之選項。 resolve_description_html: 被檢舉的帳號將不被採取任何行動,不會加以刪除線標記,並且此份報告將被關閉。 - silence_description_html: 此帳號僅會對已跟隨帳號之使用者或手動查詢可見,將大幅度限制觸及範圍。此設定可隨時被還原。關閉所有對此帳號之檢舉報告。 + silence_description_html: 此帳號僅對已跟隨帳號之使用者或手動查詢可見,將大幅度限制觸及範圍。此設定可隨時被還原。關閉所有對此帳號之檢舉報告。 suspend_description_html: 此帳號及其所有內容將不可被存取並且最終被移除,並且無法與之進行互動。三十天內可以撤銷此動作。關閉所有對此帳號之檢舉報告。 actions_description_html: 決定應對此報告採取何種行動。若您對檢舉之帳號採取懲罰措施,則將對他們發送 e-mail 通知,如非選擇了 垃圾郵件 類別。 actions_description_remote_html: 決定將對此檢舉報告採取何種動作。這將僅作用於您的伺服器與此遠端帳號及其內容之通訊行為。 From 7bc8f031628db11f5505c47e3e80d6ed074fa682 Mon Sep 17 00:00:00 2001 From: Daniel M Brasil Date: Thu, 19 Oct 2023 11:11:15 -0300 Subject: [PATCH 11/13] Add test coverage for `Mastodon::CLI::Accounts#migrate` (#25284) --- spec/lib/mastodon/cli/accounts_spec.rb | 177 +++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb index 6d6d81c41..2c8c99471 100644 --- a/spec/lib/mastodon/cli/accounts_spec.rb +++ b/spec/lib/mastodon/cli/accounts_spec.rb @@ -1429,4 +1429,181 @@ describe Mastodon::CLI::Accounts do end end end + + describe '#migrate' do + let!(:source_account) { Fabricate(:account) } + let!(:target_account) { Fabricate(:account, domain: 'example.com') } + let(:arguments) { [source_account.username] } + let(:resolve_account_service) { instance_double(ResolveAccountService, call: nil) } + let(:move_service) { instance_double(MoveService, call: nil) } + + before do + allow(ResolveAccountService).to receive(:new).and_return(resolve_account_service) + allow(MoveService).to receive(:new).and_return(move_service) + end + + shared_examples 'a successful migration' do + it 'calls the MoveService for the last migration' do + cli.invoke(:migrate, arguments, options) + + last_migration = source_account.migrations.last + + expect(move_service).to have_received(:call).with(last_migration).once + end + + it 'displays a successful message' do + expect { cli.invoke(:migrate, arguments, options) }.to output( + a_string_including("OK, migrated #{source_account.acct} to #{target_account.acct}") + ).to_stdout + end + end + + context 'when both --replay and --target options are given' do + let(:options) { { replay: true, target: "#{target_account.username}@example.com" } } + + it 'exits with an error message indicating that using both options is not possible' do + expect { cli.invoke(:migrate, arguments, options) }.to output( + a_string_including('Use --replay or --target, not both') + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'when no option is given' do + it 'exits with an error message indicating that at least one option must be used' do + expect { cli.invoke(:migrate, arguments, {}) }.to output( + a_string_including('Use either --replay or --target') + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'when the given username is not found' do + let(:arguments) { ['non_existent_username'] } + + it 'exits with an error message indicating that there is no such account' do + expect { cli.invoke(:migrate, arguments, replay: true) }.to output( + a_string_including("No such account: #{arguments.first}") + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'with --replay option' do + let(:options) { { replay: true } } + + context 'when the specified account has no previous migrations' do + it 'exits with an error message indicating that the given account has no previous migrations' do + expect { cli.invoke(:migrate, arguments, options) }.to output( + a_string_including('The specified account has not performed any migration') + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'when the specified account has a previous migration' do + before do + allow(resolve_account_service).to receive(:call).with(source_account.acct, any_args).and_return(source_account) + allow(resolve_account_service).to receive(:call).with(target_account.acct, any_args).and_return(target_account) + target_account.aliases.create!(acct: source_account.acct) + source_account.migrations.create!(acct: target_account.acct) + source_account.update!(moved_to_account: target_account) + end + + it_behaves_like 'a successful migration' + + context 'when the specified account is redirecting to a different target account' do + before do + source_account.update!(moved_to_account: nil) + end + + it 'exits with an error message' do + expect { cli.invoke(:migrate, arguments, options) }.to output( + a_string_including('The specified account is not redirecting to its last migration target. Use --force if you want to replay the migration anyway') + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'with --force option' do + let(:options) { { replay: true, force: true } } + + it_behaves_like 'a successful migration' + end + end + end + + context 'with --target option' do + let(:options) { { target: target_account.acct } } + + before do + allow(resolve_account_service).to receive(:call).with(source_account.acct, any_args).and_return(source_account) + allow(resolve_account_service).to receive(:call).with(target_account.acct, any_args).and_return(target_account) + end + + context 'when the specified target account is not found' do + before do + allow(resolve_account_service).to receive(:call).with(target_account.acct).and_return(nil) + end + + it 'exits with an error message indicating that there is no such account' do + expect { cli.invoke(:migrate, arguments, options) }.to output( + a_string_including("The specified target account could not be found: #{options[:target]}") + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'when the specified target account exists' do + before do + target_account.aliases.create!(acct: source_account.acct) + end + + it 'creates a migration for the specified account with the target account' do + cli.invoke(:migrate, arguments, options) + + last_migration = source_account.migrations.last + + expect(last_migration.acct).to eq(target_account.acct) + end + + it_behaves_like 'a successful migration' + end + + context 'when the migration record is invalid' do + it 'exits with an error indicating that the validation failed' do + expect { cli.invoke(:migrate, arguments, options) }.to output( + a_string_including('Error: Validation failed') + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'when the specified account is redirecting to a different target account' do + before do + allow(Account).to receive(:find_local).with(source_account.username).and_return(source_account) + allow(source_account).to receive(:moved_to_account_id).and_return(-1) + end + + it 'exits with an error message' do + expect { cli.invoke(:migrate, arguments, options) }.to output( + a_string_including('The specified account is redirecting to a different target account. Use --force if you want to change the migration target') + ).to_stdout + .and raise_error(SystemExit) + end + end + + context 'with --target and --force options' do + let(:options) { { target: target_account.acct, force: true } } + + before do + target_account.aliases.create!(acct: source_account.acct) + allow(Account).to receive(:find_local).with(source_account.username).and_return(source_account) + allow(source_account).to receive(:moved_to_account_id).and_return(-1) + end + + it_behaves_like 'a successful migration' + end + end + end end From bcd0171e5eb0a4c4f42adf247f897bf49f12e8f1 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 19 Oct 2023 10:55:06 -0400 Subject: [PATCH 12/13] Fix `Lint/UselessAssignment` cop (#27472) --- .rubocop_todo.yml | 21 ------------------- .../process_status_update_service.rb | 2 -- config/initializers/3_omniauth.rb | 3 --- ...dd_silenced_at_suspended_at_to_accounts.rb | 1 - ...emove_suspended_silenced_account_fields.rb | 1 - .../account_controller_concern_spec.rb | 2 +- spec/helpers/jsonld_helper_spec.rb | 4 ++-- spec/models/account_spec.rb | 8 +++---- spec/models/status_spec.rb | 2 +- spec/models/user_spec.rb | 2 +- spec/models/webauthn_credentials_spec.rb | 4 ++-- spec/services/account_search_service_spec.rb | 8 +++---- spec/services/post_status_service_spec.rb | 4 ++-- spec/services/precompute_feed_service_spec.rb | 2 +- spec/services/resolve_url_service_spec.rb | 4 ++-- spec/views/statuses/show.html.haml_spec.rb | 4 ++-- 16 files changed, 22 insertions(+), 50 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index fc5828d37..1a21fd156 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -48,27 +48,6 @@ Lint/UnusedBlockArgument: - 'config/initializers/paperclip.rb' - 'config/initializers/simple_form.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -Lint/UselessAssignment: - Exclude: - - 'app/services/activitypub/process_status_update_service.rb' - - 'config/initializers/3_omniauth.rb' - - 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb' - - 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb' - - 'spec/controllers/api/v1/favourites_controller_spec.rb' - - 'spec/controllers/concerns/account_controller_concern_spec.rb' - - 'spec/helpers/jsonld_helper_spec.rb' - - 'spec/models/account_spec.rb' - - 'spec/models/domain_block_spec.rb' - - 'spec/models/status_spec.rb' - - 'spec/models/user_spec.rb' - - 'spec/models/webauthn_credentials_spec.rb' - - 'spec/services/account_search_service_spec.rb' - - 'spec/services/post_status_service_spec.rb' - - 'spec/services/precompute_feed_service_spec.rb' - - 'spec/services/resolve_url_service_spec.rb' - - 'spec/views/statuses/show.html.haml_spec.rb' - # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 144 diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index ec983510b..4ff92da01 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -97,8 +97,6 @@ class ActivityPub::ProcessStatusUpdateService < BaseService end end - added_media_attachments = @next_media_attachments - previous_media_attachments - @status.ordered_media_attachment_ids = @next_media_attachments.map(&:id) @media_attachments_changed = true if @status.ordered_media_attachment_ids != previous_media_attachments_ids diff --git a/config/initializers/3_omniauth.rb b/config/initializers/3_omniauth.rb index 566e7362a..d316c3b73 100644 --- a/config/initializers/3_omniauth.rb +++ b/config/initializers/3_omniauth.rb @@ -9,9 +9,6 @@ Rails.application.config.middleware.use OmniAuth::Builder do end Devise.setup do |config| - # Devise omniauth strategies - options = {} - # CAS strategy if ENV['CAS_ENABLED'] == 'true' cas_options = {} diff --git a/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb b/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb index 7301e960d..c9f084955 100644 --- a/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb +++ b/db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb @@ -19,7 +19,6 @@ class AddSilencedAtSuspendedAtToAccounts < ActiveRecord::Migration[5.2] # Record suspend date of blocks and silences for users whose limitations match # a domain block DomainBlock.where(severity: [:silence, :suspend]).find_each do |block| - scope = block.accounts if block.suspend? block.accounts.where(suspended: true).in_batches.update_all(suspended_at: block.created_at) else diff --git a/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb b/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb index 615f35cd0..7788431cd 100644 --- a/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb +++ b/db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb @@ -18,7 +18,6 @@ class RemoveSuspendedSilencedAccountFields < ActiveRecord::Migration[5.2] # Record suspend date of blocks and silences for users whose limitations match # a domain block DomainBlock.where(severity: [:silence, :suspend]).find_each do |block| - scope = block.accounts if block.suspend? block.accounts.where(suspended: true).in_batches.update_all(suspended_at: block.created_at) else diff --git a/spec/controllers/concerns/account_controller_concern_spec.rb b/spec/controllers/concerns/account_controller_concern_spec.rb index d080475c3..56ffcfb04 100644 --- a/spec/controllers/concerns/account_controller_concern_spec.rb +++ b/spec/controllers/concerns/account_controller_concern_spec.rb @@ -62,7 +62,7 @@ describe AccountControllerConcern do end it 'sets link headers' do - account = Fabricate(:account, username: 'username') + Fabricate(:account, username: 'username') get 'success', params: { account_username: 'username' } expect(response.headers['Link'].to_s).to eq '; rel="lrdd"; type="application/jrd+json", ; rel="alternate"; type="application/activity+json"' end diff --git a/spec/helpers/jsonld_helper_spec.rb b/spec/helpers/jsonld_helper_spec.rb index 3575bba85..5124bcf85 100644 --- a/spec/helpers/jsonld_helper_spec.rb +++ b/spec/helpers/jsonld_helper_spec.rb @@ -158,14 +158,14 @@ describe JsonLdHelper do it 'deems a safe compacting as such' do json['object'].delete('convo') compacted = compact(json) - deemed_compatible = patch_for_forwarding!(json, compacted) + patch_for_forwarding!(json, compacted) expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] expect(safe_for_forwarding?(json, compacted)).to be true end it 'deems an unsafe compacting as such' do compacted = compact(json) - deemed_compatible = patch_for_forwarding!(json, compacted) + patch_for_forwarding!(json, compacted) expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] expect(safe_for_forwarding?(json, compacted)).to be false end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index e8637e1b3..b5d942412 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -356,7 +356,7 @@ RSpec.describe Account do end it 'does not return suspended users' do - match = Fabricate( + Fabricate( :account, display_name: 'Display Name', username: 'username', @@ -483,7 +483,7 @@ RSpec.describe Account do end it 'does not return non-followed accounts' do - match = Fabricate( + Fabricate( :account, display_name: 'A & l & i & c & e', username: 'username', @@ -495,7 +495,7 @@ RSpec.describe Account do end it 'does not return suspended users' do - match = Fabricate( + Fabricate( :account, display_name: 'Display Name', username: 'username', @@ -535,7 +535,7 @@ RSpec.describe Account do end it 'does not return suspended users' do - match = Fabricate( + Fabricate( :account, display_name: 'Display Name', username: 'username', diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb index 8c37b1acc..938d0546d 100644 --- a/spec/models/status_spec.rb +++ b/spec/models/status_spec.rb @@ -166,7 +166,7 @@ RSpec.describe Status do describe '#replies_count' do it 'is the number of replies' do - reply = Fabricate(:status, account: bob, thread: subject) + Fabricate(:status, account: bob, thread: subject) expect(subject.replies_count).to eq 1 end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7485abe62..92ce87e36 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -63,7 +63,7 @@ RSpec.describe User do describe 'confirmed' do it 'returns an array of users who are confirmed' do - unconfirmed_user = Fabricate(:user, confirmed_at: nil) + Fabricate(:user, confirmed_at: nil) confirmed_user = Fabricate(:user, confirmed_at: Time.zone.now) expect(described_class.confirmed).to contain_exactly(confirmed_user) end diff --git a/spec/models/webauthn_credentials_spec.rb b/spec/models/webauthn_credentials_spec.rb index 4579ebb82..9631245e1 100644 --- a/spec/models/webauthn_credentials_spec.rb +++ b/spec/models/webauthn_credentials_spec.rb @@ -37,7 +37,7 @@ RSpec.describe WebauthnCredential do end it 'is invalid if already exist a webauthn credential with the same external id' do - existing_webauthn_credential = Fabricate(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw') + Fabricate(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw') new_webauthn_credential = Fabricate.build(:webauthn_credential, external_id: '_Typ0ygudDnk9YUVWLQayw') new_webauthn_credential.valid? @@ -47,7 +47,7 @@ RSpec.describe WebauthnCredential do it 'is invalid if user already registered a webauthn credential with the same nickname' do user = Fabricate(:user) - existing_webauthn_credential = Fabricate(:webauthn_credential, user_id: user.id, nickname: 'USB Key') + Fabricate(:webauthn_credential, user_id: user.id, nickname: 'USB Key') new_webauthn_credential = Fabricate.build(:webauthn_credential, user_id: user.id, nickname: 'USB Key') new_webauthn_credential.valid? diff --git a/spec/services/account_search_service_spec.rb b/spec/services/account_search_service_spec.rb index 1cd036f48..4f89cd220 100644 --- a/spec/services/account_search_service_spec.rb +++ b/spec/services/account_search_service_spec.rb @@ -56,7 +56,7 @@ describe AccountSearchService, type: :service do service = instance_double(ResolveAccountService, call: nil) allow(ResolveAccountService).to receive(:new).and_return(service) - results = subject.call('newuser@remote.com', nil, limit: 10, resolve: true) + subject.call('newuser@remote.com', nil, limit: 10, resolve: true) expect(service).to have_received(:call).with('newuser@remote.com') end @@ -64,14 +64,14 @@ describe AccountSearchService, type: :service do service = instance_double(ResolveAccountService, call: nil) allow(ResolveAccountService).to receive(:new).and_return(service) - results = subject.call('newuser@remote.com', nil, limit: 10, resolve: false) + subject.call('newuser@remote.com', nil, limit: 10, resolve: false) expect(service).to_not have_received(:call) end end it 'returns the fuzzy match first, and does not return suspended exacts' do partial = Fabricate(:account, username: 'exactness') - exact = Fabricate(:account, username: 'exact', suspended: true) + Fabricate(:account, username: 'exact', suspended: true) results = subject.call('exact', nil, limit: 10) expect(results.size).to eq 1 @@ -79,7 +79,7 @@ describe AccountSearchService, type: :service do end it 'does not return suspended remote accounts' do - remote = Fabricate(:account, username: 'a', domain: 'remote', display_name: 'e', suspended: true) + Fabricate(:account, username: 'a', domain: 'remote', display_name: 'e', suspended: true) results = subject.call('a@example.com', nil, limit: 2) expect(results.size).to eq 0 diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb index 7d7679c88..1e5c420a6 100644 --- a/spec/services/post_status_service_spec.rb +++ b/spec/services/post_status_service_spec.rb @@ -155,7 +155,7 @@ RSpec.describe PostStatusService, type: :service do it 'processes duplicate mentions correctly' do account = Fabricate(:account) - mentioned_account = Fabricate(:account, username: 'alice') + Fabricate(:account, username: 'alice') expect do subject.call(account, text: '@alice @alice @alice hey @alice') @@ -212,7 +212,7 @@ RSpec.describe PostStatusService, type: :service do account = Fabricate(:account) media = Fabricate(:media_attachment, account: Fabricate(:account)) - status = subject.call( + subject.call( account, text: 'test status update', media_ids: [media.id] diff --git a/spec/services/precompute_feed_service_spec.rb b/spec/services/precompute_feed_service_spec.rb index 54e0d94ee..663babae8 100644 --- a/spec/services/precompute_feed_service_spec.rb +++ b/spec/services/precompute_feed_service_spec.rb @@ -27,7 +27,7 @@ RSpec.describe PrecomputeFeedService, type: :service do muted_account = Fabricate(:account) Fabricate(:mute, account: account, target_account: muted_account) reblog = Fabricate(:status, account: muted_account) - status = Fabricate(:status, account: account, reblog: reblog) + Fabricate(:status, account: account, reblog: reblog) subject.call(account) diff --git a/spec/services/resolve_url_service_spec.rb b/spec/services/resolve_url_service_spec.rb index 7991aa6ef..bcfb9dbfb 100644 --- a/spec/services/resolve_url_service_spec.rb +++ b/spec/services/resolve_url_service_spec.rb @@ -7,8 +7,8 @@ describe ResolveURLService, type: :service do describe '#call' do it 'returns nil when there is no resource url' do - url = 'http://example.com/missing-resource' - known_account = Fabricate(:account, uri: url, domain: 'example.com') + url = 'http://example.com/missing-resource' + Fabricate(:account, uri: url, domain: 'example.com') service = instance_double(FetchResourceService) allow(FetchResourceService).to receive(:new).and_return service diff --git a/spec/views/statuses/show.html.haml_spec.rb b/spec/views/statuses/show.html.haml_spec.rb index 354f9d3e6..a9d3edf7a 100644 --- a/spec/views/statuses/show.html.haml_spec.rb +++ b/spec/views/statuses/show.html.haml_spec.rb @@ -13,7 +13,7 @@ describe 'statuses/show.html.haml', without_verify_partial_doubles: true do it 'has valid opengraph tags' do alice = Fabricate(:account, username: 'alice', display_name: 'Alice') status = Fabricate(:status, account: alice, text: 'Hello World') - media = Fabricate(:media_attachment, account: alice, status: status, type: :video) + Fabricate(:media_attachment, account: alice, status: status, type: :video) assign(:status, status) assign(:account, alice) @@ -32,7 +32,7 @@ describe 'statuses/show.html.haml', without_verify_partial_doubles: true do it 'has twitter player tag' do alice = Fabricate(:account, username: 'alice', display_name: 'Alice') status = Fabricate(:status, account: alice, text: 'Hello World') - media = Fabricate(:media_attachment, account: alice, status: status, type: :video) + Fabricate(:media_attachment, account: alice, status: status, type: :video) assign(:status, status) assign(:account, alice) From 9f218c9924b883207a3463a29314c92032cf06df Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 19 Oct 2023 11:25:54 -0400 Subject: [PATCH 13/13] Refactor appeal partial to avoid brakeman XSS warning (#25880) --- app/helpers/admin/disputes_helper.rb | 19 +++++++++++ .../admin/disputes/appeals/_appeal.html.haml | 2 +- config/brakeman.ignore | 33 ------------------- .../admin/disputes/appeals_controller_spec.rb | 8 +++-- spec/helpers/admin/disputes_helper_spec.rb | 21 ++++++++++++ 5 files changed, 47 insertions(+), 36 deletions(-) create mode 100644 app/helpers/admin/disputes_helper.rb create mode 100644 spec/helpers/admin/disputes_helper_spec.rb diff --git a/app/helpers/admin/disputes_helper.rb b/app/helpers/admin/disputes_helper.rb new file mode 100644 index 000000000..366a470ed --- /dev/null +++ b/app/helpers/admin/disputes_helper.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Admin + module DisputesHelper + def strike_action_label(appeal) + t(key_for_action(appeal), + scope: 'admin.strikes.actions', + name: content_tag(:span, appeal.strike.account.username, class: 'username'), + target: content_tag(:span, appeal.account.username, class: 'target')) + .html_safe + end + + private + + def key_for_action(appeal) + AccountWarning.actions.slice(appeal.strike.action).keys.first + end + end +end diff --git a/app/views/admin/disputes/appeals/_appeal.html.haml b/app/views/admin/disputes/appeals/_appeal.html.haml index 3f6efb856..d5611211e 100644 --- a/app/views/admin/disputes/appeals/_appeal.html.haml +++ b/app/views/admin/disputes/appeals/_appeal.html.haml @@ -4,7 +4,7 @@ = image_tag appeal.account.avatar.url(:original), alt: '', width: 40, height: 40, class: 'avatar' .log-entry__content .log-entry__title - = t(appeal.strike.action, scope: 'admin.strikes.actions', name: content_tag(:span, appeal.strike.account.username, class: 'username'), target: content_tag(:span, appeal.account.username, class: 'target')).html_safe + = strike_action_label(appeal) .log-entry__timestamp %time.formatted{ datetime: appeal.strike.created_at.iso8601 } = l(appeal.strike.created_at) diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 9f85ccb6a..d5c0b9443 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -1,38 +1,5 @@ { "ignored_warnings": [ - { - "warning_type": "Cross-Site Scripting", - "warning_code": 2, - "fingerprint": "71cf98c8235b5cfa9946b5db8fdc1a2f3a862566abb34e4542be6f3acae78233", - "check_name": "CrossSiteScripting", - "message": "Unescaped model attribute", - "file": "app/views/admin/disputes/appeals/_appeal.html.haml", - "line": 7, - "link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting", - "code": "t((Unresolved Model).new.strike.action, :scope => \"admin.strikes.actions\", :name => content_tag(:span, (Unresolved Model).new.strike.account.username, :class => \"username\"), :target => content_tag(:span, (Unresolved Model).new.account.username, :class => \"target\"))", - "render_path": [ - { - "type": "template", - "name": "admin/disputes/appeals/index", - "line": 20, - "file": "app/views/admin/disputes/appeals/index.html.haml", - "rendered": { - "name": "admin/disputes/appeals/_appeal", - "file": "app/views/admin/disputes/appeals/_appeal.html.haml" - } - } - ], - "location": { - "type": "template", - "template": "admin/disputes/appeals/_appeal" - }, - "user_input": "(Unresolved Model).new.strike", - "confidence": "Weak", - "cwe_id": [ - 79 - ], - "note": "" - }, { "warning_type": "Cross-Site Scripting", "warning_code": 4, diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb index 4afe07492..3f4175a28 100644 --- a/spec/controllers/admin/disputes/appeals_controller_spec.rb +++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb @@ -18,10 +18,14 @@ RSpec.describe Admin::Disputes::AppealsController do describe 'GET #index' do let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } - it 'lists appeals' do + before { appeal } + + it 'returns a page that lists details of appeals' do get :index - expect(response).to have_http_status(200) + expect(response).to have_http_status(:success) + expect(response.body).to include("#{strike.account.username}") + expect(response.body).to include("#{appeal.account.username}") end end diff --git a/spec/helpers/admin/disputes_helper_spec.rb b/spec/helpers/admin/disputes_helper_spec.rb new file mode 100644 index 000000000..5f9a85df8 --- /dev/null +++ b/spec/helpers/admin/disputes_helper_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Admin::DisputesHelper do + describe 'strike_action_label' do + it 'returns html describing the appeal' do + adam = Account.new(username: 'Adam') + becky = Account.new(username: 'Becky') + strike = AccountWarning.new(account: adam, action: :suspend) + appeal = Appeal.new(strike: strike, account: becky) + + expected = <<~OUTPUT.strip + Adam suspended Becky's account + OUTPUT + result = helper.strike_action_label(appeal) + + expect(result).to eq(expected) + end + end +end