From 0cf91213c93e87ce775453ae20a3d9a7f9b4e8d0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 10 Jun 2024 02:32:20 -0400 Subject: [PATCH 01/90] Opt in to remaining Rails 7.1 defaults (#30332) Co-authored-by: Claire --- config/application.rb | 5 +- .../initializers/active_record_encryption.rb | 5 + .../new_framework_defaults_7_1.rb | 214 ------------------ 3 files changed, 8 insertions(+), 216 deletions(-) delete mode 100644 config/initializers/new_framework_defaults_7_1.rb diff --git a/config/application.rb b/config/application.rb index 069eb3774063cf..b3a9b99ff5b266 100644 --- a/config/application.rb +++ b/config/application.rb @@ -60,9 +60,10 @@ module Mastodon class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.0 + config.load_defaults 7.1 - config.active_record.marshalling_format_version = 7.1 + # Explicitly set the cache format version to align with Rails version + config.active_support.cache_format_version = 7.1 # Please, add to the `ignore` list any other `lib` subdirectories that do # not contain `.rb` files, or that should not be reloaded or eager loaded. diff --git a/config/initializers/active_record_encryption.rb b/config/initializers/active_record_encryption.rb index 777bafc2730d05..900f3c68f0d527 100644 --- a/config/initializers/active_record_encryption.rb +++ b/config/initializers/active_record_encryption.rb @@ -32,4 +32,9 @@ config.active_record.encryption.deterministic_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY') config.active_record.encryption.key_derivation_salt = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT') config.active_record.encryption.primary_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY') + config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true + + # TODO: https://github.com/rails/rails/issues/50604#issuecomment-1880990392 + # Remove after updating to Rails 7.1.4 + ActiveRecord::Encryption.configure(**config.active_record.encryption) end diff --git a/config/initializers/new_framework_defaults_7_1.rb b/config/initializers/new_framework_defaults_7_1.rb deleted file mode 100644 index bcc300c89f6f9c..00000000000000 --- a/config/initializers/new_framework_defaults_7_1.rb +++ /dev/null @@ -1,214 +0,0 @@ -# frozen_string_literal: true - -# Be sure to restart your server when you modify this file. -# -# This file eases your Rails 7.1 framework defaults upgrade. -# -# Uncomment each configuration one by one to switch to the new default. -# Once your application is ready to run with all new defaults, you can remove -# this file and set the `config.load_defaults` to `7.1`. -# -# Read the Guide for Upgrading Ruby on Rails for more info on each option. -# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html - -# No longer add autoloaded paths into `$LOAD_PATH`. This means that you won't be able -# to manually require files that are managed by the autoloader, which you shouldn't do anyway. -# This will reduce the size of the load path, making `require` faster if you don't use bootsnap, or reduce the size -# of the bootsnap cache if you use it. -Rails.application.config.add_autoload_paths_to_load_path = false - -# Remove the default X-Download-Options headers since it is used only by Internet Explorer. -# If you need to support Internet Explorer, add back `"X-Download-Options" => "noopen"`. -# Rails.application.config.action_dispatch.default_headers = { -# "X-Frame-Options" => "SAMEORIGIN", -# "X-XSS-Protection" => "0", -# "X-Content-Type-Options" => "nosniff", -# "X-Permitted-Cross-Domain-Policies" => "none", -# "Referrer-Policy" => "strict-origin-when-cross-origin" -# } - -# Do not treat an `ActionController::Parameters` instance -# as equal to an equivalent `Hash` by default. -Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false - -# Active Record Encryption now uses SHA-256 as its hash digest algorithm. Important: If you have -# data encrypted with previous Rails versions, there are two scenarios to consider: -# -# 1. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA1 (the default -# before Rails 7.0), you need to configure SHA-1 for Active Record Encryption too: -# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1 -# 2. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA256 (the new default -# in 7.0), then you need to configure SHA-256 for Active Record Encryption: -# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256 -# -# If you don't currently have data encrypted with Active Record encryption, you can disable this setting to -# configure the default behavior starting 7.1+: -# Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = false - -# No longer run after_commit callbacks on the first of multiple Active Record -# instances to save changes to the same database row within a transaction. -# Instead, run these callbacks on the instance most likely to have internal -# state which matches what was committed to the database, typically the last -# instance to save. -Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false - -# Configures SQLite with a strict strings mode, which disables double-quoted string literals. -# -# SQLite has some quirks around double-quoted string literals. -# It first tries to consider double-quoted strings as identifier names, but if they don't exist -# it then considers them as string literals. Because of this, typos can silently go unnoticed. -# For example, it is possible to create an index for a non existing column. -# See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details. -Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true - -# Disable deprecated singular associations names -Rails.application.config.active_record.allow_deprecated_singular_associations_name = false - -# Enable the Active Job `BigDecimal` argument serializer, which guarantees -# roundtripping. Without this serializer, some queue adapters may serialize -# `BigDecimal` arguments as simple (non-roundtrippable) strings. -# -# When deploying an application with multiple replicas, old (pre-Rails 7.1) -# replicas will not be able to deserialize `BigDecimal` arguments from this -# serializer. Therefore, this setting should only be enabled after all replicas -# have been successfully upgraded to Rails 7.1. -# Rails.application.config.active_job.use_big_decimal_serializer = true - -# Specify if an `ArgumentError` should be raised if `Rails.cache` `fetch` or -# `write` are given an invalid `expires_at` or `expires_in` time. -# Options are `true`, and `false`. If `false`, the exception will be reported -# as `handled` and logged instead. -Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true - -# Specify whether Query Logs will format tags using the SQLCommenter format -# (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format. -# Options are `:legacy` and `:sqlcommenter`. -Rails.application.config.active_record.query_log_tags_format = :sqlcommenter - -# Specify the default serializer used by `MessageEncryptor` and `MessageVerifier` -# instances. -# -# The legacy default is `:marshal`, which is a potential vector for -# deserialization attacks in cases where a message signing secret has been -# leaked. -# -# In Rails 7.1, the new default is `:json_allow_marshal` which serializes and -# deserializes with `ActiveSupport::JSON`, but can fall back to deserializing -# with `Marshal` so that legacy messages can still be read. -# -# In Rails 7.2, the default will become `:json` which serializes and -# deserializes with `ActiveSupport::JSON` only. -# -# Alternatively, you can choose `:message_pack` or `:message_pack_allow_marshal`, -# which serialize with `ActiveSupport::MessagePack`. `ActiveSupport::MessagePack` -# can roundtrip some Ruby types that are not supported by JSON, and may provide -# improved performance, but it requires the `msgpack` gem. -# -# For more information, see -# https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer -# -# If you are performing a rolling deploy of a Rails 7.1 upgrade, wherein servers -# that have not yet been upgraded must be able to read messages from upgraded -# servers, first deploy without changing the serializer, then set the serializer -# in a subsequent deploy. -# Rails.application.config.active_support.message_serializer = :json_allow_marshal - -# Enable a performance optimization that serializes message data and metadata -# together. This changes the message format, so messages serialized this way -# cannot be read by older versions of Rails. However, messages that use the old -# format can still be read, regardless of whether this optimization is enabled. -# -# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have -# not yet been upgraded must be able to read messages from upgraded servers, -# leave this optimization off on the first deploy, then enable it on a -# subsequent deploy. -# Rails.application.config.active_support.use_message_serializer_for_metadata = true - -# Set the maximum size for Rails log files. -# -# `config.load_defaults 7.1` does not set this value for environments other than -# development and test. -# -Rails.application.config.log_file_size = 100 * 1024 * 1024 if Rails.env.local? - -# Enable raising on assignment to attr_readonly attributes. The previous -# behavior would allow assignment but silently not persist changes to the -# database. -Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true - -# Enable validating only parent-related columns for presence when the parent is mandatory. -# The previous behavior was to validate the presence of the parent record, which performed an extra query -# to get the parent every time the child record was updated, even when parent has not changed. -Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false - -# Enable precompilation of `config.filter_parameters`. Precompilation can -# improve filtering performance, depending on the quantity and types of filters. -Rails.application.config.precompile_filter_parameters = true - -# Enable before_committed! callbacks on all enrolled records in a transaction. -# The previous behavior was to only run the callbacks on the first copy of a record -# if there were multiple copies of the same record enrolled in the transaction. -Rails.application.config.active_record.before_committed_on_all_records = true - -# Disable automatic column serialization into YAML. -# To keep the historic behavior, you can set it to `YAML`, however it is -# recommended to explicitly define the serialization method for each column -# rather than to rely on a global default. -Rails.application.config.active_record.default_column_serializer = nil - -# Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model. -# This matches the behaviour of all other callbacks. -# In previous versions of Rails, they ran in the inverse order. -Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true - -# Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`. -# -# Rails.application.config.active_record.commit_transaction_on_non_local_return = true - -# Controls when to generate a value for has_secure_token declarations. -# -Rails.application.config.active_record.generate_secure_token_on = :initialize - -# ** Please read carefully, this must be configured in config/application.rb ** -# Change the format of the cache entry. -# Changing this default means that all new cache entries added to the cache -# will have a different format that is not supported by Rails 7.0 -# applications. -# Only change this value after your application is fully deployed to Rails 7.1 -# and you have no plans to rollback. -# When you're ready to change format, add this to `config/application.rb` (NOT -# this file): -# config.active_support.cache_format_version = 7.1 - -# Configure Action View to use HTML5 standards-compliant sanitizers when they are supported on your -# platform. -# -# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action View to use HTML5-compliant -# sanitizers if they are supported, else fall back to HTML4 sanitizers. -# -# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor. -# -Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor - -# Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your -# platform. -# -# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action Text to use HTML5-compliant -# sanitizers if they are supported, else fall back to HTML4 sanitizers. -# -# In previous versions of Rails, Action Text always used `Rails::HTML4::Sanitizer` as its vendor. -# -# Rails.application.config.action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor - -# Configure the log level used by the DebugExceptions middleware when logging -# uncaught exceptions during requests -# Rails.application.config.action_dispatch.debug_exception_log_level = :error - -# Configure the test helpers in Action View, Action Dispatch, and rails-dom-testing to use HTML5 -# parsers. -# -# Nokogiri::HTML5 isn't supported on JRuby, so JRuby applications must set this to :html4. -# -# In previous versions of Rails, these test helpers always used an HTML4 parser. -# -Rails.application.config.dom_testing_default_html_version = :html5 From 77c2216e47c8ffba4dde91c1a300cf924a8e5c05 Mon Sep 17 00:00:00 2001 From: Daniel M Brasil Date: Mon, 10 Jun 2024 10:33:48 -0300 Subject: [PATCH 02/90] fix: Return HTTP 422 when scheduled status time is less than 5 minutes (#30584) --- app/services/post_status_service.rb | 2 +- spec/requests/api/v1/statuses_spec.rb | 26 +++++++++++++++++++++++ spec/services/post_status_service_spec.rb | 10 +++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 83a93181709b6c..8b18ce038d8d47 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -171,7 +171,7 @@ def idempotency_duplicate? end def scheduled_in_the_past? - @scheduled_at.present? && @scheduled_at <= Time.now.utc + MIN_SCHEDULE_OFFSET + @scheduled_at.present? && @scheduled_at <= Time.now.utc end def bump_potential_friendship! diff --git a/spec/requests/api/v1/statuses_spec.rb b/spec/requests/api/v1/statuses_spec.rb index 694861fb1c3f8e..2f99b35e74fa0d 100644 --- a/spec/requests/api/v1/statuses_spec.rb +++ b/spec/requests/api/v1/statuses_spec.rb @@ -193,6 +193,32 @@ expect(response).to have_http_status(404) end end + + context 'when scheduling a status' do + let(:params) { { status: 'Hello world', scheduled_at: 10.minutes.from_now } } + let(:account) { user.account } + + it 'returns HTTP 200' do + subject + + expect(response).to have_http_status(200) + end + + it 'creates a scheduled status' do + expect { subject }.to change { account.scheduled_statuses.count }.from(0).to(1) + end + + context 'when the scheduling time is less than 5 minutes' do + let(:params) { { status: 'Hello world', scheduled_at: 4.minutes.from_now } } + + it 'does not create a scheduled status', :aggregate_failures do + subject + + expect(response).to have_http_status(422) + expect(account.scheduled_statuses).to be_empty + end + end + end end describe 'DELETE /api/v1/statuses/:id' do diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb index 11bf4c30ea3adf..f21548b5f2c1d5 100644 --- a/spec/services/post_status_service_spec.rb +++ b/spec/services/post_status_service_spec.rb @@ -61,6 +61,16 @@ status2 = subject.call(account, text: 'test', idempotency: 'meepmeep', scheduled_at: future) expect(status2.id).to eq status1.id end + + context 'when scheduled_at is less than min offset' do + let(:invalid_scheduled_time) { 4.minutes.from_now } + + it 'raises invalid record error' do + expect do + subject.call(account, text: 'Hi future!', scheduled_at: invalid_scheduled_time) + end.to raise_error(ActiveRecord::RecordInvalid) + end + end end it 'creates response to the original status of boost' do From 801f9feec3d23be013751a3c468356a1c3c6ddf7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:52:57 +0200 Subject: [PATCH 03/90] chore(deps): update dependency concurrent-ruby to v1.3.3 (#30605) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8ff990260b6309..93877e15d86177 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -168,7 +168,7 @@ GEM climate_control (1.2.0) cocoon (1.2.15) color_diff (0.1) - concurrent-ruby (1.3.1) + concurrent-ruby (1.3.3) connection_pool (2.4.1) cose (1.3.0) cbor (~> 0.5.9) From bfd674d819327b4af3053ec35aea96f0c9e36428 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:04:44 +0200 Subject: [PATCH 04/90] chore(deps): update dependency httplog to '~> 1.7.0' (#30613) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 136d074d3318d7..be02a656263944 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,7 @@ gem 'hiredis', '~> 0.6' gem 'htmlentities', '~> 4.3' gem 'http', '~> 5.2.0' gem 'http_accept_language', '~> 2.1' -gem 'httplog', '~> 1.6.2' +gem 'httplog', '~> 1.7.0' gem 'i18n' gem 'idn-ruby', require: 'idn' gem 'inline_svg' diff --git a/Gemfile.lock b/Gemfile.lock index 93877e15d86177..812e23a852bef2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -321,7 +321,7 @@ GEM http-form_data (2.3.0) http_accept_language (2.1.1) httpclient (2.8.3) - httplog (1.6.3) + httplog (1.7.0) rack (>= 2.0) rainbow (>= 2.0.0) i18n (1.14.5) @@ -947,7 +947,7 @@ DEPENDENCIES htmlentities (~> 4.3) http (~> 5.2.0) http_accept_language (~> 2.1) - httplog (~> 1.6.2) + httplog (~> 1.7.0) i18n i18n-tasks (~> 1.0) idn-ruby From 2dca6ec77ad8be8674cde103578c416095a3522b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:05:57 +0200 Subject: [PATCH 05/90] chore(deps): update dependency oj to v3.16.4 (#30620) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 812e23a852bef2..095433981aaa21 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -453,7 +453,7 @@ GEM concurrent-ruby (~> 1.0, >= 1.0.2) sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) - oj (3.16.3) + oj (3.16.4) bigdecimal (>= 3.0) omniauth (2.1.2) hashie (>= 3.4.6) From 452872412dd5a3af0ca9186726bf5a5fb8038856 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:07:35 +0200 Subject: [PATCH 06/90] chore(deps): update dependency @types/lodash to v4.17.5 (#30627) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index dcc17d65990acc..e3d3bebeb15afa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3712,9 +3712,9 @@ __metadata: linkType: hard "@types/lodash@npm:^4.14.195": - version: 4.17.4 - resolution: "@types/lodash@npm:4.17.4" - checksum: 10c0/0124c64cb9fe7a0f78b6777955abd05ef0d97844d49118652eae45f8fa57bfb7f5a7a9bccc0b5a84c0a6dc09631042e4590cb665acb9d58dfd5e6543c75341ec + version: 4.17.5 + resolution: "@types/lodash@npm:4.17.5" + checksum: 10c0/55924803ed853e72261512bd3eaf2c5b16558c3817feb0a3125ef757afe46e54b86f33d1960e40b7606c0ddab91a96f47966bf5e6006b7abfd8994c13b04b19b languageName: node linkType: hard From dd4a976122ac1da57ac011f84d71e168ad911cfe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:08:02 +0200 Subject: [PATCH 07/90] chore(deps): update devdependencies (non-major) (#30628) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index e3d3bebeb15afa..8a1f96b69a6f54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13062,8 +13062,8 @@ __metadata: linkType: hard "pino-pretty@npm:^11.0.0": - version: 11.1.0 - resolution: "pino-pretty@npm:11.1.0" + version: 11.2.0 + resolution: "pino-pretty@npm:11.2.0" dependencies: colorette: "npm:^2.0.7" dateformat: "npm:^4.6.3" @@ -13081,7 +13081,7 @@ __metadata: strip-json-comments: "npm:^3.1.1" bin: pino-pretty: bin.js - checksum: 10c0/418be6f854b0d62c83c65e75b0969d5311792bfadeefbfe77d8a7f8c5ba26b8bea40f549222b5f500439f440eb4d6c2fa99d712bdd02881ebae7be3a0193b581 + checksum: 10c0/59421522c0e07877614ed8b51eb45fe79aad9865244b95dfaf5e28c83f9e95631941b5b9e37a277d1751ed90903d7593915e8a8857cc856b4af7e6bf20a5f97d languageName: node linkType: hard @@ -14022,11 +14022,11 @@ __metadata: linkType: hard "prettier@npm:^3.0.0": - version: 3.3.0 - resolution: "prettier@npm:3.3.0" + version: 3.3.1 + resolution: "prettier@npm:3.3.1" bin: prettier: bin/prettier.cjs - checksum: 10c0/d033c356320aa2e468bf29c931b094ac730d2f4defd5eb2989d8589313dec901d2fc866e3788f3d161e420b142ea4ec3dda535dbe0169ef4d0026397a68ba9cf + checksum: 10c0/c25a709c9f0be670dc6bcb190b622347e1dbeb6c3e7df8b0711724cb64d8647c60b839937a4df4df18e9cfb556c2b08ca9d24d9645eb5488a7fc032a2c4d5cb3 languageName: node linkType: hard From a6e0e167a71025b27719666906cfb5511734134e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:29:11 +0200 Subject: [PATCH 08/90] fix(deps): update dependency uuid to v10 (#30624) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- streaming/package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/streaming/package.json b/streaming/package.json index cf1fe4ba69b7a0..2e515167c7de57 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -27,7 +27,7 @@ "pino": "^9.0.0", "pino-http": "^10.0.0", "prom-client": "^15.0.0", - "uuid": "^9.0.0", + "uuid": "^10.0.0", "ws": "^8.12.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 8a1f96b69a6f54..33cd7b481d414d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2942,7 +2942,7 @@ __metadata: prom-client: "npm:^15.0.0" typescript: "npm:^5.0.4" utf-8-validate: "npm:^6.0.3" - uuid: "npm:^9.0.0" + uuid: "npm:^10.0.0" ws: "npm:^8.12.1" dependenciesMeta: bufferutil: @@ -17489,6 +17489,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^10.0.0": + version: 10.0.0 + resolution: "uuid@npm:10.0.0" + bin: + uuid: dist/bin/uuid + checksum: 10c0/eab18c27fe4ab9fb9709a5d5f40119b45f2ec8314f8d4cf12ce27e4c6f4ffa4a6321dc7db6c515068fa373c075b49691ba969f0010bf37f44c37ca40cd6bf7fe + languageName: node + linkType: hard + "uuid@npm:^3.3.2": version: 3.4.0 resolution: "uuid@npm:3.4.0" @@ -17507,15 +17516,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^9.0.0": - version: 9.0.1 - resolution: "uuid@npm:9.0.1" - bin: - uuid: dist/bin/uuid - checksum: 10c0/1607dd32ac7fc22f2d8f77051e6a64845c9bce5cd3dd8aa0070c074ec73e666a1f63c7b4e0f4bf2bc8b9d59dc85a15e17807446d9d2b17c8485fbc2147b27f9b - languageName: node - linkType: hard - "v8-compile-cache@npm:^2.1.1": version: 2.3.0 resolution: "v8-compile-cache@npm:2.3.0" From 589365ba52b5e982f31c7acbb0a264bc378e061b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:29:26 +0200 Subject: [PATCH 09/90] chore(deps): update dependency rubocop-capybara to v2.21.0 (#30611) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 095433981aaa21..4d16fea47cb973 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -578,7 +578,7 @@ GEM opentelemetry-api (~> 1.0) orm_adapter (0.5.0) ox (2.14.18) - parallel (1.24.0) + parallel (1.25.1) parser (3.3.2.0) ast (~> 2.4.1) racc @@ -739,7 +739,7 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.31.3) parser (>= 3.3.1.0) - rubocop-capybara (2.20.0) + rubocop-capybara (2.21.0) rubocop (~> 1.41) rubocop-factory_bot (2.25.1) rubocop (~> 1.41) From bb27321781778d4d849dd0a4c2f16747f85f1a3d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:29:30 +0200 Subject: [PATCH 10/90] New Crowdin Translations (automated) (#30608) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/eo.json | 7 ++ app/javascript/mastodon/locales/fr-CA.json | 6 +- app/javascript/mastodon/locales/fr.json | 6 +- app/javascript/mastodon/locales/ia.json | 4 +- app/javascript/mastodon/locales/id.json | 10 ++ app/javascript/mastodon/locales/la.json | 125 +++++++++++++++++++-- config/locales/devise.la.yml | 7 ++ config/locales/doorkeeper.ja.yml | 2 + config/locales/doorkeeper.lad.yml | 2 + config/locales/doorkeeper.lt.yml | 2 + config/locales/doorkeeper.sv.yml | 1 + config/locales/doorkeeper.th.yml | 2 + config/locales/doorkeeper.vi.yml | 2 + config/locales/id.yml | 6 + config/locales/la.yml | 33 ++++++ config/locales/nl.yml | 4 +- config/locales/simple_form.id.yml | 3 + config/locales/th.yml | 4 +- 18 files changed, 204 insertions(+), 22 deletions(-) diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 6e7885f485bc90..2dbbf787730920 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -498,7 +498,14 @@ "poll_button.add_poll": "Aldoni balotenketon", "poll_button.remove_poll": "Forigi balotenketon", "privacy.change": "Agordi mesaĝan privatecon", + "privacy.direct.long": "Ĉiuj menciitaj en la afiŝo", + "privacy.direct.short": "Specifaj homoj", + "privacy.private.long": "Nur viaj sekvantoj", + "privacy.private.short": "Sekvantoj", + "privacy.public.long": "Ĉiujn ajn ĉe kaj ekster Mastodon", "privacy.public.short": "Publika", + "privacy.unlisted.long": "Malpli algoritmaj fanfaroj", + "privacy.unlisted.short": "Diskrete publika", "privacy_policy.last_updated": "Laste ĝisdatigita en {date}", "privacy_policy.title": "Politiko de privateco", "recommended": "Rekomendita", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index 9e29852904107c..9c14d05d5c88a9 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -156,7 +156,7 @@ "compose_form.poll.duration": "Durée du sondage", "compose_form.poll.multiple": "Choix multiple", "compose_form.poll.option_placeholder": "Option {number}", - "compose_form.poll.single": "Choisissez-en un", + "compose_form.poll.single": "Choix unique", "compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix", "compose_form.poll.switch_to_single": "Changer le sondage pour n'autoriser qu'un seul choix", "compose_form.poll.type": "Style", @@ -585,9 +585,9 @@ "privacy.private.short": "Abonnés", "privacy.public.long": "Tout le monde sur et en dehors de Mastodon", "privacy.public.short": "Public", - "privacy.unlisted.additional": "Cette option se comporte exactement comme l'option publique, sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, l'exploration ou la recherche Mastodon, même si vous avez opté pour l'option publique pour l'ensemble de votre compte.", + "privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.", "privacy.unlisted.long": "Moins de fanfares algorithmiques", - "privacy.unlisted.short": "Public calme", + "privacy.unlisted.short": "Public discret", "privacy_policy.last_updated": "Dernière mise à jour {date}", "privacy_policy.title": "Politique de confidentialité", "recommended": "Recommandé", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 1a5803623f0037..36ec673a475b28 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -156,7 +156,7 @@ "compose_form.poll.duration": "Durée du sondage", "compose_form.poll.multiple": "Choix multiple", "compose_form.poll.option_placeholder": "Option {number}", - "compose_form.poll.single": "Choisissez-en un", + "compose_form.poll.single": "Choix unique", "compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix", "compose_form.poll.switch_to_single": "Modifier le sondage pour autoriser qu'un seul choix", "compose_form.poll.type": "Style", @@ -585,9 +585,9 @@ "privacy.private.short": "Abonnés", "privacy.public.long": "Tout le monde sur et en dehors de Mastodon", "privacy.public.short": "Public", - "privacy.unlisted.additional": "Cette option se comporte exactement comme l'option publique, sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, l'exploration ou la recherche Mastodon, même si vous avez opté pour l'option publique pour l'ensemble de votre compte.", + "privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.", "privacy.unlisted.long": "Moins de fanfares algorithmiques", - "privacy.unlisted.short": "Public calme", + "privacy.unlisted.short": "Public discret", "privacy_policy.last_updated": "Dernière mise à jour {date}", "privacy_policy.title": "Politique de confidentialité", "recommended": "Recommandé", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index ce4e89e99a2c02..ed33a45d45047d 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -19,7 +19,7 @@ "account.block_domain": "Blocar dominio {domain}", "account.block_short": "Blocar", "account.blocked": "Blocate", - "account.browse_more_on_origin_server": "Percurrer plus sur le profilo original", + "account.browse_more_on_origin_server": "Explorar plus sur le profilo original", "account.cancel_follow_request": "Cancellar sequimento", "account.copy": "Copiar ligamine a profilo", "account.direct": "Mentionar privatemente @{name}", @@ -111,7 +111,7 @@ "bundle_modal_error.message": "Un error ha occurrite durante le cargamento de iste componente.", "bundle_modal_error.retry": "Tentar novemente", "closed_registrations.other_server_instructions": "Perque Mastodon es decentralisate, tu pote crear un conto sur un altere servitor e totevia interager con iste servitor.", - "closed_registrations_modal.description": "Crear un conto in {domain} actualmente non es possibile, ma considera que non es necessari haber un conto specificamente sur {domain} pro usar Mastodon.", + "closed_registrations_modal.description": "Crear un conto sur {domain} non es actualmente possibile, ma considera que non es necessari haber un conto specificamente sur {domain} pro usar Mastodon.", "closed_registrations_modal.find_another_server": "Cercar un altere servitor", "closed_registrations_modal.preamble": "Mastodon es decentralisate, dunque, non importa ubi tu crea tu conto, tu pote sequer e communicar con omne persona sur iste servitor. Tu pote mesmo hospitar tu proprie servitor!", "closed_registrations_modal.title": "Crear un conto sur Mastodon", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 33161f888251d9..79224c57df1f7d 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -299,6 +299,11 @@ "follow_suggestions.dismiss": "Jangan tampilkan lagi", "follow_suggestions.hints.featured": "Profil ini telah dipilih sendiri oleh tim {domain}.", "follow_suggestions.hints.friends_of_friends": "Profil ini populer di kalangan orang yang anda ikuti.", + "follow_suggestions.personalized_suggestion": "Saran yang dipersonalisasi", + "follow_suggestions.popular_suggestion": "Saran populer", + "follow_suggestions.popular_suggestion_longer": "Populer di {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Serupa dengan profil yang baru Anda ikuti", + "follow_suggestions.view_all": "Lihat semua", "followed_tags": "Tagar yang diikuti", "footer.about": "Tentang", "footer.directory": "Direktori profil", @@ -324,6 +329,7 @@ "home.column_settings.show_reblogs": "Tampilkan boost", "home.column_settings.show_replies": "Tampilkan balasan", "home.hide_announcements": "Sembunyikan pengumuman", + "home.pending_critical_update.link": "Lihat pembaruan", "home.show_announcements": "Tampilkan pengumuman", "interaction_modal.description.follow": "Dengan sebuah akun di Mastodon, Anda bisa mengikuti {name} untuk menerima kirimannya di beranda Anda.", "interaction_modal.description.reblog": "Dengan sebuah akun di Mastodon, Anda bisa mem-boost kiriman ini untuk membagikannya ke pengikut Anda sendiri.", @@ -375,6 +381,7 @@ "lightbox.previous": "Sebelumnya", "limited_account_hint.action": "Tetap tampilkan profil", "limited_account_hint.title": "Profil ini telah disembunyikan oleh moderator {domain}.", + "link_preview.author": "Oleh {name}", "lists.account.add": "Tambah ke daftar", "lists.account.remove": "Hapus dari daftar", "lists.delete": "Hapus daftar", @@ -389,8 +396,11 @@ "lists.search": "Cari di antara orang yang Anda ikuti", "lists.subheading": "Daftar Anda", "load_pending": "{count, plural, other {# item baru}}", + "loading_indicator.label": "Memuat…", "media_gallery.toggle_visible": "Tampil/Sembunyikan", "moved_to_account_banner.text": "Akun {disabledAccount} Anda kini dinonaktifkan karena Anda pindah ke {movedToAccount}.", + "mute_modal.hide_options": "Sembunyikan opsi", + "mute_modal.title": "Bisukan pengguna?", "navigation_bar.about": "Tentang", "navigation_bar.blocks": "Pengguna diblokir", "navigation_bar.bookmarks": "Markah", diff --git a/app/javascript/mastodon/locales/la.json b/app/javascript/mastodon/locales/la.json index a49ec94d726b24..4bee0efed47c98 100644 --- a/app/javascript/mastodon/locales/la.json +++ b/app/javascript/mastodon/locales/la.json @@ -1,7 +1,9 @@ { "about.contact": "Ratio:", "about.domain_blocks.no_reason_available": "Ratio abdere est", + "about.domain_blocks.silenced.explanation": "Tua profilia atque tuum contentum ab hac serve praecipue non videbis, nisi explōrēs expresse aut subsequeris et optēs.", "account.account_note_header": "Annotatio", + "account.add_or_remove_from_list": "Adde aut ēripe ex tabellīs", "account.badges.bot": "Robotum", "account.badges.group": "Congregatio", "account.block": "Impedire @{name}", @@ -11,11 +13,21 @@ "account.domain_blocked": "Dominium impeditum", "account.edit_profile": "Recolere notionem", "account.featured_tags.last_status_never": "Nulla contributa", + "account.featured_tags.title": "Hashtag notātī {name}", + "account.followers_counter": "{count, plural, one {{counter} Sectator} other {{counter} Sectatores}}", + "account.following_counter": "{count, plural, one {{counter} Sequens} other {{counter} Sequentes}}", + "account.moved_to": "{name} significavit eum suam rationem novam nunc esse:", "account.muted": "Confutatus", + "account.requested_follow": "{name} postulavit ut te sequeretur", + "account.statuses_counter": "{count, plural, one {{counter} Nuntius} other {{counter} Nuntii}}", "account.unblock_short": "Solvere impedimentum", "account_note.placeholder": "Click to add a note", "admin.dashboard.retention.average": "Mediocritas", + "admin.impact_report.instance_accounts": "Rationes perfiles hoc deleret", + "alert.unexpected.message": "Error inopinatus occurrit.", "announcement.announcement": "Proclamatio", + "attachments_list.unprocessed": "(immūtātus)", + "block_modal.you_wont_see_mentions": "Nuntios quibus eos commemorant non videbis.", "bundle_column_error.error.title": "Eheu!", "bundle_column_error.retry": "Retemptare", "bundle_column_error.routing.title": "CCCCIIII", @@ -37,26 +49,55 @@ "compose_form.placeholder": "What is on your mind?", "compose_form.publish_form": "Barrire", "compose_form.spoiler.marked": "Text is hidden behind warning", - "compose_form.spoiler.unmarked": "Text is not hidden", + "compose_form.spoiler.unmarked": "Adde praeconium contentūs", "confirmations.block.confirm": "Impedire", "confirmations.delete.confirm": "Oblitterare", "confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete_list.confirm": "Oblitterare", + "confirmations.discard_edit_media.message": "Habēs mutationēs in descriptionem vel prōspectum medii quae nōn sunt servātae; eas dēmittam?", "confirmations.mute.confirm": "Confutare", "confirmations.reply.confirm": "Respondere", + "disabled_account_banner.account_settings": "Praeferentiae ratiōnis", + "disabled_account_banner.text": "Ratio tua {disabledAccount} debilitata est.", "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", + "domain_block_modal.you_will_lose_followers": "Omnes sectatores tuī ex hoc servō removēbuntur.", + "domain_block_modal.you_wont_see_posts": "Nuntios aut notificātiōnēs ab usoribus in hōc servō nōn vidēbis.", + "domain_pill.activitypub_like_language": "ActivityPub est velut lingua quam Mastodon cum aliīs sociālibus rētibus loquitur.", + "domain_pill.your_handle": "Tuus nominulus:", + "domain_pill.your_server": "Tua domus digitalis, ubi omnia tua nuntia habitant. Hanc non amas? Servēs trānsferāre potes quōcumque tempore et sectātōrēs tuōs simul addūcere.", + "domain_pill.your_username": "Tuō singulāre id indicium in hōc servō est. Est possibile invenīre usōrēs cum eōdem nōmine in servīs aliīs.", "embed.instructions": "Embed this status on your website by copying the code below.", + "emoji_button.activity": "Actiō", "emoji_button.food": "Cibus et potus", "emoji_button.people": "Homines", "emoji_button.search": "Quaerere...", + "empty_column.account_suspended": "Rātiō suspēnsa", "empty_column.account_timeline": "Hic nulla contributa!", "empty_column.account_unavailable": "Notio non impetrabilis", - "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}", + "empty_column.blocks": "Nondum quemquam usorem obsēcāvisti.", + "empty_column.direct": "Nōn habēs adhūc ullo mentionēs prīvātās. Cum ūnam mīseris aut accipis, hīc apparēbit.", + "empty_column.followed_tags": "Nōn adhūc aliquem hastāginem secūtus es. Cum id fēceris, hic ostendētur.", + "empty_column.home": "Tua linea temporum domesticus vacua est! Sequere plures personas ut eam compleas.", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", + "empty_column.lists": "Nōn adhūc habēs ullo tabellās. Cum creās, hīc apparēbunt.", + "empty_column.mutes": "Nondum quemquam usorem tacuisti.", + "empty_column.notification_requests": "Omnia clara sunt! Nihil hic est. Cum novās notificātiōnēs accipīs, hic secundum tua praecepta apparebunt.", + "empty_column.notifications": "Nōn adhūc habēs ullo notificātiōnēs. Cum aliī tē interagunt, hīc videbis.", "explore.trending_statuses": "Contributa", + "filtered_notifications_banner.mentions": "{count, plural, one {mentiō} other {mentiōnēs}}", + "firehose.all": "Omnis", + "footer.about": "De", "generic.saved": "Servavit", + "hashtag.column_settings.tag_mode.all": "Haec omnia", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} particeps} other {{counter} participēs}}", + "hashtag.counter_by_uses": "{count, plural, one {{counter} nuntius} other {{counter} nuntii}}", + "hashtag.counter_by_uses_today": "{count, plural, one {{counter} nuntius} other {{counter} nuntii}} hodie", + "hashtags.and_other": "…et {count, plural, other {# plus}}", + "intervals.full.days": "{number, plural, one {# die} other {# dies}}", + "intervals.full.hours": "{number, plural, one {# hora} other {# horae}}", + "intervals.full.minutes": "{number, plural, one {# minutum} other {# minuta}}", "keyboard_shortcuts.back": "Re navigare", "keyboard_shortcuts.blocked": "Aperire listam usorum obstructorum", "keyboard_shortcuts.boost": "Inlustrare publicatio", @@ -90,18 +131,47 @@ "keyboard_shortcuts.up": "to move up in the list", "lightbox.close": "Claudere", "lightbox.next": "Secundum", + "lists.account.add": "Adde ad tabellās", + "lists.new.create": "Addere tabella", + "load_pending": "{count, plural, one {# novum item} other {# nova itema}}", + "media_gallery.toggle_visible": "{number, plural, one {Cēla imaginem} other {Cēla imagines}}", + "moved_to_account_banner.text": "Tua ratione {disabledAccount} interdum reposita est, quod ad {movedToAccount} migrāvisti.", + "mute_modal.you_wont_see_mentions": "Non videbis nuntios quī eōs commemorant.", + "navigation_bar.about": "De", "navigation_bar.domain_blocks": "Hidden domains", - "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", + "not_signed_in_indicator.not_signed_in": "Ad hunc locum pervenire oportet ut inīre facias.", + "notification.admin.report": "{name} nuntiavit {target}", + "notification.admin.sign_up": "{name} subscripsit", + "notification.favourite": "{name} nuntium tuum favit", + "notification.follow": "{name} te secutus est", + "notification.follow_request": "{name} postulavit ut te sequeretur", + "notification.mention": "{name} memoravi", + "notification.moderation_warning": "Accepistī monitionem moderationis.", + "notification.moderation_warning.action_disable": "Ratio tua debilitata est.", "notification.moderation_warning.action_none": "Tua ratiō monitum moderātiōnis accēpit.", - "notification.reblog": "{name} boosted your status", + "notification.moderation_warning.action_sensitive": "Tua nuntia hinc sensibiliter notabuntur.", + "notification.moderation_warning.action_silence": "Ratio tua est limitata.", + "notification.moderation_warning.action_suspend": "Ratio tua suspensus est.", + "notification.own_poll": "Suffragium tuum terminatum est.", + "notification.poll": "Electione in quam suffragium dedisti finita est.", + "notification.reblog": "{name} tuum nuntium amplificavit.", + "notification.relationships_severance_event.account_suspension": "Admin ab {from} {target} suspendit, quod significat nōn iam posse tē novitātēs ab eīs accipere aut cum eīs interagere.", + "notification.relationships_severance_event.domain_block": "Admin ab {from} {target} obsēcāvit, includēns {followersCount} ex tuīs sectātōribus et {followingCount, plural, one {# ratione} other {# rationibus}} quās sequeris.", + "notification.relationships_severance_event.user_domain_block": "Bloqueāstī {target}, removēns {followersCount} ex sectātōribus tuīs et {followingCount, plural, one {# rationem} other {# rationēs}} quōs sequeris.", + "notification.status": "{name} nuper publicavit", + "notification.update": "{name} nuntium correxit", + "notification_requests.accept": "Accipe", "notifications.filter.all": "Omnia", "notifications.filter.polls": "Eventus electionis", + "notifications.group": "Notificātiōnēs", "onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_home": "Go to your home feed", - "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", + "onboarding.follows.lead": "Tua domus feed est principalis via Mastodon experīrī. Quō plūrēs persōnas sequeris, eō actīvior et interessantior erit. Ad tē incipiendum, ecce quaedam suāsiones:", "onboarding.follows.title": "Popular on Mastodon", - "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", + "onboarding.profile.display_name_hint": "Tuum nomen completum aut tuum nomen ludens...", + "onboarding.start.lead": "Nunc pars es Mastodonis, singularis, socialis medii platformae decentralis ubi—non algorismus—tuam ipsius experientiam curas. Incipiāmus in nova hac socialis regione:", "onboarding.start.skip": "Want to skip right ahead?", + "onboarding.start.title": "Perfecisti eam!", "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", "onboarding.steps.publish_status.body": "Say hello to the world.", @@ -109,31 +179,48 @@ "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.title": "Share your profile", - "onboarding.tips.accounts_from_other_servers": "Scisne? Quoniam Mastodon dēcentālis est, nōnnulla profīlia quae invenīs in servīs aliīs quam tuōrum erunt hospitāta. Tamen cum eīs sine impedīmentō interāgere potes! Servus eōrum in alterā parte nōminis eōrum est!", + "onboarding.tips.2fa": "Scisne? Tūam ratiōnem sēcūrāre potes duōrum elementōrum authentīcātiōnem in ratiōnis tuī praeferentiīs statuendō. Cum ūllā app TOTP ex tuā ēlēctiōne operātur, numerus tēlephōnicus necessārius nōn est!", + "onboarding.tips.accounts_from_other_servers": "Scisne? Quoniam Mastodon dēcentrālis est, nōnnulla profīlia quae invenīs in servīs aliīs quam tuōrum erunt hospitāta. Tamen cum eīs sine impedīmentō interāgere potes! Servus eōrum in alterā parte nōminis eōrum est!", "onboarding.tips.migration": "Scisne? Sī sentīs {domain} tibi in futūrō nōn esse optimam servī ēlēctiōnem, ad alium servum Mastodon sine amittendō sectātōribus tuīs migrāre potes. Etiam tuum servum hospitārī potes!", + "onboarding.tips.verification": "Scisne? Tūam ratiōnem verificāre potes iungendō nexum ad prōfīlium Mastodon tuum in propriā pāginā interrētiā et addendō pāginam ad prōfīlium tuum. Nullae pecūniae aut documenta necessāria sunt!", "poll.closed": "Clausum", + "poll.total_people": "{count, plural, one {# persona} other {# personae}}", + "poll.total_votes": "{count, plural, one {# suffragium} other {# suffragia}}", "poll.vote": "Eligere", "poll.voted": "Elegisti hoc responsum", + "poll.votes": "{votes, plural, one {# sufragium} other {# sufragia}}", "poll_button.add_poll": "Addere electionem", "poll_button.remove_poll": "Auferre electionem", "privacy.change": "Adjust status privacy", "privacy.public.short": "Coram publico", + "regeneration_indicator.sublabel": "Tua domus feed praeparātur!", + "relative_time.full.days": "{number, plural, one {# ante die} other {# ante dies}}", + "relative_time.full.hours": "{number, plural, one {# ante horam} other {# ante horas}}", "relative_time.full.just_now": "nunc", + "relative_time.full.minutes": "{number, plural, one {# ante minutum} other {# ante minuta}}", + "relative_time.full.seconds": "{number, plural, one {# ante secundum} other {# ante secunda}}", "relative_time.just_now": "nunc", "relative_time.today": "hodie", + "reply_indicator.attachments": "{count, plural, one {# annexus} other {# annexūs}}", "report.block": "Impedimentum", + "report.block_explanation": "Non videbis eorum nuntios. Non poterunt vidēre tuōs nuntios aut tē sequī. Intelligere poterunt sē obstrūctōs esse.", "report.categories.other": "Altera", "report.category.title_account": "notio", "report.category.title_status": "contributum", "report.close": "Confectum", "report.mute": "Confutare", + "report.mute_explanation": "Non videbis eōrum nuntiōs. Possunt adhuc tē sequī et tuōs nuntiōs vidēre, nec sciēbunt sē tacitōs esse.", "report.next": "Secundum", - "report.placeholder": "Type or paste additional comments", + "report.placeholder": "Commentāriī adiūnctī", "report.submit": "Mittere", "report.target": "Report {target}", - "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", + "report_notification.attached_statuses": "{count, plural, one {{count} nuntius} other {{count} nuntii}} attachiatus", "report_notification.categories.other": "Altera", "search.placeholder": "Quaerere", + "search_results.all": "Omnis", + "server_banner.active_users": "Usūrāriī āctīvī", + "server_banner.administered_by": "Administratur:", + "server_banner.introduction": "{domain} pars est de rete sociali decentralizato a {mastodon} propulsato.", "server_banner.learn_more": "Discere plura", "sign_in_banner.sign_in": "Sign in", "status.admin_status": "Open this status in the moderation interface", @@ -143,13 +230,29 @@ "status.delete": "Oblitterare", "status.edit": "Recolere", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", + "status.favourites": "{count, plural, one {favoritum} other {favorita}}", + "status.history.created": "{name} creatum {date}", + "status.history.edited": "{name} correxit {date}", "status.open": "Expand this status", - "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}", + "status.reblogged_by": "{name} adiuvavit", + "status.reblogs": "{count, plural, one {auctus} other {auctūs}}", + "status.title.with_attachments": "{user} publicavit {attachmentCount, plural, one {unum annexum} other {{attachmentCount} annexa}}", "tabs_bar.home": "Domi", + "time_remaining.days": "{number, plural, one {# die} other {# dies}} restant", + "time_remaining.hours": "{number, plural, one {# hora} other {# horae}} restant", + "time_remaining.minutes": "{number, plural, one {# minutum} other {# minuta}} restant", + "time_remaining.seconds": "{number, plural, one {# secundum} other {# secunda}} restant", + "timeline_hint.remote_resource_not_displayed": "{resource} ab aliīs servīs nōn ostenduntur.", "timeline_hint.resources.statuses": "Contributa pristina", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", + "trends.counter_by_accounts": "{count, plural, one {{counter} persōna} other {{counter} persōnae}} in {days, plural, one {diē prīdiē} other {diēbus praeteritīs {days}}}", + "ui.beforeunload": "Si Mastodon discesseris, tua epitome peribit.", + "units.short.billion": "{count} millia milionum", + "units.short.million": "{count} milionum", + "units.short.thousand": "{count} millia", + "upload_button.label": "Imaginēs, vīdeō aut fīle audītūs adde", "upload_form.audio_description": "Describe for people who are hard of hearing", "upload_form.edit": "Recolere", + "upload_modal.description_placeholder": "A velox brunneis vulpes salit super piger canis", "upload_progress.label": "Uploading…", "video.mute": "Confutare soni" } diff --git a/config/locales/devise.la.yml b/config/locales/devise.la.yml index 3a7ba0d44589e5..a6fe5e1e4baeaa 100644 --- a/config/locales/devise.la.yml +++ b/config/locales/devise.la.yml @@ -1 +1,8 @@ +--- la: + devise: + passwords: + send_instructions: Sī adresa tua epistularis in nostra basi datōrum exstat, vinculum ad recuperandam clavem adresa tua epistulari adferētur pauca momenta post. Sī autem hanc epistulam nōn recēpistī, rogāmus ut scrūtināriōnem spurcāriī tuī faciās. + registrations: + destroyed: Vale! Ratio tua succēssu cancellāta est. Spērāmus tē mox iterum vidēre. + signed_up_but_inactive: Te cōnscrīpsistī succēdāneē. At nōn potuimus tē introīre quod ratio* tua nōn adhūc est activāta.* diff --git a/config/locales/doorkeeper.ja.yml b/config/locales/doorkeeper.ja.yml index 62f2a3eb0ae415..26f7ff5635d996 100644 --- a/config/locales/doorkeeper.ja.yml +++ b/config/locales/doorkeeper.ja.yml @@ -135,6 +135,7 @@ ja: media: メディアの添付 mutes: ミュート notifications: 通知 + profile: Mastodonのプロフィール push: プッシュ通知 reports: 通報 search: 検索 @@ -165,6 +166,7 @@ ja: admin:write:reports: 通報に対するアクションの実行 crypto: エンドツーエンド暗号化の使用 follow: アカウントのつながりを変更 + profile: アカウントのプロフィール情報の読み取りのみ push: プッシュ通知の受信 read: アカウントのすべてのデータの読み取り read:accounts: アカウント情報の読み取り diff --git a/config/locales/doorkeeper.lad.yml b/config/locales/doorkeeper.lad.yml index b2c140b9c23c54..c335d67fd6ee09 100644 --- a/config/locales/doorkeeper.lad.yml +++ b/config/locales/doorkeeper.lad.yml @@ -135,6 +135,7 @@ lad: media: Aneksos de multimedia mutes: Silensiasyones notifications: Avizos + profile: Tu profil de Mastodon push: Avizos arrepushados reports: Raportos search: Bushkeda @@ -165,6 +166,7 @@ lad: admin:write:reports: fazer aksyones de moderasyon en raportos crypto: kulanear shifrasyon de lado a lado follow: modifikar relasyones de kuentos + profile: melda solo la informasyon del profil push: risivir tus avizos arrepushados read: meldar todos tus datos de kuento read:accounts: ver enformasyon de kuentos diff --git a/config/locales/doorkeeper.lt.yml b/config/locales/doorkeeper.lt.yml index 5c2e4fd4e0efb3..38bb17ad139918 100644 --- a/config/locales/doorkeeper.lt.yml +++ b/config/locales/doorkeeper.lt.yml @@ -135,6 +135,7 @@ lt: media: Medijos priedai mutes: Nutildymai notifications: Pranešimai + profile: Tavo Mastodon profilis push: Tiesioginiai pranešimai reports: Ataskaitos search: Paieška @@ -165,6 +166,7 @@ lt: admin:write:reports: atlikti ataskaitų prižiūrėjimo veiksmus crypto: naudoti visapusį šifravimą follow: modifikuoti paskyros sąryšius + profile: skaityti tik tavo paskyros profilio informaciją push: gauti tiesioginius pranešimus read: skaityti visus paskyros duomenis read:accounts: matyti paskyrų informaciją diff --git a/config/locales/doorkeeper.sv.yml b/config/locales/doorkeeper.sv.yml index f2c8bd34b8c6c2..bc4ba6f53ed575 100644 --- a/config/locales/doorkeeper.sv.yml +++ b/config/locales/doorkeeper.sv.yml @@ -135,6 +135,7 @@ sv: media: Mediabilagor mutes: Tystade användare notifications: Aviseringar + profile: Din Mastodon-profil push: Push-aviseringar reports: Rapporter search: Sök diff --git a/config/locales/doorkeeper.th.yml b/config/locales/doorkeeper.th.yml index 067e0655884691..b0d0549d1df2c1 100644 --- a/config/locales/doorkeeper.th.yml +++ b/config/locales/doorkeeper.th.yml @@ -135,6 +135,7 @@ th: media: ไฟล์แนบสื่อ mutes: การซ่อน notifications: การแจ้งเตือน + profile: โปรไฟล์ Mastodon ของคุณ push: การแจ้งเตือนแบบผลัก reports: การรายงาน search: ค้นหา @@ -165,6 +166,7 @@ th: admin:write:reports: ทำการกระทำการกลั่นกรองต่อรายงาน crypto: ใช้การเข้ารหัสแบบต้นทางถึงปลายทาง follow: ปรับเปลี่ยนความสัมพันธ์ของบัญชี + profile: อ่านเฉพาะข้อมูลโปรไฟล์ของบัญชีของคุณเท่านั้น push: รับการแจ้งเตือนแบบผลักของคุณ read: อ่านข้อมูลบัญชีทั้งหมดของคุณ read:accounts: ดูข้อมูลบัญชี diff --git a/config/locales/doorkeeper.vi.yml b/config/locales/doorkeeper.vi.yml index 7f1c5430edc1ea..d0bdd2cc7b1606 100644 --- a/config/locales/doorkeeper.vi.yml +++ b/config/locales/doorkeeper.vi.yml @@ -135,6 +135,7 @@ vi: media: Tập tin đính kèm mutes: Đã ẩn notifications: Thông báo + profile: Hồ sơ Mastodon của bạn push: Thông báo đẩy reports: Báo cáo search: Tìm kiếm @@ -165,6 +166,7 @@ vi: admin:write:reports: áp đặt kiểm duyệt với các báo cáo crypto: dùng mã hóa đầu cuối follow: sửa đổi các mối quan hệ tài khoản + profile: chỉ đọc thông tin tài khoản cơ bản push: nhận thông báo đẩy read: đọc mọi dữ liệu tài khoản read:accounts: xem thông tin tài khoản diff --git a/config/locales/id.yml b/config/locales/id.yml index aae790f4814164..ac42afdb4f7892 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -89,6 +89,7 @@ id: moderation: active: Aktif all: Semua + disabled: Nonaktif pending: Tertunda silenced: Terbatas suspended: Disuspen @@ -121,6 +122,8 @@ id: removed_header_msg: Berhasil menghapus gambar header %{username} resend_confirmation: already_confirmed: Pengguna ini sudah dikonfirmasi + send: Kirim ulang email konfirmasi + success: Email konfirmasi berhasil dikirim! reset: Atur ulang reset_password: Reset kata sandi resubscribe: Langganan ulang @@ -128,6 +131,7 @@ id: search: Cari search_same_email_domain: Pengguna lain dengan domain email yang sama search_same_ip: Pengguna lain dengan IP yang sama + security: Keamanan security_measures: only_password: Hanya kata sandi password_and_2fa: Kata sandi dan 2FA @@ -278,6 +282,7 @@ id: update_custom_emoji_html: "%{name} memperbarui emoji %{target}" update_domain_block_html: "%{name} memperbarui blokir domain untuk %{target}" update_ip_block_html: "%{name} mengubah peraturan untuk IP %{target}" + update_report_html: "%{name} memperbarui laporan %{target}" update_status_html: "%{name} memperbarui status %{target}" update_user_role_html: "%{name} mengubah peran %{target}" deleted_account: akun yang dihapus @@ -302,6 +307,7 @@ id: unpublish: Batal terbitkan unpublished_msg: Pengumuman berhasil ditarik! updated_msg: Pengumuman berhasil diperbarui! + critical_update_pending: Pembaruan penting tertunda custom_emojis: assign_category: Beri kategori by_domain: Domain diff --git a/config/locales/la.yml b/config/locales/la.yml index 3a7ba0d44589e5..d3733df934d083 100644 --- a/config/locales/la.yml +++ b/config/locales/la.yml @@ -1 +1,34 @@ +--- la: + about: + about_mastodon_html: '"Rete sociale futuri: Nullae praebendae, nulla observatio corporativa, ethica designatio, et decentralizatio! Tua data cum Mastodonte posside!"' + contact_missing: Non definitum + contact_unavailable: Nōn Applicābilis + hosted_on: Mastodon in %{domain} hospitātum + title: De + accounts: + follow: Sequere + followers: + one: Sectātor + other: Sectātōrēs + following: Sequendī + instance_actor_flash: Hic ratio est actōr virtuālis ad repraesentandam ipsum servatorem et non ullam individuam usorem. Ad scopōs foederātiōnis ūtor nec suspendendus est. + last_active: Ultimum Actum + link_verified_on: Dominium huius nexūs est comprobatum die %{date}. + nothing_here: Nihil est hic! + pin_errors: + following: Iam debes sequi personam quam vis probare. + posts: + one: Nuntius + other: Nuntii + posts_tab_heading: Nuntii + admin: + account_actions: + action: Agere actionem + title: Actionem moderationis in %{acct} gerere + account_moderation_notes: + create: Relinque nota + created_msg: Nota moderationis feliciter creata est! + destroyed_msg: Nota moderationis feliciter deleta est! + accounts: + are_you_sure: Esne certus? diff --git a/config/locales/nl.yml b/config/locales/nl.yml index a527fdb5a7009a..328467f483d2bf 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1814,14 +1814,14 @@ nl: subject: Jouw archief staat klaar om te worden gedownload title: Archief ophalen failed_2fa: - details: 'Hier zijn details van de inlogpoging:' + details: 'Hier zijn de details van de inlogpoging:' explanation: Iemand heeft geprobeerd om in te loggen op jouw account maar heeft een ongeldige tweede verificatiefactor opgegeven. further_actions_html: Als jij dit niet was, raden we je aan om onmiddellijk %{action} aangezien het in gevaar kan zijn. subject: Tweestapsverificatiefout title: Tweestapsverificatie mislukt suspicious_sign_in: change_password: je wachtwoord te wijzigen - details: 'Hier zijn de details van inlogpoging:' + details: 'Hier zijn de details van het inloggen:' explanation: We hebben vastgesteld dat iemand vanaf een nieuw IP-adres op jouw account is ingelogd. further_actions_html: Wanneer jij dit niet was, adviseren wij om onmiddellijk %{action} en om tweestapsverificatie in te schakelen, om zo je account veilig te houden. subject: Jouw account is vanaf een nieuw IP-adres benaderd diff --git a/config/locales/simple_form.id.yml b/config/locales/simple_form.id.yml index 856f312eda4765..1f493435e873c4 100644 --- a/config/locales/simple_form.id.yml +++ b/config/locales/simple_form.id.yml @@ -2,6 +2,9 @@ id: simple_form: hints: + account: + discoverable: Postingan dan profil publik Anda mungkin ditampilkan atau direkomendasikan di berbagai area Mastodon dan profil Anda mungkin disarankan ke pengguna lain. + display_name: Nama lengkap Anda atau nama lucu Anda. account_alias: acct: Tentukan namapengguna@domain akun yang ingin Anda pindah account_migration: diff --git a/config/locales/th.yml b/config/locales/th.yml index bafcd30dee6608..d1359e01768d96 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -1837,11 +1837,13 @@ th: edit_profile_title: ปรับแต่งโปรไฟล์ของคุณ explanation: นี่คือเคล็ดลับบางส่วนที่จะช่วยให้คุณเริ่มต้นใช้งาน feature_action: เรียนรู้เพิ่มเติม - feature_audience: Mastodon มีความพิเศษที่ให้คุณจัดการผู้รับสารของคุณได้โดยไม่มีตัวกลาง นอกจากนี้ การติดตั้ง Mastodon บนโครงสร้างพื้นฐานของคุณจะทำให้คุณสามารถติดตาม (และติดตามโดย) เซิร์ฟเวอร์ Mastodon แห่งไหนก็ได้ที่ทำงานอยู่ โดยไม่มีใครสามารถควบคุมได้นอกจากคุณ + feature_audience: Mastodon ให้ความเป็นไปได้ที่เป็นเอกลักษณ์แก่คุณในการจัดการผู้ชมของคุณโดยไม่มีตัวกลาง Mastodon ที่ปรับใช้ในโครงสร้างพื้นฐานของคุณเองอนุญาตให้คุณติดตามและได้รับการติดตามจากเซิร์ฟเวอร์ Mastodon อื่นใดทางออนไลน์และไม่อยู่ภายใต้การควบคุมของใครนอกจากคุณ feature_audience_title: สร้างผู้ชมของคุณด้วยความมั่นใจ feature_control: คุณทราบดีที่สุดถึงสิ่งที่คุณต้องการเห็นในฟีดหน้าแรกของคุณ ไม่มีอัลกอริทึมหรือโฆษณาให้เสียเวลาของคุณ ติดตามใครก็ตามทั่วทั้งเซิร์ฟเวอร์ Mastodon ใด ๆ จากบัญชีเดียวและรับโพสต์ของเขาตามลำดับเวลา และทำให้มุมอินเทอร์เน็ตของคุณเป็นเหมือนคุณมากขึ้นอีกนิด feature_control_title: การควบคุมเส้นเวลาของคุณเอง + feature_creativity: Mastodon รองรับโพสต์เสียง วิดีโอ และรูปภาพ, คำอธิบายการช่วยการเข้าถึง, การสำรวจความคิดเห็น, คำเตือนเนื้อหา, ภาพประจำตัวแบบเคลื่อนไหว, อีโมจิที่กำหนดเอง, การควบคุมการครอบตัดภาพขนาดย่อ และอื่น ๆ เพื่อช่วยให้คุณแสดงออกตัวคุณเองทางออนไลน์ ไม่ว่าคุณกำลังจะเผยแพร่ศิลปะของคุณ, เพลงของคุณ หรือพอดแคสต์ของคุณ Mastodon อยู่ที่นั่นเพื่อคุณ feature_creativity_title: ความคิดสร้างสรรค์ที่ไม่มีใครเทียบได้ + feature_moderation: Mastodon นำการตัดสินใจกลับมาอยู่ในมือของคุณ แต่ละเซิร์ฟเวอร์สร้างกฎและระเบียบข้อบังคับของตนเอง ซึ่งบังคับใช้ในเซิร์ฟเวอร์และไม่ใช่จากบนลงล่างเหมือนสื่อสังคมขององค์กร ทำให้สื่อสังคมยืดหยุ่นมากที่สุดในการตอบสนองต่อความต้องการของกลุ่มคนที่แตกต่างกัน เข้าร่วมเซิร์ฟเวอร์ที่มีกฎที่คุณเห็นด้วย หรือโฮสต์ของคุณเอง feature_moderation_title: การกลั่นกรองในแบบที่ควรจะเป็น follow_action: ติดตาม follow_step: การติดตามผู้คนที่น่าสนใจคือสิ่งที่ Mastodon ให้ความสำคัญ From f0f144e96da62718e849a8dd5cd55ddbc03763ab Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Mon, 10 Jun 2024 23:47:59 +0900 Subject: [PATCH 11/90] Add `customManagers:dockerfileVersions` to renovate.json5 (#30607) --- .github/renovate.json5 | 1 + Dockerfile | 2 ++ streaming/Dockerfile | 1 + 3 files changed, 4 insertions(+) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 52f7c63e5b82f1..2cf7bec8eebd21 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -2,6 +2,7 @@ $schema: 'https://docs.renovatebot.com/renovate-schema.json', extends: [ 'config:recommended', + 'customManagers:dockerfileVersions', ':labels(dependencies)', ':prConcurrentLimitNone', // Remove limit for open PRs at any time. ':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour. diff --git a/Dockerfile b/Dockerfile index 09aa8f2ddbc190..cb5b8720592df4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,8 +11,10 @@ ARG TARGETPLATFORM=${TARGETPLATFORM} ARG BUILDPLATFORM=${BUILDPLATFORM} # Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"] +# renovate: datasource=docker depName=docker.io/ruby ARG RUBY_VERSION="3.3.2" # # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] +# renovate: datasource=node-version depName=node ARG NODE_MAJOR_VERSION="20" # Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"] ARG DEBIAN_VERSION="bookworm" diff --git a/streaming/Dockerfile b/streaming/Dockerfile index 7f373e9cd5aa61..564e717a402d4e 100644 --- a/streaming/Dockerfile +++ b/streaming/Dockerfile @@ -8,6 +8,7 @@ ARG TARGETPLATFORM=${TARGETPLATFORM} ARG BUILDPLATFORM=${BUILDPLATFORM} # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] +# renovate: datasource=node-version depName=node ARG NODE_MAJOR_VERSION="20" # Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"] ARG DEBIAN_VERSION="bookworm" From 28f9a8f2ecabb0c087e27522217b78da732611c2 Mon Sep 17 00:00:00 2001 From: Daniel M Brasil Date: Mon, 10 Jun 2024 11:52:33 -0300 Subject: [PATCH 12/90] Add Specs for Scheduled Status Model Validations (#30585) --- spec/models/scheduled_status_spec.rb | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 spec/models/scheduled_status_spec.rb diff --git a/spec/models/scheduled_status_spec.rb b/spec/models/scheduled_status_spec.rb new file mode 100644 index 00000000000000..15031a589520f6 --- /dev/null +++ b/spec/models/scheduled_status_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe ScheduledStatus do + let(:account) { Fabricate(:account) } + + describe 'validations' do + context 'when scheduled_at is less than minimum offset' do + subject { Fabricate.build(:scheduled_status, scheduled_at: 4.minutes.from_now, account: account) } + + it 'is not valid', :aggregate_failures do + expect(subject).to_not be_valid + expect(subject.errors[:scheduled_at]).to include(I18n.t('scheduled_statuses.too_soon')) + end + end + + context 'when account has reached total limit' do + subject { Fabricate.build(:scheduled_status, account: account) } + + before do + allow(account.scheduled_statuses).to receive(:count).and_return(described_class::TOTAL_LIMIT) + end + + it 'is not valid', :aggregate_failures do + expect(subject).to_not be_valid + expect(subject.errors[:base]).to include(I18n.t('scheduled_statuses.over_total_limit', limit: ScheduledStatus::TOTAL_LIMIT)) + end + end + + context 'when account has reached daily limit' do + subject { Fabricate.build(:scheduled_status, account: account, scheduled_at: base_time + 10.minutes) } + + let(:base_time) { Time.current.change(hour: 12) } + + before do + stub_const('ScheduledStatus::DAILY_LIMIT', 3) + + travel_to base_time do + Fabricate.times(ScheduledStatus::DAILY_LIMIT, :scheduled_status, account: account, scheduled_at: base_time + 1.hour) + end + end + + it 'is not valid', :aggregate_failures do + expect(subject).to_not be_valid + expect(subject.errors[:base]).to include(I18n.t('scheduled_statuses.over_daily_limit', limit: ScheduledStatus::DAILY_LIMIT)) + end + end + end +end From 92b3004bf31d91c94efae4957234a36aef10da59 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 10 Jun 2024 11:03:41 -0400 Subject: [PATCH 13/90] Reference constants from account validation specs (#30634) --- spec/models/account_spec.rb | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 2c5df198d97f88..225929ae39f9a6 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -768,20 +768,20 @@ expect(account).to model_have_error_on_field(:username) end - it 'is invalid if the username is longer than 30 characters' do - account = Fabricate.build(:account, username: Faker::Lorem.characters(number: 31)) + it 'is invalid if the username is longer than the character limit' do + account = Fabricate.build(:account, username: username_over_limit) account.valid? expect(account).to model_have_error_on_field(:username) end - it 'is invalid if the display name is longer than 30 characters' do - account = Fabricate.build(:account, display_name: Faker::Lorem.characters(number: 31)) + it 'is invalid if the display name is longer than the character limit' do + account = Fabricate.build(:account, display_name: username_over_limit) account.valid? expect(account).to model_have_error_on_field(:display_name) end - it 'is invalid if the note is longer than 500 characters' do - account = Fabricate.build(:account, note: Faker::Lorem.characters(number: 501)) + it 'is invalid if the note is longer than the character limit' do + account = Fabricate.build(:account, note: account_note_over_limit) account.valid? expect(account).to model_have_error_on_field(:note) end @@ -814,24 +814,32 @@ expect(account).to model_have_error_on_field(:username) end - it 'is valid even if the username is longer than 30 characters' do - account = Fabricate.build(:account, domain: 'domain', username: Faker::Lorem.characters(number: 31)) + it 'is valid even if the username is longer than the character limit' do + account = Fabricate.build(:account, domain: 'domain', username: username_over_limit) account.valid? expect(account).to_not model_have_error_on_field(:username) end - it 'is valid even if the display name is longer than 30 characters' do - account = Fabricate.build(:account, domain: 'domain', display_name: Faker::Lorem.characters(number: 31)) + it 'is valid even if the display name is longer than the character limit' do + account = Fabricate.build(:account, domain: 'domain', display_name: username_over_limit) account.valid? expect(account).to_not model_have_error_on_field(:display_name) end - it 'is valid even if the note is longer than 500 characters' do - account = Fabricate.build(:account, domain: 'domain', note: Faker::Lorem.characters(number: 501)) + it 'is valid even if the note is longer than the character limit' do + account = Fabricate.build(:account, domain: 'domain', note: account_note_over_limit) account.valid? expect(account).to_not model_have_error_on_field(:note) end end + + def username_over_limit + 'a' * described_class::USERNAME_LENGTH_LIMIT * 2 + end + + def account_note_over_limit + 'a' * described_class::NOTE_LENGTH_LIMIT * 2 + end end describe 'scopes' do From 3e3f3d75805ec4209e0b12984626a5be0a9ba2e5 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 10 Jun 2024 11:04:01 -0400 Subject: [PATCH 14/90] Match report validation spec to extracted constant (#30633) --- spec/models/report_spec.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index 0168268bcb7723..d01d37bd8bba0e 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -123,14 +123,14 @@ describe 'validations' do let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') } - it 'is invalid if comment is longer than 1000 characters only if reporter is local' do - report = Fabricate.build(:report, comment: Faker::Lorem.characters(number: 1001)) + it 'is invalid if comment is longer than character limit and reporter is local' do + report = Fabricate.build(:report, comment: comment_over_limit) expect(report.valid?).to be false expect(report).to model_have_error_on_field(:comment) end - it 'is valid if comment is longer than 1000 characters and reporter is not local' do - report = Fabricate.build(:report, account: remote_account, comment: Faker::Lorem.characters(number: 1001)) + it 'is valid if comment is longer than character limit and reporter is not local' do + report = Fabricate.build(:report, account: remote_account, comment: comment_over_limit) expect(report.valid?).to be true end @@ -146,5 +146,9 @@ expect(report.valid?).to be false expect(report).to model_have_error_on_field(:rule_ids) end + + def comment_over_limit + 'a' * described_class::COMMENT_SIZE_LIMIT * 2 + end end end From 28921a12fe0033c7231f42e95a2be80628844bb4 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 10 Jun 2024 11:22:26 -0400 Subject: [PATCH 15/90] Update macOS local dev setup instructions (#30641) --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f807120c1eddf3..4aca37673b8ef7 100644 --- a/README.md +++ b/README.md @@ -86,18 +86,18 @@ A **Vagrant** configuration is included for development purposes. To use it, com - Run `vagrant ssh -c "cd /vagrant && bin/dev"` - Open `http://mastodon.local` in your browser -### MacOS +### macOS -To set up **MacOS** for native development, complete the following steps: +To set up **macOS** for native development, complete the following steps: -- Use a Ruby version manager to install the specified version from `.ruby-version` -- Run `bundle` to install required gems -- Run `brew install postgresql@14 redis imagemagick libidn` to install required dependencies -- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from `.nvmrc` -- Run `yarn` to install required packages -- Run `corepack enable && corepack prepare` -- Run `RAILS_ENV=development bundle exec rails db:setup` -- Finally, run `bin/dev` which will launch the local services via `overmind` (if installed) or `foreman` +- Install [Homebrew] and run `brew install postgresql@14 redis imagemagick +libidn nvm` to install the required project dependencies +- Use a Ruby version manager to activate the ruby in `.ruby-version` and run + `nvm use` to activate the node version from `.nvmrc` +- Run the `bin/setup` script, which will install the required ruby gems and node + packages and prepare the database for local development +- Finally, run the `bin/dev` script which will launch services via `overmind` + (if installed) or `foreman` ### Docker @@ -155,3 +155,4 @@ You should have received a copy of the GNU Affero General Public License along w [Development Containers]: https://containers.dev/supporting [Docker]: https://docs.docker.com [GitHub Codespaces]: https://docs.github.com/en/codespaces +[Homebrew]: https://brew.sh From 9bf2e2eda0ffea6382e161f7ebb43d73aaf658ca Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 10 Jun 2024 11:23:17 -0400 Subject: [PATCH 16/90] Extract `TEXT_LENGTH_LIMIT` constant in `Appeal` class (#30638) --- app/models/appeal.rb | 4 +++- spec/models/appeal_spec.rb | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/models/appeal.rb b/app/models/appeal.rb index 395056b76f5347..fafa75e69d8830 100644 --- a/app/models/appeal.rb +++ b/app/models/appeal.rb @@ -18,6 +18,8 @@ class Appeal < ApplicationRecord MAX_STRIKE_AGE = 20.days + TEXT_LENGTH_LIMIT = 2_000 + belongs_to :account belongs_to :strike, class_name: 'AccountWarning', foreign_key: 'account_warning_id', inverse_of: :appeal @@ -26,7 +28,7 @@ class Appeal < ApplicationRecord belongs_to :rejected_by_account end - validates :text, presence: true, length: { maximum: 2_000 } + validates :text, presence: true, length: { maximum: TEXT_LENGTH_LIMIT } validates :account_warning_id, uniqueness: true validate :validate_time_frame, on: :create diff --git a/spec/models/appeal_spec.rb b/spec/models/appeal_spec.rb index 12373a9494e75a..13ca3a2d901ae5 100644 --- a/spec/models/appeal_spec.rb +++ b/spec/models/appeal_spec.rb @@ -3,6 +3,19 @@ require 'rails_helper' describe Appeal do + describe 'Validations' do + it 'validates text length is under limit' do + appeal = Fabricate.build( + :appeal, + strike: Fabricate(:account_warning), + text: 'a' * described_class::TEXT_LENGTH_LIMIT * 2 + ) + + expect(appeal).to_not be_valid + expect(appeal).to model_have_error_on_field(:text) + end + end + describe 'scopes' do describe 'approved' do let(:approved_appeal) { Fabricate(:appeal, approved_at: 10.days.ago) } From 9cc4040308a758d4b77961f4da79cf63a044fffe Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 10 Jun 2024 11:23:55 -0400 Subject: [PATCH 17/90] Extract `COMMENT_SIZE_LIMIT` constant in `AP::Activity::Flag` class (#30637) --- app/lib/activitypub/activity/flag.rb | 4 +++- spec/lib/activitypub/activity/flag_spec.rb | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/lib/activitypub/activity/flag.rb b/app/lib/activitypub/activity/flag.rb index 68ee43d0ebf7c1..b7a412485c07e7 100644 --- a/app/lib/activitypub/activity/flag.rb +++ b/app/lib/activitypub/activity/flag.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class ActivityPub::Activity::Flag < ActivityPub::Activity + COMMENT_SIZE_LIMIT = 5000 + def perform return if skip_reports? @@ -38,6 +40,6 @@ def report_uri end def report_comment - (@json['content'] || '')[0...5000] + (@json['content'] || '')[0...COMMENT_SIZE_LIMIT] end end diff --git a/spec/lib/activitypub/activity/flag_spec.rb b/spec/lib/activitypub/activity/flag_spec.rb index 8593d567f42616..426cd97df9acf3 100644 --- a/spec/lib/activitypub/activity/flag_spec.rb +++ b/spec/lib/activitypub/activity/flag_spec.rb @@ -54,7 +54,7 @@ }.with_indifferent_access, sender) end - let(:long_comment) { Faker::Lorem.characters(number: 6000) } + let(:long_comment) { 'a' * described_class::COMMENT_SIZE_LIMIT * 2 } before do subject.perform @@ -63,10 +63,12 @@ it 'creates a report but with a truncated comment' do report = Report.find_by(account: sender, target_account: flagged) - expect(report).to_not be_nil - expect(report.comment.length).to eq 5000 - expect(report.comment).to eq long_comment[0...5000] - expect(report.status_ids).to eq [status.id] + expect(report) + .to be_present + .and have_attributes(status_ids: [status.id]) + expect(report.comment) + .to have_attributes(length: described_class::COMMENT_SIZE_LIMIT) + .and eq(long_comment[0...described_class::COMMENT_SIZE_LIMIT]) end end From 0e1110c947caf31ae650c73ef35adedebc16b28a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 10 Jun 2024 16:08:04 -0400 Subject: [PATCH 18/90] Use `SECRET_KEY_BASE_DUMMY` feature as placeholder during asset compilation (#30505) --- .github/workflows/test-ruby.yml | 6 +----- Dockerfile | 6 +----- config/environments/production.rb | 6 +++++- config/initializers/active_record_encryption.rb | 5 +++++ 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index 5f2297381a7328..8f05dcab3ec59f 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -28,11 +28,7 @@ jobs: env: RAILS_ENV: ${{ matrix.mode }} BUNDLE_WITH: ${{ matrix.mode }} - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY: precompile_placeholder - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT: precompile_placeholder - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY: precompile_placeholder - OTP_SECRET: precompile_placeholder - SECRET_KEY_BASE: precompile_placeholder + SECRET_KEY_BASE_DUMMY: 1 steps: - uses: actions/checkout@v4 diff --git a/Dockerfile b/Dockerfile index cb5b8720592df4..2dc7602b2d23d2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -212,11 +212,7 @@ ARG TARGETPLATFORM RUN \ # Use Ruby on Rails to create Mastodon assets - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=precompile_placeholder \ - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=precompile_placeholder \ - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=precompile_placeholder \ - OTP_SECRET=precompile_placeholder \ - SECRET_KEY_BASE=precompile_placeholder \ + SECRET_KEY_BASE_DUMMY=1 \ bundle exec rails assets:precompile; \ # Cleanup temporary files rm -fr /opt/mastodon/tmp; diff --git a/config/environments/production.rb b/config/environments/production.rb index a39843e9562d1f..6686a23d60da91 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -156,7 +156,11 @@ } # TODO: Remove once devise-two-factor data migration complete - config.x.otp_secret = ENV.fetch('OTP_SECRET') + config.x.otp_secret = if ENV['SECRET_KEY_BASE_DUMMY'] + SecureRandom.hex(64) + else + ENV.fetch('OTP_SECRET') + end # Enable DNS rebinding protection and other `Host` header attacks. # config.hosts = [ diff --git a/config/initializers/active_record_encryption.rb b/config/initializers/active_record_encryption.rb index 900f3c68f0d527..a83ca807657711 100644 --- a/config/initializers/active_record_encryption.rb +++ b/config/initializers/active_record_encryption.rb @@ -5,6 +5,11 @@ ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY ).each do |key| + if ENV['SECRET_KEY_BASE_DUMMY'] + # Use placeholder value during production env asset compilation + ENV[key] = SecureRandom.hex(64) + end + value = ENV.fetch(key) do abort <<~MESSAGE From ef23abcf617813901e34c5dd9587ef7c88fd754d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 08:55:30 +0200 Subject: [PATCH 19/90] chore(deps): update dependency aws-sdk-s3 to v1.152.1 (#30643) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4d16fea47cb973..984bc32d49b7ed 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,7 +109,7 @@ GEM aws-sdk-kms (1.83.0) aws-sdk-core (~> 3, >= 3.197.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.152.0) + aws-sdk-s3 (1.152.1) aws-sdk-core (~> 3, >= 3.197.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) From cfd4823b65cc91e758ac9d6d97e367b19ca35691 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 02:57:09 -0400 Subject: [PATCH 20/90] Use fabricator in follow_spec (#30642) --- spec/models/follow_spec.rb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index c7743183cc612b..9aa172b2f21cfc 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -36,16 +36,15 @@ end end - describe 'recent' do - it 'sorts so that more recent follows comes earlier' do - follow0 = described_class.create!(account: alice, target_account: bob) - follow1 = described_class.create!(account: bob, target_account: alice) + describe '.recent' do + let!(:follow_earlier) { Fabricate(:follow) } + let!(:follow_later) { Fabricate(:follow) } - a = described_class.recent.to_a + it 'sorts with most recent follows first' do + results = described_class.recent - expect(a.size).to eq 2 - expect(a[0]).to eq follow1 - expect(a[1]).to eq follow0 + expect(results.size).to eq 2 + expect(results).to eq [follow_later, follow_earlier] end end From 0dabda9beec11706fbef8cbf8a141266cc69590c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:14:52 +0200 Subject: [PATCH 21/90] New Crowdin Translations (automated) (#30646) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ar.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 68e32dd2aab6e7..6d67d354b63e32 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -225,7 +225,11 @@ "domain_pill.their_username": "مُعرّفُهم الفريد على الخادم. من الممكن العثور على مستخدمين بنفس اسم المستخدم على خوادم مختلفة.", "domain_pill.username": "اسم المستخدم", "domain_pill.whats_in_a_handle": "ما المقصود بالمُعرِّف؟", + "domain_pill.who_they_are": "بما أن المعالجات تقول من هو الشخص ومكان وجوده، يمكنك التفاعل مع الناس عبر الشبكة الاجتماعية لـ .", + "domain_pill.who_you_are": "لأن معالجتك تقول من أنت ومكان وجودك، يمكن الناس التفاعل معك عبر الشبكة الاجتماعية لـ .", "domain_pill.your_handle": "عنوانك الكامل:", + "domain_pill.your_server": "منزلك الرقمي، حيث تعيش جميع مشاركاتك. لا تحب هذا؟ إنقل الخوادم في أي وقت واخضر متابعينك أيضًا.", + "domain_pill.your_username": "معرفك الفريد على هذا الخادم. من الممكن العثور على مستخدمين بنفس إسم المستخدم على خوادم مختلفة.", "embed.instructions": "يمكنكم إدماج هذا المنشور على موقعكم الإلكتروني عن طريق نسخ الشفرة أدناه.", "embed.preview": "إليك ما سيبدو عليه:", "emoji_button.activity": "الأنشطة", @@ -262,6 +266,7 @@ "empty_column.list": "هذه القائمة فارغة مؤقتا و لكن سوف تمتلئ تدريجيا عندما يبدأ الأعضاء المُنتَمين إليها بنشر منشورات.", "empty_column.lists": "ليس عندك أية قائمة بعد. سوف تظهر قوائمك هنا إن قمت بإنشاء واحدة.", "empty_column.mutes": "لم تقم بكتم أي مستخدم بعد.", + "empty_column.notification_requests": "لا يوجد شيء هنا. عندما تتلقى إشعارات جديدة، سوف تظهر هنا وفقًا لإعداداتك.", "empty_column.notifications": "لم تتلق أي إشعار بعدُ. تفاعل مع المستخدمين الآخرين لإنشاء محادثة.", "empty_column.public": "لا يوجد أي شيء هنا! قم بنشر شيء ما للعامة، أو اتبع المستخدمين الآخرين المتواجدين على الخوادم الأخرى لملء خيط المحادثات", "error.unexpected_crash.explanation": "نظرا لوجود خطأ في التعليمات البرمجية أو مشكلة توافق مع المتصفّح، تعذر عرض هذه الصفحة بشكل صحيح.", @@ -292,6 +297,8 @@ "filter_modal.select_filter.subtitle": "استخدم فئة موجودة أو قم بإنشاء فئة جديدة", "filter_modal.select_filter.title": "تصفية هذا المنشور", "filter_modal.title.status": "تصفية منشور", + "filtered_notifications_banner.mentions": "{count, plural, one {إشارة} two {إشارتين} few {# إشارات} other {# إشارة}}", + "filtered_notifications_banner.pending_requests": "إشعارات من {count, plural, zero {}=0 {لا أحد} one {شخص واحد قد تعرفه} two {شخصين قد تعرفهما} few {# أشخاص قد تعرفهم} many {# شخص قد تعرفهم} other {# شخص قد تعرفهم}}", "filtered_notifications_banner.title": "الإشعارات المصفاة", "firehose.all": "الكل", "firehose.local": "هذا الخادم", @@ -301,6 +308,8 @@ "follow_requests.unlocked_explanation": "حتى وإن كان حسابك غير مقفل، يعتقد فريق {domain} أنك قد ترغب في مراجعة طلبات المتابعة من هذه الحسابات يدوياً.", "follow_suggestions.curated_suggestion": "اختيار الموظفين", "follow_suggestions.dismiss": "لا تُظهرها مجدّدًا", + "follow_suggestions.featured_longer": "مختار يدوياً من قِبل فريق {domain}", + "follow_suggestions.friends_of_friends_longer": "مشهور بين الأشخاص الذين تتابعهم", "follow_suggestions.hints.featured": "تم اختيار هذا الملف الشخصي يدوياً من قبل فريق {domain}.", "follow_suggestions.hints.friends_of_friends": "هذا الملف الشخصي مشهور بين الأشخاص الذين تتابعهم.", "follow_suggestions.hints.most_followed": "هذا الملف الشخصي هو واحد من الأكثر متابعة على {domain}.", @@ -405,6 +414,7 @@ "limited_account_hint.action": "إظهار الملف التعريفي على أي حال", "limited_account_hint.title": "تم إخفاء هذا الملف الشخصي من قبل مشرفي {domain}.", "link_preview.author": "مِن {name}", + "link_preview.more_from_author": "المزيد من {name}", "lists.account.add": "أضف إلى القائمة", "lists.account.remove": "احذف من القائمة", "lists.delete": "احذف القائمة", @@ -465,10 +475,13 @@ "notification.follow_request": "لقد طلب {name} متابعتك", "notification.mention": "{name} ذكرك", "notification.moderation-warning.learn_more": "اعرف المزيد", + "notification.moderation_warning": "لقد تلقيت تحذيرًا بالإشراف", + "notification.moderation_warning.action_delete_statuses": "تم إزالة بعض مشاركاتك.", "notification.moderation_warning.action_disable": "تم تعطيل حسابك.", "notification.moderation_warning.action_mark_statuses_as_sensitive": "بعض من منشوراتك تم تصنيفها على أنها حساسة.", "notification.moderation_warning.action_none": "لقد تلقى حسابك تحذيرا بالإشراف.", "notification.moderation_warning.action_sensitive": "سيتم وضع علامة على منشوراتك على أنها حساسة من الآن فصاعدا.", + "notification.moderation_warning.action_silence": "لقد تم تقييد حسابك.", "notification.moderation_warning.action_suspend": "لقد تم تعليق حسابك.", "notification.own_poll": "انتهى استطلاعك للرأي", "notification.poll": "لقد انتهى استطلاع رأي شاركتَ فيه", From b2496177e00af2b9ce73b378233b2ef3de14cbe4 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 03:35:30 -0400 Subject: [PATCH 22/90] Use correct params in `v1/admin/domain_allows` spec (#30378) --- spec/requests/api/v1/admin/domain_allows_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/requests/api/v1/admin/domain_allows_spec.rb b/spec/requests/api/v1/admin/domain_allows_spec.rb index 662a8f9a8d629b..b8f0b0055c84fc 100644 --- a/spec/requests/api/v1/admin/domain_allows_spec.rb +++ b/spec/requests/api/v1/admin/domain_allows_spec.rb @@ -113,7 +113,7 @@ end context 'with invalid domain name' do - let(:params) { 'foo bar' } + let(:params) { { domain: 'foo bar' } } it 'returns http unprocessable entity' do subject From edf6d64eebdf4c1651f09c0e314d46b7436b46df Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 03:36:46 -0400 Subject: [PATCH 23/90] Use correct params in `settings/preferences/appearance` spec (#30379) --- .../settings/preferences/appearance_controller_spec.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/spec/controllers/settings/preferences/appearance_controller_spec.rb b/spec/controllers/settings/preferences/appearance_controller_spec.rb index 261c426acbdb15..84b82772502fec 100644 --- a/spec/controllers/settings/preferences/appearance_controller_spec.rb +++ b/spec/controllers/settings/preferences/appearance_controller_spec.rb @@ -23,8 +23,11 @@ end describe 'PUT #update' do + subject { put :update, params: { user: { settings_attributes: { theme: 'contrast' } } } } + it 'redirects correctly' do - put :update, params: { user: { setting_theme: 'contrast' } } + expect { subject } + .to change { user.reload.settings.theme }.to('contrast') expect(response).to redirect_to(settings_preferences_appearance_path) end From 88cfc4056de1f7ab86011eb80b904cd9cd6dc754 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 03:42:15 -0400 Subject: [PATCH 24/90] Extract method to generate series of days in measure sql classes (#29928) --- .../admin/metrics/measure/instance_accounts_measure.rb | 2 +- .../admin/metrics/measure/instance_followers_measure.rb | 2 +- app/lib/admin/metrics/measure/instance_follows_measure.rb | 2 +- .../metrics/measure/instance_media_attachments_measure.rb | 2 +- app/lib/admin/metrics/measure/instance_reports_measure.rb | 2 +- .../admin/metrics/measure/instance_statuses_measure.rb | 2 +- app/lib/admin/metrics/measure/new_users_measure.rb | 2 +- app/lib/admin/metrics/measure/opened_reports_measure.rb | 2 +- app/lib/admin/metrics/measure/query_helper.rb | 8 ++++++++ app/lib/admin/metrics/measure/resolved_reports_measure.rb | 2 +- app/lib/admin/metrics/measure/tag_servers_measure.rb | 2 +- 11 files changed, 18 insertions(+), 10 deletions(-) diff --git a/app/lib/admin/metrics/measure/instance_accounts_measure.rb b/app/lib/admin/metrics/measure/instance_accounts_measure.rb index 3d081fdd909fc2..746780ee7719e3 100644 --- a/app/lib/admin/metrics/measure/instance_accounts_measure.rb +++ b/app/lib/admin/metrics/measure/instance_accounts_measure.rb @@ -43,7 +43,7 @@ def sql_query_string SELECT count(*) FROM new_accounts ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/instance_followers_measure.rb b/app/lib/admin/metrics/measure/instance_followers_measure.rb index 378c6754d9230d..0693d5a64a91d2 100644 --- a/app/lib/admin/metrics/measure/instance_followers_measure.rb +++ b/app/lib/admin/metrics/measure/instance_followers_measure.rb @@ -44,7 +44,7 @@ def sql_query_string SELECT count(*) FROM new_followers ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/instance_follows_measure.rb b/app/lib/admin/metrics/measure/instance_follows_measure.rb index e213348fbc7195..90d38193585c8d 100644 --- a/app/lib/admin/metrics/measure/instance_follows_measure.rb +++ b/app/lib/admin/metrics/measure/instance_follows_measure.rb @@ -44,7 +44,7 @@ def sql_query_string SELECT count(*) FROM new_follows ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb b/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb index 1d2dbbe4146a86..89f8b414973b83 100644 --- a/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb +++ b/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb @@ -53,7 +53,7 @@ def sql_query_string SELECT COALESCE(SUM(size), 0) FROM new_media_attachments ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/instance_reports_measure.rb b/app/lib/admin/metrics/measure/instance_reports_measure.rb index 9da3d53e348a3d..5f58387a640ae0 100644 --- a/app/lib/admin/metrics/measure/instance_reports_measure.rb +++ b/app/lib/admin/metrics/measure/instance_reports_measure.rb @@ -44,7 +44,7 @@ def sql_query_string SELECT count(*) FROM new_reports ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/instance_statuses_measure.rb b/app/lib/admin/metrics/measure/instance_statuses_measure.rb index b918a30a57cc09..5873c6e71fcee3 100644 --- a/app/lib/admin/metrics/measure/instance_statuses_measure.rb +++ b/app/lib/admin/metrics/measure/instance_statuses_measure.rb @@ -45,7 +45,7 @@ def sql_query_string SELECT count(*) FROM new_statuses ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/new_users_measure.rb b/app/lib/admin/metrics/measure/new_users_measure.rb index 6837c14c82cf62..32057154d6b5f7 100644 --- a/app/lib/admin/metrics/measure/new_users_measure.rb +++ b/app/lib/admin/metrics/measure/new_users_measure.rb @@ -32,7 +32,7 @@ def sql_query_string SELECT count(*) FROM new_users ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/opened_reports_measure.rb b/app/lib/admin/metrics/measure/opened_reports_measure.rb index c395c4634118f4..47de38bbe648b6 100644 --- a/app/lib/admin/metrics/measure/opened_reports_measure.rb +++ b/app/lib/admin/metrics/measure/opened_reports_measure.rb @@ -32,7 +32,7 @@ def sql_query_string SELECT count(*) FROM new_reports ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/query_helper.rb b/app/lib/admin/metrics/measure/query_helper.rb index 969065f73f15a6..5969a96ba9f17e 100644 --- a/app/lib/admin/metrics/measure/query_helper.rb +++ b/app/lib/admin/metrics/measure/query_helper.rb @@ -15,6 +15,14 @@ def sanitized_sql_string ActiveRecord::Base.sanitize_sql_array(sql_array) end + def generated_series_days + Arel.sql( + <<~SQL.squish + SELECT generate_series(timestamp :start_at, :end_at, '1 day')::date AS period + SQL + ) + end + def account_domain_sql(include_subdomains) if include_subdomains "accounts.domain IN (SELECT domain FROM instances WHERE reverse('.' || domain) LIKE reverse('.' || :domain::text))" diff --git a/app/lib/admin/metrics/measure/resolved_reports_measure.rb b/app/lib/admin/metrics/measure/resolved_reports_measure.rb index 780db75a10d4d9..ecfd779c86a9df 100644 --- a/app/lib/admin/metrics/measure/resolved_reports_measure.rb +++ b/app/lib/admin/metrics/measure/resolved_reports_measure.rb @@ -32,7 +32,7 @@ def sql_query_string SELECT count(*) FROM resolved_reports ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/tag_servers_measure.rb b/app/lib/admin/metrics/measure/tag_servers_measure.rb index f273d739d04aaa..5db1076062b735 100644 --- a/app/lib/admin/metrics/measure/tag_servers_measure.rb +++ b/app/lib/admin/metrics/measure/tag_servers_measure.rb @@ -40,7 +40,7 @@ def sql_query_string SELECT COUNT(*) FROM tag_servers ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) as axis SQL end From 1622f7aeb9e911d43296caef45e17181652c9c0e Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 03:48:42 -0400 Subject: [PATCH 25/90] Remove duplicate fabricator validity checks (#29667) --- spec/models/import_spec.rb | 5 ----- spec/models/poll_spec.rb | 8 -------- 2 files changed, 13 deletions(-) diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index 3605f0b9bf8d21..10df5f8c0b2a31 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -8,11 +8,6 @@ let(:data) { attachment_fixture('imports.txt') } describe 'validations' do - it 'has a valid parameters' do - import = described_class.create(account: account, type: type, data: data) - expect(import).to be_valid - end - it 'is invalid without an type' do import = described_class.create(account: account, data: data) expect(import).to model_have_error_on_field(:type) diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb index 5aa5548cc83a1f..ebcc459078b88c 100644 --- a/spec/models/poll_spec.rb +++ b/spec/models/poll_spec.rb @@ -31,14 +31,6 @@ end describe 'validations' do - context 'when valid' do - let(:poll) { Fabricate.build(:poll) } - - it 'is valid with valid attributes' do - expect(poll).to be_valid - end - end - context 'when not valid' do let(:poll) { Fabricate.build(:poll, expires_at: nil) } From 665f6f09a07fa9d1d813e8343f1687b369e7f3dc Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 04:50:51 -0400 Subject: [PATCH 26/90] Add expired/revoked scopes for doorkeeper models via extension modules (#29936) --- app/lib/access_grant_extension.rb | 10 ++++++++++ app/lib/access_token_extension.rb | 4 ++++ app/lib/vacuum/access_tokens_vacuum.rb | 8 ++++---- app/models/web/push_subscription.rb | 2 +- config/application.rb | 1 + 5 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 app/lib/access_grant_extension.rb diff --git a/app/lib/access_grant_extension.rb b/app/lib/access_grant_extension.rb new file mode 100644 index 00000000000000..bf8f5ae25ae949 --- /dev/null +++ b/app/lib/access_grant_extension.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module AccessGrantExtension + extend ActiveSupport::Concern + + included do + scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') } + scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) } + end +end diff --git a/app/lib/access_token_extension.rb b/app/lib/access_token_extension.rb index 4e9585dd1e6583..6e06f988a5e3db 100644 --- a/app/lib/access_token_extension.rb +++ b/app/lib/access_token_extension.rb @@ -9,6 +9,10 @@ module AccessTokenExtension has_many :web_push_subscriptions, class_name: 'Web::PushSubscription', inverse_of: :access_token after_commit :push_to_streaming_api + + scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') } + scope :not_revoked, -> { where(revoked_at: nil) } + scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) } end def revoke(clock = Time) diff --git a/app/lib/vacuum/access_tokens_vacuum.rb b/app/lib/vacuum/access_tokens_vacuum.rb index a224f6d6380e58..281ae22bf04c30 100644 --- a/app/lib/vacuum/access_tokens_vacuum.rb +++ b/app/lib/vacuum/access_tokens_vacuum.rb @@ -9,12 +9,12 @@ def perform private def vacuum_revoked_access_tokens! - Doorkeeper::AccessToken.where.not(expires_in: nil).where('created_at + make_interval(secs => expires_in) < NOW()').in_batches.delete_all - Doorkeeper::AccessToken.where.not(revoked_at: nil).where('revoked_at < NOW()').in_batches.delete_all + Doorkeeper::AccessToken.expired.in_batches.delete_all + Doorkeeper::AccessToken.revoked.in_batches.delete_all end def vacuum_revoked_access_grants! - Doorkeeper::AccessGrant.where.not(expires_in: nil).where('created_at + make_interval(secs => expires_in) < NOW()').in_batches.delete_all - Doorkeeper::AccessGrant.where.not(revoked_at: nil).where('revoked_at < NOW()').in_batches.delete_all + Doorkeeper::AccessGrant.expired.in_batches.delete_all + Doorkeeper::AccessGrant.revoked.in_batches.delete_all end end diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb index b482ad3afe25c7..ddfd08146e76ae 100644 --- a/app/models/web/push_subscription.rb +++ b/app/models/web/push_subscription.rb @@ -75,7 +75,7 @@ def associated_access_token class << self def unsubscribe_for(application_id, resource_owner) - access_token_ids = Doorkeeper::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id, revoked_at: nil).pluck(:id) + access_token_ids = Doorkeeper::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id).not_revoked.pluck(:id) where(access_token_id: access_token_ids).delete_all end end diff --git a/config/application.rb b/config/application.rb index b3a9b99ff5b266..65407da05c91a6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -115,6 +115,7 @@ class Application < Rails::Application Doorkeeper::AuthorizationsController.layout 'modal' Doorkeeper::AuthorizedApplicationsController.layout 'admin' Doorkeeper::Application.include ApplicationExtension + Doorkeeper::AccessGrant.include AccessGrantExtension Doorkeeper::AccessToken.include AccessTokenExtension Devise::FailureApp.include AbstractController::Callbacks Devise::FailureApp.include Localized From 410370eecdcc6ad7aeac30c48957d3b044e7cabe Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 05:40:47 -0400 Subject: [PATCH 27/90] Extract `PERMITTED_PARAMS` constant from `admin/domain_blocks` controller (#30380) --- .../admin/domain_blocks_controller.rb | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 325b33df80be66..16a8cb9eeae715 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -4,6 +4,18 @@ module Admin class DomainBlocksController < BaseController before_action :set_domain_block, only: [:destroy, :edit, :update] + PERMITTED_PARAMS = %i( + domain + obfuscate + private_comment + public_comment + reject_media + reject_reports + severity + ).freeze + + PERMITTED_UPDATE_PARAMS = PERMITTED_PARAMS.without(:domain).freeze + def batch authorize :domain_block, :create? @form = Form::DomainBlockBatch.new(form_domain_block_batch_params.merge(current_account: current_account, action: action_from_button)) @@ -88,11 +100,17 @@ def set_domain_block end def update_params - params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) + params + .require(:domain_block) + .slice(*PERMITTED_UPDATE_PARAMS) + .permit(*PERMITTED_UPDATE_PARAMS) end def resource_params - params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) + params + .require(:domain_block) + .slice(*PERMITTED_PARAMS) + .permit(*PERMITTED_PARAMS) end def form_domain_block_batch_params From f48f39a7679667da51171a77a0e1bcbc7512cd36 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Tue, 11 Jun 2024 14:54:37 +0200 Subject: [PATCH 28/90] Fix cutoff of instance name (#30598) --- app/javascript/styles/mastodon/forms.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index f6ec44fb5380fa..26bb2bee1450ad 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -613,9 +613,10 @@ code { font-family: inherit; pointer-events: none; cursor: default; - max-width: 140px; + max-width: 50%; white-space: nowrap; overflow: hidden; + text-overflow: ellipsis; &::after { content: ''; From 328d3a87f5749b5b9ea2c17289fc7a53dbaa6d7b Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 11 Jun 2024 15:58:10 +0200 Subject: [PATCH 29/90] Fix libvips color extraction when multiple maxima differ only on blue component (#30632) --- lib/paperclip/color_extractor.rb | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/paperclip/color_extractor.rb b/lib/paperclip/color_extractor.rb index 0f168d233b2c14..378af0961de0d3 100644 --- a/lib/paperclip/color_extractor.rb +++ b/lib/paperclip/color_extractor.rb @@ -122,26 +122,28 @@ def palette_from_image(image) colors['out_array'].zip(colors['x_array'], colors['y_array']).map do |v, x, y| rgb_from_xyv(histogram, x, y, v) - end.reverse + end.flatten.reverse.uniq end # rubocop:disable Naming/MethodParameterName def rgb_from_xyv(image, x, y, v) pixel = image.getpoint(x, y) - # Unfortunately, we only have the first 2 dimensions, so try to - # guess the third one by looking up the value + # As we only have the first 2 dimensions for this maximum, we + # can't distinguish with different maxima with the same `r` and `g` + # values but different `b` values. + # + # Therefore, we return an array of maxima, which is always non-empty, + # but may contain multiple colors with the same values. - # NOTE: this means that if multiple bins with the same `r` and `g` - # components have the same number of occurrences, we will always return - # the one with the lowest `b` value. This means that in case of a tie, - # we will return the same color twice and skip the ones it tied with. - z = pixel.find_index(v) + pixel.filter_map.with_index do |pv, z| + next if pv != v - r = (x + 0.5) * 256 / BINS - g = (y + 0.5) * 256 / BINS - b = (z + 0.5) * 256 / BINS - ColorDiff::Color::RGB.new(r, g, b) + r = (x + 0.5) * 256 / BINS + g = (y + 0.5) * 256 / BINS + b = (z + 0.5) * 256 / BINS + ColorDiff::Color::RGB.new(r, g, b) + end end def w3c_contrast(color1, color2) From b124dff1748797e54256e1c8161d18513b921458 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:58:40 +0200 Subject: [PATCH 30/90] chore(deps): update opentelemetry-ruby (non-major) (#30648) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 984bc32d49b7ed..c2253fe19cf28b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -498,6 +498,10 @@ GEM opentelemetry-semantic_conventions opentelemetry-helpers-sql-obfuscation (0.1.0) opentelemetry-common (~> 0.20) + opentelemetry-instrumentation-action_mailer (0.1.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-active_support (~> 0.1) + opentelemetry-instrumentation-base (~> 0.22.1) opentelemetry-instrumentation-action_pack (0.9.0) opentelemetry-api (~> 1.0) opentelemetry-instrumentation-base (~> 0.22.1) @@ -551,8 +555,9 @@ GEM opentelemetry-api (~> 1.0) opentelemetry-common (~> 0.20.0) opentelemetry-instrumentation-base (~> 0.22.1) - opentelemetry-instrumentation-rails (0.30.1) + opentelemetry-instrumentation-rails (0.30.2) opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-action_mailer (~> 0.1.0) opentelemetry-instrumentation-action_pack (~> 0.9.0) opentelemetry-instrumentation-action_view (~> 0.7.0) opentelemetry-instrumentation-active_job (~> 0.7.0) From 62d070c438a2cccb6af486a02d8c6839d642c827 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 09:59:56 -0400 Subject: [PATCH 31/90] Check both before/after state in `AccountDomainBlock` spec (#30640) --- spec/models/account_domain_block_spec.rb | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/spec/models/account_domain_block_spec.rb b/spec/models/account_domain_block_spec.rb index 10bd579363c486..d994403b8e8cfb 100644 --- a/spec/models/account_domain_block_spec.rb +++ b/spec/models/account_domain_block_spec.rb @@ -3,22 +3,30 @@ require 'rails_helper' RSpec.describe AccountDomainBlock do + let(:account) { Fabricate(:account) } + it 'removes blocking cache after creation' do - account = Fabricate(:account) Rails.cache.write("exclude_domains_for:#{account.id}", 'a.domain.already.blocked') - described_class.create!(account: account, domain: 'a.domain.blocked.later') - - expect(Rails.cache.exist?("exclude_domains_for:#{account.id}")).to be false + expect { block_domain_for_account('a.domain.blocked.later') } + .to change { account_has_exclude_domains_cache? }.to(false) end it 'removes blocking cache after destruction' do - account = Fabricate(:account) - block = described_class.create!(account: account, domain: 'domain') + block = block_domain_for_account('domain') Rails.cache.write("exclude_domains_for:#{account.id}", 'domain') - block.destroy! + expect { block.destroy! } + .to change { account_has_exclude_domains_cache? }.to(false) + end + + private + + def block_domain_for_account(domain) + Fabricate(:account_domain_block, account: account, domain: domain) + end - expect(Rails.cache.exist?("exclude_domains_for:#{account.id}")).to be false + def account_has_exclude_domains_cache? + Rails.cache.exist?("exclude_domains_for:#{account.id}") end end From 978601a0ae556c4e214df8f6d73181c2a6359531 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 11:29:41 -0400 Subject: [PATCH 32/90] Extract permitted params constant in v1/admin/tags (#30652) --- app/controllers/api/v1/admin/tags_controller.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/admin/tags_controller.rb b/app/controllers/api/v1/admin/tags_controller.rb index 67d987d0e3d8a1..283383acb4ac46 100644 --- a/app/controllers/api/v1/admin/tags_controller.rb +++ b/app/controllers/api/v1/admin/tags_controller.rb @@ -13,6 +13,13 @@ class Api::V1::Admin::TagsController < Api::BaseController LIMIT = 100 + PERMITTED_PARAMS = %i( + display_name + listable + trendable + usable + ).freeze + def index authorize :tag, :index? render json: @tags, each_serializer: REST::Admin::TagSerializer @@ -40,7 +47,9 @@ def set_tags end def tag_params - params.permit(:display_name, :trendable, :usable, :listable) + params + .slice(*PERMITTED_PARAMS) + .permit(*PERMITTED_PARAMS) end def next_path From 921b0db5440cc6e0bc990d6f0186c43aaa887fe9 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 11 Jun 2024 17:29:45 +0200 Subject: [PATCH 33/90] Add `noindex` meta tag and `rel=canonical` link to redirect interstitials (#30651) --- app/views/redirects/show.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/redirects/show.html.haml b/app/views/redirects/show.html.haml index 0d09387a9c7fef..64436e05d14c43 100644 --- a/app/views/redirects/show.html.haml +++ b/app/views/redirects/show.html.haml @@ -1,3 +1,7 @@ +- content_for :header_tags do + %meta{ name: 'robots', content: 'noindex, noarchive' }/ + %link{ rel: 'canonical', href: @redirect_path } + .redirect .redirect__logo = link_to render_logo, root_path From d818ddd6870094e89e58ef61f37da4cb73935856 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 11:36:21 -0400 Subject: [PATCH 34/90] Extract `SIGN_COUNT_LIMIT` constant in `WebauthnCredential` class (#30636) --- app/models/webauthn_credential.rb | 4 +++- ...bauthn_credentials_spec.rb => webauthn_credential_spec.rb} | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) rename spec/models/{webauthn_credentials_spec.rb => webauthn_credential_spec.rb} (95%) diff --git a/app/models/webauthn_credential.rb b/app/models/webauthn_credential.rb index 4fa31ece520bc8..d7ed1b9d401d8e 100644 --- a/app/models/webauthn_credential.rb +++ b/app/models/webauthn_credential.rb @@ -15,9 +15,11 @@ # class WebauthnCredential < ApplicationRecord + SIGN_COUNT_LIMIT = (2**63) + validates :external_id, :public_key, :nickname, :sign_count, presence: true validates :external_id, uniqueness: true validates :nickname, uniqueness: { scope: :user_id } validates :sign_count, - numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: (2**63) - 1 } + numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: SIGN_COUNT_LIMIT - 1 } end diff --git a/spec/models/webauthn_credentials_spec.rb b/spec/models/webauthn_credential_spec.rb similarity index 95% rename from spec/models/webauthn_credentials_spec.rb rename to spec/models/webauthn_credential_spec.rb index 9631245e11bbc7..23f0229a67ab39 100644 --- a/spec/models/webauthn_credentials_spec.rb +++ b/spec/models/webauthn_credential_spec.rb @@ -71,8 +71,8 @@ expect(webauthn_credential).to model_have_error_on_field(:sign_count) end - it 'is invalid if sign_count is greater 2**63 - 1' do - webauthn_credential = Fabricate.build(:webauthn_credential, sign_count: 2**63) + it 'is invalid if sign_count is greater than the limit' do + webauthn_credential = Fabricate.build(:webauthn_credential, sign_count: (described_class::SIGN_COUNT_LIMIT * 2)) webauthn_credential.valid? From cec8e34b250c368ec6c4a5acb75eed311aa901bf Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 16:29:00 -0400 Subject: [PATCH 35/90] Remove unused CI env vars (#30660) --- .github/workflows/test-migrations-one-step.yml | 1 - .github/workflows/test-migrations-two-step.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/test-migrations-one-step.yml b/.github/workflows/test-migrations-one-step.yml index 1ff5cc06b9f096..104e1b067c7b40 100644 --- a/.github/workflows/test-migrations-one-step.yml +++ b/.github/workflows/test-migrations-one-step.yml @@ -57,7 +57,6 @@ jobs: - 6379:6379 env: - CONTINUOUS_INTEGRATION: true DB_HOST: localhost DB_USER: postgres DB_PASS: postgres diff --git a/.github/workflows/test-migrations-two-step.yml b/.github/workflows/test-migrations-two-step.yml index 66988473152655..c4209d6329d78e 100644 --- a/.github/workflows/test-migrations-two-step.yml +++ b/.github/workflows/test-migrations-two-step.yml @@ -57,7 +57,6 @@ jobs: - 6379:6379 env: - CONTINUOUS_INTEGRATION: true DB_HOST: localhost DB_USER: postgres DB_PASS: postgres From 1dfd51628416598d2386621b6229a4f169cd360e Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 12 Jun 2024 09:28:28 +0200 Subject: [PATCH 36/90] Fix duplicate `@context` attribute in user export (#30653) --- app/services/backup_service.rb | 4 ++-- spec/services/backup_service_spec.rb | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb index 886bab1ebfe54d..1e9018437685f0 100644 --- a/app/services/backup_service.rb +++ b/app/services/backup_service.rb @@ -19,8 +19,8 @@ def call(backup) def build_outbox_json!(file) skeleton = serialize(collection_presenter, ActivityPub::CollectionSerializer) - skeleton[:@context] = full_context - skeleton[:orderedItems] = ['!PLACEHOLDER!'] + skeleton['@context'] = full_context + skeleton['orderedItems'] = ['!PLACEHOLDER!'] skeleton = Oj.dump(skeleton) prepend, append = skeleton.split('"!PLACEHOLDER!"') add_comma = false diff --git a/spec/services/backup_service_spec.rb b/spec/services/backup_service_spec.rb index b4cb60083b7ff1..145b06e3722ca9 100644 --- a/spec/services/backup_service_spec.rb +++ b/spec/services/backup_service_spec.rb @@ -55,9 +55,11 @@ def process_backup end def expect_outbox_export - json = export_json(:outbox) + body = export_json_raw(:outbox) + json = Oj.load(body) aggregate_failures do + expect(body.scan('@context').count).to eq 1 expect(json['@context']).to_not be_nil expect(json['type']).to eq 'OrderedCollection' expect(json['totalItems']).to eq 2 @@ -85,8 +87,12 @@ def expect_bookmarks_export end end + def export_json_raw(type) + read_zip_file(backup, "#{type}.json") + end + def export_json(type) - Oj.load(read_zip_file(backup, "#{type}.json")) + Oj.load(export_json_raw(type)) end def include_create_item(status) From ced463360e39b92689144e366b6f3a9ceabf1bf7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:48:31 +0200 Subject: [PATCH 37/90] New Crowdin Translations (automated) (#30666) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/be.json | 19 ++++++++++++++++++- app/javascript/mastodon/locales/ur.json | 5 +++++ config/locales/be.yml | 3 +++ config/locales/doorkeeper.be.yml | 2 ++ config/locales/doorkeeper.fy.yml | 2 ++ config/locales/fy.yml | 1 + config/locales/simple_form.be.yml | 6 ++++++ config/locales/simple_form.fy.yml | 2 ++ 8 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index 61e96e4b585b91..041d90775b5795 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.json @@ -308,6 +308,8 @@ "follow_requests.unlocked_explanation": "Ваш акаўнт не схаваны, аднак прадстаўнікі {domain} палічылі, што вы можаце захацець праглядзець запыты на падпіску з гэтых профіляў уручную.", "follow_suggestions.curated_suggestion": "Выбар адміністрацыі", "follow_suggestions.dismiss": "Не паказваць зноў", + "follow_suggestions.featured_longer": "Адабраныя камандай {domain} уручную", + "follow_suggestions.friends_of_friends_longer": "Папулярнае сярод людзей, на якіх Вы падпісаны", "follow_suggestions.hints.featured": "Гэты профіль быў выбраны ўручную камандай {domain}.", "follow_suggestions.hints.friends_of_friends": "Гэты профіль папулярны сярод людзей, на якіх вы падпісаліся.", "follow_suggestions.hints.most_followed": "Гэты профіль - адзін з профіляў з самай вялікай колькасцю падпісак на {domain}.", @@ -315,6 +317,8 @@ "follow_suggestions.hints.similar_to_recently_followed": "Гэты профіль падобны на профілі, на якія вы нядаўна падпісаліся.", "follow_suggestions.personalized_suggestion": "Персаналізаваная прапанова", "follow_suggestions.popular_suggestion": "Папулярная прапанова", + "follow_suggestions.popular_suggestion_longer": "Папулярнае на {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Падобныя профілі, за якімі вы нядаўна сачылі", "follow_suggestions.view_all": "Праглядзець усё", "follow_suggestions.who_to_follow": "На каго падпісацца", "followed_tags": "Падпіскі", @@ -410,6 +414,7 @@ "limited_account_hint.action": "Усе роўна паказваць профіль", "limited_account_hint.title": "Гэты профіль быў схаваны мадэратарамі", "link_preview.author": "Ад {name}", + "link_preview.more_from_author": "Больш ад {name}", "lists.account.add": "Дадаць да спісу", "lists.account.remove": "Выдаліць са спісу", "lists.delete": "Выдаліць спіс", @@ -458,7 +463,7 @@ "navigation_bar.opened_in_classic_interface": "Допісы, уліковыя запісы і іншыя спецыфічныя старонкі па змоўчанні адчыняюцца ў класічным вэб-інтэрфейсе.", "navigation_bar.personal": "Асабістае", "navigation_bar.pins": "Замацаваныя допісы", - "navigation_bar.preferences": "Параметры", + "navigation_bar.preferences": "Налады", "navigation_bar.public_timeline": "Глабальная стужка", "navigation_bar.search": "Пошук", "navigation_bar.security": "Бяспека", @@ -470,10 +475,22 @@ "notification.follow_request": "{name} адправіў запыт на падпіску", "notification.mention": "{name} згадаў вас", "notification.moderation-warning.learn_more": "Даведацца больш", + "notification.moderation_warning": "Вы атрымалі папярэджанне аб мадэрацыі", + "notification.moderation_warning.action_delete_statuses": "Некаторыя вашыя допісы былі выдаленыя.", + "notification.moderation_warning.action_disable": "Ваш уліковы запіс быў адключаны.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Некаторыя з вашых допісаў былі пазначаныя як далікатныя.", + "notification.moderation_warning.action_none": "Ваш уліковы запіс атрымаў папярэджанне ад мадэратараў.", + "notification.moderation_warning.action_sensitive": "З гэтага моманту вашыя допісы будуць пазначаныя як далікатныя.", + "notification.moderation_warning.action_silence": "Ваш уліковы запіс быў абмежаваны.", + "notification.moderation_warning.action_suspend": "Ваш уліковы запіс быў прыпынены.", "notification.own_poll": "Ваша апытанне скончылася", "notification.poll": "Апытанне, дзе вы прынялі ўдзел, скончылася", "notification.reblog": "{name} пашырыў ваш допіс", + "notification.relationships_severance_event": "Страціў сувязь з {name}", + "notification.relationships_severance_event.account_suspension": "Адміністратар з {from} прыпыніў працу {target}, што азначае, што вы больш не можаце атрымліваць ад іх абнаўлення ці ўзаемадзейнічаць з імі.", + "notification.relationships_severance_event.domain_block": "Адміністратар з {from} заблакіраваў {target}, у тым ліку {followersCount} вашых падпісчыка(-аў) і {followingCount, plural, one {# уліковы запіс} few {# уліковыя запісы} many {# уліковых запісаў} other {# уліковых запісаў}}.", "notification.relationships_severance_event.learn_more": "Даведацца больш", + "notification.relationships_severance_event.user_domain_block": "Вы заблакіравалі {target} выдаліўшы {followersCount} сваіх падпісчыкаў і {followingCount, plural, one {# уліковы запіс} few {# уліковыя запісы} many {# уліковых запісаў} other {# уліковых запісаў}}, за якімі вы сочыце.", "notification.status": "Новы допіс ад {name}", "notification.update": "Допіс {name} адрэдагаваны", "notification_requests.accept": "Прыняць", diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json index 37f156c28fc9f6..6f3debae2eaacb 100644 --- a/app/javascript/mastodon/locales/ur.json +++ b/app/javascript/mastodon/locales/ur.json @@ -26,6 +26,7 @@ "account.featured_tags.last_status_never": "کوئی مراسلہ نہیں", "account.featured_tags.title": "{name} کے نمایاں ہیش ٹیگز", "account.follow": "پیروی کریں", + "account.follow_back": "اکاؤنٹ کو فالو بیک ", "account.followers": "پیروکار", "account.followers.empty": "\"ہنوز اس صارف کی کوئی پیروی نہیں کرتا\".", "account.followers_counter": "{count, plural,one {{counter} پیروکار} other {{counter} پیروکار}}", @@ -46,6 +47,7 @@ "account.mute_notifications_short": "نوٹیفیکیشنز کو خاموش کریں", "account.mute_short": "خاموش", "account.muted": "خاموش کردہ", + "account.mutual": "میوچول اکاؤنٹ", "account.no_bio": "کوئی تفصیل نہیں دی گئی۔", "account.open_original_page": "اصل صفحہ کھولیں", "account.posts": "ٹوٹ", @@ -65,7 +67,10 @@ "account.unmute_notifications_short": "نوٹیفیکیشنز کو خاموش نہ کریں", "account.unmute_short": "کو خاموش نہ کریں", "account_note.placeholder": "Click to add a note", + "admin.dashboard.daily_retention": "ایڈمن ڈیش بورڈ کو ڈیلی چیک ان کریں", + "admin.dashboard.monthly_retention": "ایڈمن کیش بورڈ کو منتھلی چیک ان کریں", "admin.dashboard.retention.average": "اوسط", + "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "نئے یسرز", "alert.rate_limited.message": "\"{retry_time, time, medium} کے بعد کوشش کریں\".", "alert.rate_limited.title": "محدود شرح", diff --git a/config/locales/be.yml b/config/locales/be.yml index 6f1f189523e61e..a14ba3d2243e9d 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -291,6 +291,7 @@ be: update_custom_emoji_html: "%{name} абнавіў эмодзі %{target}" update_domain_block_html: "%{name} абнавіў блакіроўку дамена для %{target}" update_ip_block_html: "%{name} змяніў правіла для IP %{target}" + update_report_html: "%{name} абнавіў скаргу %{target}" update_status_html: "%{name} абнавіў допіс %{target}" update_user_role_html: "%{name} змяніў ролю %{target}" deleted_account: выдалены ўліковы запіс @@ -779,6 +780,7 @@ be: desc_html: Гэта функцыянальнасць залежыць ад знешніх скрыптоў hCaptcha, што можа быць праблемай бяспекі і прыватнасці. Акрамя таго, гэта можа зрабіць працэс рэгістрацыі значна менш даступным для некаторых людзей, асабліва інвалідаў. Па гэтых прычынах, калі ласка, разгледзьце альтэрнатыўныя меры, такія як рэгістрацыя на аснове зацвярджэння або запрашэння. title: Патрабаваць ад новых карыстальнікаў рашэння CAPTCHA для пацверджання іх уліковага запісу content_retention: + danger_zone: Небяспечная зона preamble: Кантралюйце, як створаны карыстальнікамі кантэнт захоўваецца ў Mastodon. title: Утрыманне кантэнту default_noindex: @@ -983,6 +985,7 @@ be: delete: Выдаліць edit_preset: Рэдагаваць шаблон папярэджання empty: Вы яшчэ не вызначылі ніякіх шаблонаў папярэджанняў. + title: Папярэджальныя прадусталёўкі webhooks: add_new: Дадаць канцавую кропку delete: Выдаліць diff --git a/config/locales/doorkeeper.be.yml b/config/locales/doorkeeper.be.yml index 748cbeafa122e5..f4faed1f09e1cf 100644 --- a/config/locales/doorkeeper.be.yml +++ b/config/locales/doorkeeper.be.yml @@ -135,6 +135,7 @@ be: media: Мультымедыйныя далучэнні mutes: Ігнараваныя notifications: Апавяшчэнні + profile: Ваш профіль Mastodon push: Push-апавяшчэнні reports: Скаргі search: Пошук @@ -165,6 +166,7 @@ be: admin:write:reports: мадэраваць скаргі crypto: выкарыстоўваць скразное шыфраванне (end-to-end) follow: змяняць зносіны ўліковага запісу + profile: чытаць толькі інфармацыю профілю вашага ўліковага запісу push: атрымліваць push-апавяшчэнні read: чытаць усе даныя вашага ўліковага запісу read:accounts: бачыць інфармацыю аб уліковых запісах diff --git a/config/locales/doorkeeper.fy.yml b/config/locales/doorkeeper.fy.yml index a43defc427ef67..1cf2d32212a8f1 100644 --- a/config/locales/doorkeeper.fy.yml +++ b/config/locales/doorkeeper.fy.yml @@ -135,6 +135,7 @@ fy: media: Mediabylagen mutes: Negearre notifications: Meldingen + profile: Jo Mastodon-profyl push: Pushmeldingen reports: Rapportaazjes search: Sykje @@ -165,6 +166,7 @@ fy: admin:write:reports: moderaasjemaatregelen nimme yn rapportaazjes crypto: ein-ta-ein-fersifering brûke follow: relaasjes tusken accounts bewurkje + profile: allinnich de profylgegevens fan jo account lêze push: jo pushmeldingen ûntfange read: alle gegevens fan jo account lêze read:accounts: accountynformaasje besjen diff --git a/config/locales/fy.yml b/config/locales/fy.yml index c8e287732a7c54..54e28608efa779 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -285,6 +285,7 @@ fy: update_custom_emoji_html: Emoji %{target} is troch %{name} bywurke update_domain_block_html: "%{name} hat de domeinblokkade bywurke foar %{target}" update_ip_block_html: "%{name} hat de rigel foar IP %{target} wizige" + update_report_html: Rapportaazje %{target} is troch %{name} bywurke update_status_html: "%{name} hat de berjochten %{target} bywurke" update_user_role_html: "%{name} hat de rol %{target} wizige" deleted_account: fuortsmiten account diff --git a/config/locales/simple_form.be.yml b/config/locales/simple_form.be.yml index f8000a1c81ca64..101d40f117364c 100644 --- a/config/locales/simple_form.be.yml +++ b/config/locales/simple_form.be.yml @@ -77,10 +77,15 @@ be: warn: Схаваць адфільтраваны кантэнт за папярэджаннем з назвай фільтру form_admin_settings: activity_api_enabled: Падлік лакальна апублікаваных пастоў, актыўных карыстальнікаў і новых рэгістрацый у тыдзень + app_icon: WEBP, PNG, GIF ці JPG. Заменіце прадвызначаны значок праграмы на мабільных прыладах карыстальніцкім значком. + backups_retention_period: Карыстальнікі могуць ствараць архівы сваіх допісаў для наступнай запампоўкі. Пры станоўчай колькасці дзён гэтыя архівы будуць аўтаматычна выдаляцца са сховішча пасля заканчэння названай колькасці дзён. bootstrap_timeline_accounts: Гэтыя ўліковыя запісы будуць замацаваны ў топе рэкамендацый для новых карыстальнікаў. closed_registrations_message: Паказваецца, калі рэгістрацыя закрытая + content_cache_retention_period: Усе допісы з іншых сервераў (уключаючы пашырэнні і адказы) будуць выдаленыя праз паказаную колькасць дзён, незалежна ад таго, як лакальны карыстальнік узаемадзейнічаў з гэтымі допісамі. Гэта датычыцца і тых допісаў, якія лакальны карыстальнік пазначыў у закладкі або ўпадабанае. Прыватныя згадкі паміж карыстальнікамі з розных інстанс таксама будуць страчаныя і не змогуць быць адноўлены. Выкарыстанне гэтай налады прызначана для асобнікаў спецыяльнага прызначэння і парушае многія чаканні карыстальнікаў пры выкарыстанні ў агульных мэтах. custom_css: Вы можаце прымяняць карыстальніцкія стылі ў вэб-версіі Mastodon. + favicon: WEBP, PNG, GIF ці JPG. Замяняе прадвызначаны favicon Mastodon на ўласны значок. mascot: Замяняе ілюстрацыю ў пашыраным вэб-інтэрфейсе. + media_cache_retention_period: Медыяфайлы з допісаў, зробленых выдаленымі карыстальнікамі, кэшыруюцца на вашым серверы. Пры станоўчым значэнні медыяфайлы будуць выдалены праз пазначаную колькасць дзён. Калі медыядадзеныя будуць запытаны пасля выдалення, яны будуць загружаны паўторна, калі зыходны кантэнт усё яшчэ даступны. У сувязі з абмежаваннямі на частату абнаўлення відарысаў іншых сайтаў, рэкамендуецца ўсталяваць значэнне не менш за 14 дзён, інакш відарысы не будуць загружацца па запыце раней за гэты тэрмін. peers_api_enabled: Спіс даменных імён, з якімі сутыкнуўся гэты сервер у федэсвеце. Дадзеныя аб тым, ці знаходзіцеся вы з пэўным серверам у федэрацыі, не ўключаныя, ёсць толькі тое, што ваш сервер ведае пра гэта. Гэта выкарыстоўваецца сэрвісамі, якія збіраюць статыстыку па федэрацыі ў агульным сэнсе. profile_directory: Дырэкторыя профіляў змяшчае спіс усіх карыстальнікаў, якія вырашылі быць бачнымі. require_invite_text: Калі рэгістрацыя патрабуе ручнога пацвержання, зрабіце поле "Чаму вы хочаце далучыцца?" абавязковым @@ -240,6 +245,7 @@ be: backups_retention_period: Працягласць захавання архіву карыстальніка bootstrap_timeline_accounts: Заўсёды раіць гэтыя ўліковыя запісы новым карыстальнікам closed_registrations_message: Уласнае паведамленне, калі рэгістрацыя немагчымая + content_cache_retention_period: Перыяд захоўвання выдаленага змесціва custom_css: CSS карыстальніка mascot: Уласны маскот(спадчына) media_cache_retention_period: Працягласць захавання кэшу для медыя diff --git a/config/locales/simple_form.fy.yml b/config/locales/simple_form.fy.yml index 8d599324b33be8..9e0f67b70725ac 100644 --- a/config/locales/simple_form.fy.yml +++ b/config/locales/simple_form.fy.yml @@ -77,11 +77,13 @@ fy: warn: Ferstopje de filtere ynhâld efter in warskôging, mei de titel fan it filter as warskôgingstekst form_admin_settings: activity_api_enabled: Tal lokaal publisearre artikelen, aktive brûkers en nije registraasjes yn wyklikse werjefte + app_icon: WEBP, PNG, GIF of JPG. Ferfangt op mobile apparaten it standert app-pictogram mei in oanpast piktogram. backups_retention_period: Brûkers hawwe de mooglikheid om argiven fan harren berjochten te generearjen om letter te downloaden. Wannear ynsteld op in positive wearde, wurde dizze argiven automatysk fuortsmiten út jo ûnthâld nei it opjûne oantal dagen. bootstrap_timeline_accounts: Dizze accounts wurde boppe oan de oanrekommandaasjes oan nije brûkers toand. Meardere brûkersnammen troch komma’s skiede. closed_registrations_message: Werjûn wannear’t registraasje fan nije accounts útskeakele is content_cache_retention_period: Alle berjochten fan oare servers (ynklusyf boosts en reaksjes) wurde fuortsmiten nei it opjûne oantal dagen, nettsjinsteande iennige lokale brûkersynteraksje mei dy berjochten. Dit oanbelanget ek berjochten dy’t in lokale brûker oan harren blêdwizers tafoege hat of as favoryt markearre hat. Priveeberjochten tusken brûkers fan ferskate servers gean ek ferlern en binne ûnmooglik te werstellen. It gebrûk fan dizze ynstelling is bedoeld foar servers dy’t in spesjaal doel tsjinje en oertrêdet in protte brûkersferwachtingen wannear’t dizze foar algemien gebrûk ymplemintearre wurdt. custom_css: Jo kinne oanpaste CSS tapasse op de webferzje fan dizze Mastodon-server. + favicon: WEBP, PNG, GIF of JPG. Ferfangt de standert Mastodon-favicon mei in oanpast piktogram. mascot: Oerskriuwt de yllustraasje yn de avansearre webomjouwing. media_cache_retention_period: Mediabestannen fan berjochten fan eksterne brûkers wurde op jo server yn de buffer bewarre. Wannear ynsteld op in positive wearde, wurde media fuortsmiten nei it opjûne oantal dagen. As de mediagegevens opfrege wurde neidat se fuortsmiten binne, wurde se opnij download wannear de orizjinele ynhâld noch hieltyd beskikber is. Fanwegen beheiningen op hoe faak keppelingsfoarbylden websites fan tredden rieplachtsje, wurdt oanrekommandearre om dizze wearde yn te stellen op op syn minste 14 dagen. Oars wurde keppelingsfoarbylden net op oanfraach bywurke. peers_api_enabled: In list mei domeinnammen, dêr’t dizze server yn fediverse kontakt hân mei hat. Hjir wurdt gjin data dield, oft jo mei in bepaalde server federearrest, mar alinnich, dat jo server dat wit. Dit wurdt foar tsjinsten brûkt, dy’t statistiken oer federaasje yn algemiene sin sammelet. From dff48ff705b8193702cdef149f8cd8748365d48f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:04:54 +0200 Subject: [PATCH 38/90] fix(deps): update dependency sass to v1.77.5 (#30665) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 33cd7b481d414d..b88cfaab14a6ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15355,15 +15355,15 @@ __metadata: linkType: hard "sass@npm:^1.62.1": - version: 1.77.4 - resolution: "sass@npm:1.77.4" + version: 1.77.5 + resolution: "sass@npm:1.77.5" dependencies: chokidar: "npm:>=3.0.0 <4.0.0" immutable: "npm:^4.0.0" source-map-js: "npm:>=0.6.2 <2.0.0" bin: sass: sass.js - checksum: 10c0/b9cb4882bded282aabe38d011adfce375e1f282184fcf93dc3da5d5be834c6aa53c474c15634c351ef7bd85146cfd1cc81343654cc3bcf000d78e856da4225ef + checksum: 10c0/9da049b0a3fadab419084d6becdf471e107cf6e3c8ac87cabea2feb845afac75e86c99e06ee721a5aa4f6a2d833ec5380137c4e540ab2f760edf1e4eb6139e69 languageName: node linkType: hard From 9321a454de78dc57d4382f6f366f282a111d2b31 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 12 Jun 2024 07:38:20 -0400 Subject: [PATCH 39/90] Combine CI migration tests (#30661) --- .../workflows/test-migrations-two-step.yml | 94 ------------------- ...tions-one-step.yml => test-migrations.yml} | 32 ++++--- 2 files changed, 19 insertions(+), 107 deletions(-) delete mode 100644 .github/workflows/test-migrations-two-step.yml rename .github/workflows/{test-migrations-one-step.yml => test-migrations.yml} (66%) diff --git a/.github/workflows/test-migrations-two-step.yml b/.github/workflows/test-migrations-two-step.yml deleted file mode 100644 index c4209d6329d78e..00000000000000 --- a/.github/workflows/test-migrations-two-step.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: Test two step migrations -on: - push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' - pull_request: - -jobs: - pre_job: - runs-on: ubuntu-latest - - outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} - - steps: - - id: skip_check - uses: fkirc/skip-duplicate-actions@v5 - with: - paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml", "lib/tasks/tests.rake"]' - - test: - runs-on: ubuntu-latest - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' - - strategy: - fail-fast: false - - matrix: - postgres: - - 14-alpine - - 15-alpine - - services: - postgres: - image: postgres:${{ matrix.postgres}} - env: - POSTGRES_PASSWORD: postgres - POSTGRES_USER: postgres - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - - redis: - image: redis:7-alpine - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 6379:6379 - - env: - DB_HOST: localhost - DB_USER: postgres - DB_PASS: postgres - DISABLE_SIMPLECOV: true - RAILS_ENV: test - BUNDLE_CLEAN: true - BUNDLE_FROZEN: true - BUNDLE_WITHOUT: 'development production' - BUNDLE_JOBS: 3 - BUNDLE_RETRY: 3 - - steps: - - uses: actions/checkout@v4 - - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby - - - name: Create database - run: './bin/rails db:create' - - - name: Run historical migrations with data population - run: './bin/rails tests:migrations:prepare_database' - env: - SKIP_POST_DEPLOYMENT_MIGRATIONS: true - - - name: Run all remaining pre-deployment migrations - run: './bin/rails db:migrate' - env: - SKIP_POST_DEPLOYMENT_MIGRATIONS: true - - - name: Run all post-deployment migrations - run: './bin/rails db:migrate' - - - name: Check migration result - run: './bin/rails tests:migrations:check_database' diff --git a/.github/workflows/test-migrations-one-step.yml b/.github/workflows/test-migrations.yml similarity index 66% rename from .github/workflows/test-migrations-one-step.yml rename to .github/workflows/test-migrations.yml index 104e1b067c7b40..f057efc11a44ee 100644 --- a/.github/workflows/test-migrations-one-step.yml +++ b/.github/workflows/test-migrations.yml @@ -1,4 +1,5 @@ -name: Test one step migrations +name: Historical data migration test + on: push: branches-ignore: @@ -17,7 +18,7 @@ jobs: - id: skip_check uses: fkirc/skip-duplicate-actions@v5 with: - paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml", "lib/tasks/tests.rake"]' + paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations.yml", "lib/tasks/tests.rake"]' test: runs-on: ubuntu-latest @@ -64,7 +65,7 @@ jobs: RAILS_ENV: test BUNDLE_CLEAN: true BUNDLE_FROZEN: true - BUNDLE_WITHOUT: 'development production' + BUNDLE_WITHOUT: 'development:production' BUNDLE_JOBS: 3 BUNDLE_RETRY: 3 @@ -74,14 +75,19 @@ jobs: - name: Set up Ruby environment uses: ./.github/actions/setup-ruby - - name: Create database - run: './bin/rails db:create' - - - name: Run historical migrations with data population - run: './bin/rails tests:migrations:prepare_database' - - - name: Run all remaining migrations - run: './bin/rails db:migrate' + - name: Test "one step migration" flow + run: | + bin/rails db:drop + bin/rails db:create + bin/rails tests:migrations:prepare_database + bin/rails db:migrate + bin/rails tests:migrations:check_database - - name: Check migration result - run: './bin/rails tests:migrations:check_database' + - name: Test "two step migration" flow + run: | + bin/rails db:drop + bin/rails db:create + SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails tests:migrations:prepare_database + SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails db:migrate + bin/rails db:migrate + bin/rails tests:migrations:check_database From 47f97e113a1047c067948f385b5179fa0489180f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 12 Jun 2024 07:39:16 -0400 Subject: [PATCH 40/90] Update the bundler-audit vulnerability DB when running (#30658) --- .github/workflows/bundler-audit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml index bbc31598c75a91..923abcd91c6000 100644 --- a/.github/workflows/bundler-audit.yml +++ b/.github/workflows/bundler-audit.yml @@ -31,4 +31,4 @@ jobs: uses: ./.github/actions/setup-ruby - name: Run bundler-audit - run: bundle exec bundler-audit + run: bundle exec bundler-audit check --update From 0a7249c7c687775c7ab6ef495b259cedff5f25ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:41:14 +0200 Subject: [PATCH 41/90] fix(deps): update dependency pino to v9.2.0 (#30659) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index b88cfaab14a6ab..b34f45aac0838f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13093,8 +13093,8 @@ __metadata: linkType: hard "pino@npm:^9.0.0": - version: 9.1.0 - resolution: "pino@npm:9.1.0" + version: 9.2.0 + resolution: "pino@npm:9.2.0" dependencies: atomic-sleep: "npm:^1.0.0" fast-redact: "npm:^3.1.1" @@ -13109,7 +13109,7 @@ __metadata: thread-stream: "npm:^3.0.0" bin: pino: bin.js - checksum: 10c0/d060530ae2e4e8f21d04bb0f44f009f94d207d7f4337f508f618416514214ddaf1b29f8c5c265153a19ce3b6480b451461f40020f916ace9d53a5aa07624b79c + checksum: 10c0/5fbd226ff7dab0961232b5aa5eca0530cdc5bb29f6bf17d929e42239293b1a587a26cc311db6abc1090c9dd57e8f7b031eae341b41d00d4a642b4f1736474c80 languageName: node linkType: hard From 54ab70dfcf39e13c055b99a4fc4aea721781af32 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:42:04 +0200 Subject: [PATCH 42/90] chore(deps): update yarn to v4.3.0 (#30644) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- streaming/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f84d45c32ec3c4..d52f0ea1cc296f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@mastodon/mastodon", "license": "AGPL-3.0-or-later", - "packageManager": "yarn@4.2.2", + "packageManager": "yarn@4.3.0", "engines": { "node": ">=18" }, diff --git a/streaming/package.json b/streaming/package.json index 2e515167c7de57..ba024fe7af4b3c 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -1,7 +1,7 @@ { "name": "@mastodon/streaming", "license": "AGPL-3.0-or-later", - "packageManager": "yarn@4.2.2", + "packageManager": "yarn@4.3.0", "engines": { "node": ">=18" }, From 19f1c081e161bf8ca3325f48f7fe0194827de56a Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 12 Jun 2024 08:59:32 -0400 Subject: [PATCH 43/90] Update `rubocop-rspec` to version 3.0.1 (#30655) --- .rubocop.yml | 5 ----- Gemfile | 1 + Gemfile.lock | 19 ++++++++----------- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index cbc0afd2815c53..090b89b2556b2f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -133,11 +133,6 @@ Rails/NegateInclude: 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: - Enabled: false - # Reason: # https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject RSpec/NamedSubject: diff --git a/Gemfile b/Gemfile index be02a656263944..b00eaecbcf9f02 100644 --- a/Gemfile +++ b/Gemfile @@ -171,6 +171,7 @@ group :development do gem 'rubocop-performance', require: false gem 'rubocop-rails', require: false gem 'rubocop-rspec', require: false + gem 'rubocop-rspec_rails', require: false # Annotates modules with schema gem 'annotate', '~> 3.2' diff --git a/Gemfile.lock b/Gemfile.lock index c2253fe19cf28b..902ddd5f59fe43 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -698,8 +698,8 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.8) - strscan (>= 3.0.9) + rexml (3.3.0) + strscan rotp (6.3.0) rouge (4.2.1) rpam2 (4.0.2) @@ -746,8 +746,6 @@ GEM parser (>= 3.3.1.0) rubocop-capybara (2.21.0) rubocop (~> 1.41) - rubocop-factory_bot (2.25.1) - rubocop (~> 1.41) rubocop-performance (1.21.0) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) @@ -756,13 +754,11 @@ GEM rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) - rubocop-rspec (2.31.0) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) - rubocop-rspec_rails (~> 2.28) - rubocop-rspec_rails (2.28.3) - rubocop (~> 1.40) + rubocop-rspec (3.0.1) + rubocop (~> 1.61) + rubocop-rspec_rails (2.30.0) + rubocop (~> 1.61) + rubocop-rspec (~> 3, >= 3.0.1) ruby-prof (1.7.0) ruby-progressbar (1.13.0) ruby-saml (1.16.0) @@ -1028,6 +1024,7 @@ DEPENDENCIES rubocop-performance rubocop-rails rubocop-rspec + rubocop-rspec_rails ruby-prof ruby-progressbar (~> 1.13) ruby-vips (~> 2.2) From 99842434677ef3a01f5c7700d3b67ba5e72cd1a1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 12 Jun 2024 15:10:51 +0200 Subject: [PATCH 44/90] Fix a few visual glitches with link previews in web UI (#30670) --- app/javascript/styles/mastodon/components.scss | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 4f36d85aa986f3..2400f319dbf006 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -1411,10 +1411,15 @@ body > [data-popper-placement] { .audio-player, .attachment-list, .picture-in-picture-placeholder, + .more-from-author, .status-card, .hashtag-bar { margin-inline-start: $thread-margin; - width: calc(100% - ($thread-margin)); + width: calc(100% - $thread-margin); + } + + .more-from-author { + width: calc(100% - $thread-margin + 2px); } .status__content__read-more-button { @@ -4129,6 +4134,13 @@ a.status-card { border-end-start-radius: 0; } +.status-card.bottomless .status-card__image, +.status-card.bottomless .status-card__image-image, +.status-card.bottomless .status-card__image-preview { + border-end-end-radius: 0; + border-end-start-radius: 0; +} + .status-card.expanded > a { width: 100%; } @@ -10229,6 +10241,7 @@ noscript { } .more-from-author { + box-sizing: border-box; font-size: 14px; color: $darker-text-color; background: var(--surface-background-color); From a5a15846756dd62e01bf7eb64fdf3b8fafc3ba69 Mon Sep 17 00:00:00 2001 From: Sujay Date: Wed, 12 Jun 2024 19:18:30 +0530 Subject: [PATCH 45/90] Update README.md (#30626) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4aca37673b8ef7..9c0b0d20ed5d02 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre ### Tech stack - **Ruby on Rails** powers the REST API and other web pages -- **React.js** and Redux are used for the dynamic parts of the interface +- **React.js** and **Redux** are used for the dynamic parts of the interface - **Node.js** powers the streaming API ### Requirements From bf56e982a9c211396efea16f2ee596102b36db3f Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 12 Jun 2024 15:50:38 +0200 Subject: [PATCH 46/90] Fix notifications from limited users being outright dropped (#30559) --- app/lib/feed_manager.rb | 5 +---- spec/lib/feed_manager_spec.rb | 6 +++--- spec/services/notify_service_spec.rb | 29 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 95a687fa41d335..1fb224a1337c50 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -420,10 +420,7 @@ def filter_from_mentions?(status, receiver_id) check_for_blocks = status.active_mentions.pluck(:account_id) check_for_blocks.push(status.in_reply_to_account) if status.reply? && !status.in_reply_to_account_id.nil? - should_filter = blocks_or_mutes?(receiver_id, check_for_blocks, :mentions) # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted) - should_filter ||= status.account.silenced? && !Follow.exists?(account_id: receiver_id, target_account_id: status.account_id) # Filter if the account is silenced and I'm not following them - - should_filter + blocks_or_mutes?(receiver_id, check_for_blocks, :mentions) # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted) end # Check if status should not be added to the list feed diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb index 613bcb3045da32..679309bd11c746 100644 --- a/spec/lib/feed_manager_spec.rb +++ b/spec/lib/feed_manager_spec.rb @@ -206,13 +206,13 @@ expect(described_class.instance.filter?(:mentions, reply, bob)).to be true end - it 'returns true for status by silenced account who recipient is not following' do + it 'returns false for status by limited account who recipient is not following' do status = Fabricate(:status, text: 'Hello world', account: alice) alice.silence! - expect(described_class.instance.filter?(:mentions, status, bob)).to be true + expect(described_class.instance.filter?(:mentions, status, bob)).to be false end - it 'returns false for status by followed silenced account' do + it 'returns false for status by followed limited account' do status = Fabricate(:status, text: 'Hello world', account: alice) alice.silence! bob.follow!(alice) diff --git a/spec/services/notify_service_spec.rb b/spec/services/notify_service_spec.rb index 6064d2b050f4a3..8c810f1c32b521 100644 --- a/spec/services/notify_service_spec.rb +++ b/spec/services/notify_service_spec.rb @@ -129,6 +129,35 @@ end end + describe NotifyService::DismissCondition do + subject { described_class.new(notification) } + + let(:activity) { Fabricate(:mention, status: Fabricate(:status)) } + let(:notification) { Fabricate(:notification, type: :mention, activity: activity, from_account: activity.status.account, account: activity.account) } + + describe '#dismiss?' do + context 'when sender is silenced' do + before do + notification.from_account.silence! + end + + it 'returns false' do + expect(subject.dismiss?).to be false + end + end + + context 'when recipient has blocked sender' do + before do + notification.account.block!(notification.from_account) + end + + it 'returns true' do + expect(subject.dismiss?).to be true + end + end + end + end + describe NotifyService::FilterCondition do subject { described_class.new(notification) } From 7ad5a3a2b728229704e29819b3b87bc0ccdc473f Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Thu, 13 Jun 2024 10:21:50 +0200 Subject: [PATCH 47/90] Disable `consistent-return` eslint rule for Typescript files (#30675) --- .eslintrc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index 759003b55ec3cd..e3afb1c9f23030 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -349,6 +349,9 @@ module.exports = defineConfig({ // Disable formatting rules that have been enabled in the base config 'indent': 'off', + // This is not needed as we use noImplicitReturns, which handles this in addition to understanding types + 'consistent-return': 'off', + 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], From fc2f49cfbcbe996abeb267592bcf39d60d2995ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:26:00 +0200 Subject: [PATCH 48/90] chore(deps): update docker.io/ruby docker tag to v3.3.3 (#30679) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 2dc7602b2d23d2..e29377829c55c8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ ARG BUILDPLATFORM=${BUILDPLATFORM} # Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"] # renovate: datasource=docker depName=docker.io/ruby -ARG RUBY_VERSION="3.3.2" +ARG RUBY_VERSION="3.3.3" # # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] # renovate: datasource=node-version depName=node ARG NODE_MAJOR_VERSION="20" From b379dc156e9a2292f2e21f80543c0b80d4087688 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 13 Jun 2024 04:26:09 -0400 Subject: [PATCH 49/90] Update parser to version 3.3.3.0 (#30676) --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 902ddd5f59fe43..222aaff50471ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -584,7 +584,7 @@ GEM orm_adapter (0.5.0) ox (2.14.18) parallel (1.25.1) - parser (3.3.2.0) + parser (3.3.3.0) ast (~> 2.4.1) racc parslet (2.0.0) From fe740455767a361798df3a21791f9db8e2056f7e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:26:17 +0200 Subject: [PATCH 50/90] chore(deps): update dependency ruby to v3.3.3 (#30667) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 4772543317946f..619b537668489e 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.2 +3.3.3 From 37f53542fe1c36c6126932cbb3840f6d4659104e Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 13 Jun 2024 14:42:40 +0200 Subject: [PATCH 51/90] Fix limit handling in grouped notifications CTE (#30685) --- app/models/notification.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/notification.rb b/app/models/notification.rb index e3deaa5348b7c3..01abe74f5e7eb3 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -152,6 +152,7 @@ def paginate_groups_by_max_id(limit, max_id: nil, since_id: nil) .limit(1), query .joins('CROSS JOIN grouped_notifications') + .where('array_length(grouped_notifications.groups, 1) < :limit', limit: limit) .where('notifications.id < grouped_notifications.id') .where.not("COALESCE(notifications.group_key, 'ungrouped-' || notifications.id) = ANY(grouped_notifications.groups)") .select('notifications.*', "array_append(grouped_notifications.groups, COALESCE(notifications.group_key, 'ungrouped-' || notifications.id))") @@ -179,6 +180,7 @@ def paginate_groups_by_min_id(limit, max_id: nil, min_id: nil) .limit(1), query .joins('CROSS JOIN grouped_notifications') + .where('array_length(grouped_notifications.groups, 1) < :limit', limit: limit) .where('notifications.id > grouped_notifications.id') .where.not("COALESCE(notifications.group_key, 'ungrouped-' || notifications.id) = ANY(grouped_notifications.groups)") .select('notifications.*', "array_append(grouped_notifications.groups, COALESCE(notifications.group_key, 'ungrouped-' || notifications.id))") From ed6d24330ba2f80b99428cb8ee19e5d8400ebd16 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 13 Jun 2024 15:04:16 +0200 Subject: [PATCH 52/90] Add author links on the explore page in web UI (#30521) --- .../mastodon/actions/importer/index.js | 8 +- .../mastodon/actions/importer/normalizer.js | 4 + app/javascript/mastodon/actions/trends.js | 9 +- .../mastodon/components/more_from_author.jsx | 19 +++ .../explore/components/author_link.jsx | 21 ++++ .../features/explore/components/story.jsx | 118 +++++++++++------- .../mastodon/features/explore/links.jsx | 3 +- .../features/status/components/card.jsx | 19 +-- app/javascript/mastodon/locales/en.json | 1 + .../styles/mastodon/components.scss | 69 +++++++--- app/javascript/styles/mastodon/variables.scss | 2 + 11 files changed, 189 insertions(+), 84 deletions(-) create mode 100644 app/javascript/mastodon/components/more_from_author.jsx create mode 100644 app/javascript/mastodon/features/explore/components/author_link.jsx diff --git a/app/javascript/mastodon/actions/importer/index.js b/app/javascript/mastodon/actions/importer/index.js index 16f191b5846f63..d906bdfb14c4ec 100644 --- a/app/javascript/mastodon/actions/importer/index.js +++ b/app/javascript/mastodon/actions/importer/index.js @@ -68,13 +68,17 @@ export function importFetchedStatuses(statuses) { status.filtered.forEach(result => pushUnique(filters, result.filter)); } - if (status.reblog && status.reblog.id) { + if (status.reblog?.id) { processStatus(status.reblog); } - if (status.poll && status.poll.id) { + if (status.poll?.id) { pushUnique(polls, normalizePoll(status.poll, getState().getIn(['polls', status.poll.id]))); } + + if (status.card?.author_account) { + pushUnique(accounts, status.card.author_account); + } } statuses.forEach(processStatus); diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index b5a30343e488c4..be76b0f391692d 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -36,6 +36,10 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.poll = status.poll.id; } + if (status.card?.author_account) { + normalStatus.card = { ...status.card, author_account: status.card.author_account.id }; + } + if (status.filtered) { normalStatus.filtered = status.filtered.map(normalizeFilterResult); } diff --git a/app/javascript/mastodon/actions/trends.js b/app/javascript/mastodon/actions/trends.js index 0b840b41ce6085..01089fccbb764d 100644 --- a/app/javascript/mastodon/actions/trends.js +++ b/app/javascript/mastodon/actions/trends.js @@ -1,6 +1,6 @@ import api, { getLinks } from '../api'; -import { importFetchedStatuses } from './importer'; +import { importFetchedStatuses, importFetchedAccounts } from './importer'; export const TRENDS_TAGS_FETCH_REQUEST = 'TRENDS_TAGS_FETCH_REQUEST'; export const TRENDS_TAGS_FETCH_SUCCESS = 'TRENDS_TAGS_FETCH_SUCCESS'; @@ -49,8 +49,11 @@ export const fetchTrendingLinks = () => (dispatch) => { dispatch(fetchTrendingLinksRequest()); api() - .get('/api/v1/trends/links') - .then(({ data }) => dispatch(fetchTrendingLinksSuccess(data))) + .get('/api/v1/trends/links', { params: { limit: 20 } }) + .then(({ data }) => { + dispatch(importFetchedAccounts(data.map(link => link.author_account).filter(account => !!account))); + dispatch(fetchTrendingLinksSuccess(data)); + }) .catch(err => dispatch(fetchTrendingLinksFail(err))); }; diff --git a/app/javascript/mastodon/components/more_from_author.jsx b/app/javascript/mastodon/components/more_from_author.jsx new file mode 100644 index 00000000000000..c20e76ac459f9a --- /dev/null +++ b/app/javascript/mastodon/components/more_from_author.jsx @@ -0,0 +1,19 @@ +import PropTypes from 'prop-types'; + +import { FormattedMessage } from 'react-intl'; + +import { AuthorLink } from 'mastodon/features/explore/components/author_link'; + +export const MoreFromAuthor = ({ accountId }) => ( +
+ + + + + }} /> +
+); + +MoreFromAuthor.propTypes = { + accountId: PropTypes.string.isRequired, +}; diff --git a/app/javascript/mastodon/features/explore/components/author_link.jsx b/app/javascript/mastodon/features/explore/components/author_link.jsx new file mode 100644 index 00000000000000..b9dec3367e8b46 --- /dev/null +++ b/app/javascript/mastodon/features/explore/components/author_link.jsx @@ -0,0 +1,21 @@ +import PropTypes from 'prop-types'; + +import { Link } from 'react-router-dom'; + +import { Avatar } from 'mastodon/components/avatar'; +import { useAppSelector } from 'mastodon/store'; + +export const AuthorLink = ({ accountId }) => { + const account = useAppSelector(state => state.getIn(['accounts', accountId])); + + return ( + + + + + ); +}; + +AuthorLink.propTypes = { + accountId: PropTypes.string.isRequired, +}; diff --git a/app/javascript/mastodon/features/explore/components/story.jsx b/app/javascript/mastodon/features/explore/components/story.jsx index 80dd5200fc7339..a2cae942d4b630 100644 --- a/app/javascript/mastodon/features/explore/components/story.jsx +++ b/app/javascript/mastodon/features/explore/components/story.jsx @@ -1,61 +1,89 @@ import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; +import { useState, useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; + import { Blurhash } from 'mastodon/components/blurhash'; -import { accountsCountRenderer } from 'mastodon/components/hashtag'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; import { ShortNumber } from 'mastodon/components/short_number'; import { Skeleton } from 'mastodon/components/skeleton'; -export default class Story extends PureComponent { - - static propTypes = { - url: PropTypes.string, - title: PropTypes.string, - lang: PropTypes.string, - publisher: PropTypes.string, - publishedAt: PropTypes.string, - author: PropTypes.string, - sharedTimes: PropTypes.number, - thumbnail: PropTypes.string, - thumbnailDescription: PropTypes.string, - blurhash: PropTypes.string, - expanded: PropTypes.bool, - }; - - state = { - thumbnailLoaded: false, - }; - - handleImageLoad = () => this.setState({ thumbnailLoaded: true }); - - render () { - const { expanded, url, title, lang, publisher, author, publishedAt, sharedTimes, thumbnail, thumbnailDescription, blurhash } = this.props; - - const { thumbnailLoaded } = this.state; - - return ( - -
-
{publisher ? {publisher} : }{publishedAt && <> · }
-
{title ? title : }
-
{author && <>{author} }} /> · }{typeof sharedTimes === 'number' ? : }
+import { AuthorLink } from './author_link'; + +const sharesCountRenderer = (displayNumber, pluralReady) => ( + {displayNumber}, + }} + /> +); + +export const Story = ({ + url, + title, + lang, + publisher, + publishedAt, + author, + authorAccount, + sharedTimes, + thumbnail, + thumbnailDescription, + blurhash, + expanded +}) => { + const [thumbnailLoaded, setThumbnailLoaded] = useState(false); + + const handleImageLoad = useCallback(() => { + setThumbnailLoaded(true); + }, [setThumbnailLoaded]); + + return ( +
+ + ); +}; -} +Story.propTypes = { + url: PropTypes.string, + title: PropTypes.string, + lang: PropTypes.string, + publisher: PropTypes.string, + publishedAt: PropTypes.string, + author: PropTypes.string, + authorAccount: PropTypes.string, + sharedTimes: PropTypes.number, + thumbnail: PropTypes.string, + thumbnailDescription: PropTypes.string, + blurhash: PropTypes.string, + expanded: PropTypes.bool, +}; diff --git a/app/javascript/mastodon/features/explore/links.jsx b/app/javascript/mastodon/features/explore/links.jsx index 9e143b4505083a..93fd1fb6ddebc7 100644 --- a/app/javascript/mastodon/features/explore/links.jsx +++ b/app/javascript/mastodon/features/explore/links.jsx @@ -13,7 +13,7 @@ import { DismissableBanner } from 'mastodon/components/dismissable_banner'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; -import Story from './components/story'; +import { Story } from './components/story'; const mapStateToProps = state => ({ links: state.getIn(['trends', 'links', 'items']), @@ -75,6 +75,7 @@ class Links extends PureComponent { publisher={link.get('provider_name')} publishedAt={link.get('published_at')} author={link.get('author_name')} + authorAccount={link.getIn(['author_account', 'id'])} sharedTimes={link.getIn(['history', 0, 'accounts']) * 1 + link.getIn(['history', 1, 'accounts']) * 1} thumbnail={link.get('image')} thumbnailDescription={link.get('image_description')} diff --git a/app/javascript/mastodon/features/status/components/card.jsx b/app/javascript/mastodon/features/status/components/card.jsx index c2f5703b3c4469..f562e53f0ba334 100644 --- a/app/javascript/mastodon/features/status/components/card.jsx +++ b/app/javascript/mastodon/features/status/components/card.jsx @@ -6,7 +6,6 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { Link } from 'react-router-dom'; import Immutable from 'immutable'; @@ -15,9 +14,9 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import DescriptionIcon from '@/material-icons/400-24px/description-fill.svg?react'; import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react'; import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react'; -import { Avatar } from 'mastodon/components/avatar'; import { Blurhash } from 'mastodon/components/blurhash'; import { Icon } from 'mastodon/components/icon'; +import { MoreFromAuthor } from 'mastodon/components/more_from_author'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; import { useBlurhash } from 'mastodon/initial_state'; @@ -59,20 +58,6 @@ const addAutoPlay = html => { return html; }; -const MoreFromAuthor = ({ author }) => ( -
- - - - - {author.get('display_name')} }} /> -
-); - -MoreFromAuthor.propTypes = { - author: ImmutablePropTypes.map, -}; - export default class Card extends PureComponent { static propTypes = { @@ -259,7 +244,7 @@ export default class Card extends PureComponent { {description} - {showAuthor && } + {showAuthor && } ); } diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 63298d59e3aa5e..4f5caeb6acaa58 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -415,6 +415,7 @@ "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.", "link_preview.author": "By {name}", "link_preview.more_from_author": "More from {name}", + "link_preview.shares": "{count, plural, one {{counter} post} other {{counter} posts}}", "lists.account.add": "Add to list", "lists.account.remove": "Remove from list", "lists.delete": "Delete list", diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 2400f319dbf006..d5c3d2605c91c0 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -8796,43 +8796,80 @@ noscript { display: flex; align-items: center; color: $primary-text-color; - text-decoration: none; - padding: 15px; + padding: 16px; border-bottom: 1px solid var(--background-border-color); - gap: 15px; + gap: 16px; &:last-child { border-bottom: 0; } - &:hover, - &:active, - &:focus { - color: $highlight-text-color; - - .story__details__publisher, - .story__details__shared { - color: $highlight-text-color; - } - } - &__details { flex: 1 1 auto; &__publisher { color: $darker-text-color; margin-bottom: 8px; + font-size: 14px; + line-height: 20px; } &__title { + display: block; font-size: 19px; line-height: 24px; font-weight: 500; margin-bottom: 8px; + text-decoration: none; + color: $primary-text-color; + + &:hover, + &:active, + &:focus { + color: $highlight-text-color; + } } &__shared { + display: flex; + align-items: center; color: $darker-text-color; + gap: 8px; + justify-content: space-between; + font-size: 14px; + line-height: 20px; + + & > span { + display: flex; + align-items: center; + gap: 4px; + } + + &__pill { + background: var(--surface-variant-background-color); + border-radius: 4px; + color: inherit; + text-decoration: none; + padding: 4px 12px; + font-size: 12px; + font-weight: 500; + line-height: 16px; + } + + &__author-link { + display: inline-flex; + align-items: center; + gap: 4px; + color: $primary-text-color; + font-weight: 500; + text-decoration: none; + + &:hover, + &:active, + &:focus { + color: $highlight-text-color; + } + } } strong { @@ -9903,14 +9940,14 @@ noscript { color: inherit; text-decoration: none; padding: 4px 12px; - background: $ui-base-color; + background: var(--surface-variant-background-color); border-radius: 4px; font-weight: 500; &:hover, &:focus, &:active { - background: lighten($ui-base-color, 4%); + background: var(--surface-variant-active-background-color); } } diff --git a/app/javascript/styles/mastodon/variables.scss b/app/javascript/styles/mastodon/variables.scss index 58b9dd9b61b101..2848a42b3fec7e 100644 --- a/app/javascript/styles/mastodon/variables.scss +++ b/app/javascript/styles/mastodon/variables.scss @@ -106,4 +106,6 @@ $font-monospace: 'mastodon-font-monospace' !default; --background-color: #{darken($ui-base-color, 8%)}; --background-color-tint: #{rgba(darken($ui-base-color, 8%), 0.9)}; --surface-background-color: #{darken($ui-base-color, 4%)}; + --surface-variant-background-color: #{$ui-base-color}; + --surface-variant-active-background-color: #{lighten($ui-base-color, 4%)}; } From 64fc17352bec11684cf617b10ebc5a11eb7ec924 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:13:06 +0200 Subject: [PATCH 53/90] chore(deps): update dependency sanitize to v6.1.1 (#30683) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 222aaff50471ec..89425363db8e77 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -772,7 +772,7 @@ GEM fugit (~> 1.1, >= 1.1.6) safety_net_attestation (0.4.0) jwt (~> 2.0) - sanitize (6.1.0) + sanitize (6.1.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) scenic (1.8.0) From 474dda70272b9e406fb4a22b1f66caf797c2f8b2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:15:01 +0200 Subject: [PATCH 54/90] chore(deps): update dependency aws-sdk-s3 to v1.152.2 (#30680) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 89425363db8e77..172b7cbdd46048 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,7 +109,7 @@ GEM aws-sdk-kms (1.83.0) aws-sdk-core (~> 3, >= 3.197.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.152.1) + aws-sdk-s3 (1.152.2) aws-sdk-core (~> 3, >= 3.197.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) From 3b7c50abca213353f6e210837fda0f21baf1be20 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 13 Jun 2024 09:15:32 -0400 Subject: [PATCH 55/90] Remove bundler-audit ignore config (#30672) --- .bundler-audit.yml | 6 ------ .github/workflows/bundler-audit.yml | 2 -- 2 files changed, 8 deletions(-) delete mode 100644 .bundler-audit.yml diff --git a/.bundler-audit.yml b/.bundler-audit.yml deleted file mode 100644 index 0671df390fed81..00000000000000 --- a/.bundler-audit.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -ignore: - # devise-two-factor advisory about brute-forcing TOTP - # We have rate-limits on authentication endpoints in place (including second - # factor verification) since Mastodon v3.2.0 - - CVE-2024-0227 diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml index 923abcd91c6000..48f9d82933ce7c 100644 --- a/.github/workflows/bundler-audit.yml +++ b/.github/workflows/bundler-audit.yml @@ -6,14 +6,12 @@ on: paths: - 'Gemfile*' - '.ruby-version' - - '.bundler-audit.yml' - '.github/workflows/bundler-audit.yml' pull_request: paths: - 'Gemfile*' - '.ruby-version' - - '.bundler-audit.yml' - '.github/workflows/bundler-audit.yml' schedule: From 8889816a51df17e2e78cdcaa17bda0780393bd0d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 13 Jun 2024 09:23:32 -0400 Subject: [PATCH 56/90] Use stock ruby environment on CI lint tasks (#30657) --- .github/workflows/bundler-audit.yml | 9 +++++++-- .github/workflows/lint-haml.yml | 10 ++++++++-- .github/workflows/lint-ruby.yml | 9 +++++++-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml index 48f9d82933ce7c..e3e2da0c787a54 100644 --- a/.github/workflows/bundler-audit.yml +++ b/.github/workflows/bundler-audit.yml @@ -21,12 +21,17 @@ jobs: security: runs-on: ubuntu-latest + env: + BUNDLE_ONLY: development + steps: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true - name: Run bundler-audit run: bundle exec bundler-audit check --update diff --git a/.github/workflows/lint-haml.yml b/.github/workflows/lint-haml.yml index 25615b720d45ad..ca4b0c80bfdc3e 100644 --- a/.github/workflows/lint-haml.yml +++ b/.github/workflows/lint-haml.yml @@ -26,12 +26,18 @@ on: jobs: lint: runs-on: ubuntu-latest + + env: + BUNDLE_ONLY: development + steps: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true - name: Run haml-lint run: | diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml index 411b323486a0a4..2e4de55725bb14 100644 --- a/.github/workflows/lint-ruby.yml +++ b/.github/workflows/lint-ruby.yml @@ -27,12 +27,17 @@ jobs: lint: runs-on: ubuntu-latest + env: + BUNDLE_ONLY: development + steps: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true - name: Set-up RuboCop Problem Matcher uses: r7kamura/rubocop-problem-matchers-action@v1 From dd587d29b68ee8548cd91697ba85b1ee274845d5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:30:07 +0200 Subject: [PATCH 57/90] New Crowdin Translations (automated) (#30684) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/ur.json | 4 +--- config/locales/activerecord.ur.yml | 26 +++++++++++++++++++++++++ config/locales/doorkeeper.cs.yml | 1 + config/locales/doorkeeper.ia.yml | 2 ++ config/locales/doorkeeper.sl.yml | 2 ++ config/locales/doorkeeper.sv.yml | 1 + config/locales/simple_form.sv.yml | 2 ++ config/locales/sv.yml | 1 + 8 files changed, 36 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json index 6f3debae2eaacb..1b9f8d9691d03f 100644 --- a/app/javascript/mastodon/locales/ur.json +++ b/app/javascript/mastodon/locales/ur.json @@ -28,7 +28,7 @@ "account.follow": "پیروی کریں", "account.follow_back": "اکاؤنٹ کو فالو بیک ", "account.followers": "پیروکار", - "account.followers.empty": "\"ہنوز اس صارف کی کوئی پیروی نہیں کرتا\".", + "account.followers.empty": "ہنوز اس صارف کی کوئی پیروی نہیں کرتا.", "account.followers_counter": "{count, plural,one {{counter} پیروکار} other {{counter} پیروکار}}", "account.following": "فالو کر رہے ہیں", "account.following_counter": "{count, plural, one {{counter} پیروی کر رہے ہیں} other {{counter} پیروی کر رہے ہیں}}", @@ -66,11 +66,9 @@ "account.unmute": "@{name} کو با آواز کریں", "account.unmute_notifications_short": "نوٹیفیکیشنز کو خاموش نہ کریں", "account.unmute_short": "کو خاموش نہ کریں", - "account_note.placeholder": "Click to add a note", "admin.dashboard.daily_retention": "ایڈمن ڈیش بورڈ کو ڈیلی چیک ان کریں", "admin.dashboard.monthly_retention": "ایڈمن کیش بورڈ کو منتھلی چیک ان کریں", "admin.dashboard.retention.average": "اوسط", - "admin.dashboard.retention.cohort": "Sign-up month", "admin.dashboard.retention.cohort_size": "نئے یسرز", "alert.rate_limited.message": "\"{retry_time, time, medium} کے بعد کوشش کریں\".", "alert.rate_limited.title": "محدود شرح", diff --git a/config/locales/activerecord.ur.yml b/config/locales/activerecord.ur.yml index 2cace5883d3750..e8fbef9afcceba 100644 --- a/config/locales/activerecord.ur.yml +++ b/config/locales/activerecord.ur.yml @@ -1 +1,27 @@ +--- ur: + activerecord: + attributes: + poll: + expires_at: ڈیڈ لائن + options: اپنی مرضی + user: + agreement: سروس کا معاہدہ + email: ای میل ایڈریسز + locale: لوکل + password: پاس ورڈ + user/account: + username: یوزر نیم + user/invite_request: + text: وجہ + errors: + models: + account: + attributes: + username: + invalid: صرف حروف، نمبر اور انڈر سکور پر مشتمل ہونا چاہیے۔ + reserved: محفوظ ہے + admin/webhook: + attributes: + url: + invalid: ایک درست URL نہیں ہے۔ diff --git a/config/locales/doorkeeper.cs.yml b/config/locales/doorkeeper.cs.yml index be2a4d971a5039..3323834685a165 100644 --- a/config/locales/doorkeeper.cs.yml +++ b/config/locales/doorkeeper.cs.yml @@ -135,6 +135,7 @@ cs: media: Mediální přílohy mutes: Skrytí notifications: Oznámení + profile: Váš Mastodon profil push: Push oznámení reports: Hlášení search: Hledání diff --git a/config/locales/doorkeeper.ia.yml b/config/locales/doorkeeper.ia.yml index 5b99abb7b42be0..985d073ab80ae6 100644 --- a/config/locales/doorkeeper.ia.yml +++ b/config/locales/doorkeeper.ia.yml @@ -135,6 +135,7 @@ ia: media: Annexos multimedial mutes: Silentiates notifications: Notificationes + profile: Tu profilo de Mastodon push: Notificationes push reports: Reportos search: Cercar @@ -165,6 +166,7 @@ ia: admin:write:reports: exequer actiones de moderation sur reportos crypto: usar cryptation de puncta a puncta follow: modificar relationes inter contos + profile: leger solmente le information de profilo de tu conto push: reciper tu notificationes push read: leger tote le datos de tu conto read:accounts: vider informationes de contos diff --git a/config/locales/doorkeeper.sl.yml b/config/locales/doorkeeper.sl.yml index a613308b28afbf..f6f64fc87fa0f2 100644 --- a/config/locales/doorkeeper.sl.yml +++ b/config/locales/doorkeeper.sl.yml @@ -135,6 +135,7 @@ sl: media: Predstavnostne priloge mutes: Utišani notifications: Obvestila + profile: Vaš profil Mastodon push: Potisna obvestila reports: Prijave search: Iskanje @@ -165,6 +166,7 @@ sl: admin:write:reports: izvedi moderirana dejanja na prijavah crypto: Uporabi šifriranje od konca do konca follow: spremeni razmerja med računi + profile: preberi le podatke profila računa push: prejmi potisna obvestila read: preberi vse podatke svojega računa read:accounts: oglejte si podrobnosti računov diff --git a/config/locales/doorkeeper.sv.yml b/config/locales/doorkeeper.sv.yml index bc4ba6f53ed575..b46c16d4de0f55 100644 --- a/config/locales/doorkeeper.sv.yml +++ b/config/locales/doorkeeper.sv.yml @@ -166,6 +166,7 @@ sv: admin:write:reports: utföra modereringsåtgärder på rapporter crypto: använd obruten kryptering follow: modifiera kontorelationer + profile: läs endast ditt kontos profilinformation push: ta emot dina push-notiser read: läsa dina kontodata read:accounts: se kontoinformation diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml index 5e5c6f95491507..11d142a2bd6d73 100644 --- a/config/locales/simple_form.sv.yml +++ b/config/locales/simple_form.sv.yml @@ -77,11 +77,13 @@ sv: warn: Dölj det filtrerade innehållet bakom en varning som visar filtrets rubrik form_admin_settings: activity_api_enabled: Antalet lokalt publicerade inlägg, aktiva användare och nya registrerade konton per vecka + app_icon: WEBP, PNG, GIF eller JPG. Använd istället för appens egna ikon på mobila enheter. backups_retention_period: Användare har möjlighet att generera arkiv av sina inlägg för att ladda ned senare. När det sätts till ett positivt värde raderas dessa arkiv automatiskt från din lagring efter det angivna antalet dagar. bootstrap_timeline_accounts: Dessa konton kommer fästas högst upp i nya användares följrekommendationer. closed_registrations_message: Visas när nyregistreringar är avstängda content_cache_retention_period: Alla inlägg från andra servrar (inklusive booster och svar) kommer att raderas efter det angivna antalet dagar, utan hänsyn till någon lokal användarinteraktion med dessa inlägg. Detta inkluderar inlägg där en lokal användare har markerat det som bokmärke eller favoriter. Privata omnämnanden mellan användare från olika instanser kommer också att gå förlorade och blir omöjliga att återställa. Användningen av denna inställning är avsedd för specialfall och bryter många användarförväntningar när de implementeras för allmänt bruk. custom_css: Du kan använda anpassade stilar på webbversionen av Mastodon. + favicon: WEBP, PNG, GIF eller JPG. Används på mobila enheter istället för appens egen ikon. mascot: Åsidosätter illustrationen i det avancerade webbgränssnittet. media_cache_retention_period: Mediafiler från inlägg som gjorts av fjärranvändare cachas på din server. När inställd på ett positivt värde kommer media att raderas efter det angivna antalet dagar. Om mediadatat begärs efter att det har raderats, kommer det att laddas ned igen om källinnehållet fortfarande är tillgängligt. På grund av begränsningar för hur ofta förhandsgranskningskort för länkar hämtas från tredjepartswebbplatser, rekommenderas det att ange detta värde till minst 14 dagar, annars kommer förhandsgranskningskorten inte att uppdateras på begäran före den tiden. peers_api_enabled: En lista över domänen den här servern har stött på i fediversum. Ingen data inkluderas om du har federerat med servern, bara att din server känner till den. Detta används av tjänster som samlar statistik om federering i allmänhet. diff --git a/config/locales/sv.yml b/config/locales/sv.yml index cf68cdd5637509..a3d31547cec6fc 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -951,6 +951,7 @@ sv: delete: Radera edit_preset: Redigera varningsförval empty: Du har inte definierat några varningsförval ännu. + title: Varning förinställningar webhooks: add_new: Lägg till slutpunkt delete: Ta bort From 45abddb302a44adafdcc0479cc93dea4d8fb4b64 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 13 Jun 2024 16:10:34 +0200 Subject: [PATCH 58/90] Fix pagination attributes not being returned in ungroupable-only pages (#30688) --- app/serializers/rest/notification_group_serializer.rb | 2 +- spec/requests/api/v2_alpha/notifications_spec.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/serializers/rest/notification_group_serializer.rb b/app/serializers/rest/notification_group_serializer.rb index 05b51b07a5f66f..ce1950c5a45260 100644 --- a/app/serializers/rest/notification_group_serializer.rb +++ b/app/serializers/rest/notification_group_serializer.rb @@ -45,6 +45,6 @@ def latest_page_notification_at end def paginated? - instance_options[:group_metadata].present? + !instance_options[:group_metadata].nil? end end diff --git a/spec/requests/api/v2_alpha/notifications_spec.rb b/spec/requests/api/v2_alpha/notifications_spec.rb index 9bd1a32e9bf7e1..ac44605ac5d212 100644 --- a/spec/requests/api/v2_alpha/notifications_spec.rb +++ b/spec/requests/api/v2_alpha/notifications_spec.rb @@ -58,6 +58,7 @@ expect(response).to have_http_status(200) expect(body_json_types.uniq).to eq ['mention'] + expect(body_as_json[0][:page_min_id]).to_not be_nil end end From 3a191b3797dde1daf79cd748a14b87240532d543 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 13 Jun 2024 10:27:17 -0400 Subject: [PATCH 59/90] Add `rubocop` binstub, simplify configuration (#30407) --- .github/workflows/lint-ruby.yml | 2 +- .rubocop.yml | 254 ++++---------------------------- .rubocop/custom.yml | 6 + .rubocop/layout.yml | 6 + .rubocop/metrics.yml | 23 +++ .rubocop/naming.yml | 3 + .rubocop/rails.yml | 27 ++++ .rubocop/rspec.yml | 17 +++ .rubocop/rspec_rails.yml | 3 + .rubocop/strict.yml | 19 +++ .rubocop/style.yml | 47 ++++++ bin/rubocop | 27 ++++ lint-staged.config.js | 3 +- 13 files changed, 210 insertions(+), 227 deletions(-) create mode 100644 .rubocop/custom.yml create mode 100644 .rubocop/layout.yml create mode 100644 .rubocop/metrics.yml create mode 100644 .rubocop/naming.yml create mode 100644 .rubocop/rails.yml create mode 100644 .rubocop/rspec.yml create mode 100644 .rubocop/rspec_rails.yml create mode 100644 .rubocop/strict.yml create mode 100644 .rubocop/style.yml create mode 100755 bin/rubocop diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml index 2e4de55725bb14..f4e81d508bf698 100644 --- a/.github/workflows/lint-ruby.yml +++ b/.github/workflows/lint-ruby.yml @@ -43,7 +43,7 @@ jobs: uses: r7kamura/rubocop-problem-matchers-action@v1 - name: Run rubocop - run: bundle exec rubocop + run: bin/rubocop - name: Run brakeman if: always() # Run both checks, even if the first failed diff --git a/.rubocop.yml b/.rubocop.yml index 090b89b2556b2f..cf4ee565e00eb0 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,34 @@ -# Can be removed once all rules are addressed or moved to this file as documented overrides -inherit_from: .rubocop_todo.yml +--- +AllCops: + CacheRootDirectory: tmp + DisplayCopNames: true + DisplayStyleGuide: true + Exclude: + - db/schema.rb + - bin/* + - node_modules/**/* + - Vagrantfile + - vendor/**/* + - config/initializers/json_ld* + - lib/mastodon/migration_helpers.rb + - lib/templates/**/* + ExtraDetails: true + NewCops: enable + TargetRubyVersion: 3.1 # Oldest supported ruby version + UseCache: true + +inherit_from: + - .rubocop/layout.yml + - .rubocop/metrics.yml + - .rubocop/naming.yml + - .rubocop/rails.yml + - .rubocop/rspec_rails.yml + - .rubocop/rspec.yml + - .rubocop/style.yml + - .rubocop/custom.yml + - .rubocop_todo.yml + - .rubocop/strict.yml -# Used for merging with exclude lists with .rubocop_todo.yml inherit_mode: merge: - Exclude @@ -12,224 +39,3 @@ require: - rubocop-rspec_rails - rubocop-performance - rubocop-capybara - - ./lib/linter/rubocop_middle_dot - -AllCops: - TargetRubyVersion: 3.1 # Set to minimum supported version of CI - DisplayCopNames: true - DisplayStyleGuide: true - ExtraDetails: true - UseCache: true - CacheRootDirectory: tmp - NewCops: enable # Opt-in to newly added rules - Exclude: - - db/schema.rb - - 'bin/*' - - 'node_modules/**/*' - - 'Vagrantfile' - - 'vendor/**/*' - - 'config/initializers/json_ld*' # Generated files - - 'lib/mastodon/migration_helpers.rb' # Vendored from GitLab - - 'lib/templates/**/*' - -# Reason: Prefer Hashes without extreme indentation -# https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirsthashelementindentation -Layout/FirstHashElementIndentation: - EnforcedStyle: consistent - -# Reason: Currently disabled in .rubocop_todo.yml -# https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength -Layout/LineLength: - Max: 300 # Default of 120 causes a duplicate entry in generated todo file - -## Disable most Metrics/*Length cops -# Reason: those are often triggered and force significant refactors when this happend -# but the team feel they are not really improving the code quality. - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength -Metrics/BlockLength: - Enabled: false - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsclasslength -Metrics/ClassLength: - Enabled: false - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength -Metrics/MethodLength: - Enabled: false - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmodulelength -Metrics/ModuleLength: - Enabled: false - -## End Disable Metrics/*Length cops - -# Reason: Currently disabled in .rubocop_todo.yml -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize -Metrics/AbcSize: - Exclude: - - 'lib/mastodon/cli/*.rb' - -# Reason: Currently disabled in .rubocop_todo.yml -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity -Metrics/CyclomaticComplexity: - Exclude: - - lib/mastodon/cli/*.rb - -# Reason: -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists -Metrics/ParameterLists: - CountKeywordArgs: false - -# Reason: Prefer seeing a variable name -# https://docs.rubocop.org/rubocop/cops_naming.html#namingblockforwarding -Naming/BlockForwarding: - EnforcedStyle: explicit - -# Reason: Prevailing style is argument file paths -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath -Rails/FilePath: - EnforcedStyle: arguments - -# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus -Rails/HttpStatus: - EnforcedStyle: numeric - -# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter -Rails/LexicallyScopedActionFilter: - Exclude: - - 'app/controllers/auth/*' - -# Reason: These tasks are doing local work which do not need full env loaded -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsrakeenvironment -Rails/RakeEnvironment: - Exclude: - - 'lib/tasks/auto_annotate_models.rake' - - 'lib/tasks/emojis.rake' - - 'lib/tasks/mastodon.rake' - - 'lib/tasks/repo.rake' - - 'lib/tasks/statistics.rake' - -# Reason: There are appropriate times to use these features -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsskipsmodelvalidations -Rails/SkipsModelValidations: - Enabled: false - -# Reason: We want to preserve the ability to migrate from arbitrary old versions, -# and cannot guarantee that every installation has run every migration as they upgrade. -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsunusedignoredcolumns -Rails/UnusedIgnoredColumns: - Enabled: false - -# Reason: Prevailing style choice -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsnegateinclude -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: -# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject -RSpec/NamedSubject: - EnforcedStyle: named_only - -# Reason: Prevailing style choice -# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnottonot -RSpec/NotToNot: - EnforcedStyle: to_not - -# Reason: Match overrides from Rspec/FilePath rule above -# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecspecfilepathformat -RSpec/SpecFilePathFormat: - CustomTransform: - ActivityPub: activitypub - DeepL: deepl - FetchOEmbedService: fetch_oembed_service - OEmbedController: oembed_controller - OStatus: ostatus - -# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus -# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus -RSpecRails/HttpStatus: - EnforcedStyle: numeric - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren -Style/ClassAndModuleChildren: - Enabled: false - -# Reason: Classes mostly self-document with their names -# https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation -Style/Documentation: - Enabled: false - -# Reason: Route redirects are not token-formatted and must be skipped -# https://docs.rubocop.org/rubocop/cops_style.html#styleformatstringtoken -Style/FormatStringToken: - inherit_mode: - merge: - - AllowedMethods # The rubocop-rails config adds `redirect` - AllowedMethods: - - redirect_with_vary - -# Reason: Prevailing style choice -# https://docs.rubocop.org/rubocop/cops_style.html#stylehashaslastarrayitem -Style/HashAsLastArrayItem: - Enabled: false - -# Reason: Enforce modern Ruby style -# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax -Style/HashSyntax: - EnforcedStyle: ruby19_no_mixed_keys - EnforcedShorthandSyntax: either - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals -Style/NumericLiterals: - AllowedPatterns: - - \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#stylepercentliteraldelimiters -Style/PercentLiteralDelimiters: - PreferredDelimiters: - '%i': '()' - '%w': '()' - -# Reason: Prefer less indentation in conditional assignments -# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantbegin -Style/RedundantBegin: - Enabled: false - -# Reason: Prevailing style choice -# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantfetchblock -Style/RedundantFetchBlock: - Enabled: false - -# Reason: Overridden to reduce implicit StandardError rescues -# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror -Style/RescueStandardError: - EnforcedStyle: implicit - -# Reason: Originally disabled for CodeClimate, and no config consensus has been found -# https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray -Style/SymbolArray: - Enabled: false - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainarrayliteral -Style/TrailingCommaInArrayLiteral: - EnforcedStyleForMultiline: 'comma' - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral -Style/TrailingCommaInHashLiteral: - EnforcedStyleForMultiline: 'comma' - -Style/MiddleDot: - Enabled: true diff --git a/.rubocop/custom.yml b/.rubocop/custom.yml new file mode 100644 index 00000000000000..63035837f86119 --- /dev/null +++ b/.rubocop/custom.yml @@ -0,0 +1,6 @@ +--- +require: + - ../lib/linter/rubocop_middle_dot + +Style/MiddleDot: + Enabled: true diff --git a/.rubocop/layout.yml b/.rubocop/layout.yml new file mode 100644 index 00000000000000..487879ca2c1134 --- /dev/null +++ b/.rubocop/layout.yml @@ -0,0 +1,6 @@ +--- +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent + +Layout/LineLength: + Max: 300 # Default of 120 causes a duplicate entry in generated todo file diff --git a/.rubocop/metrics.yml b/.rubocop/metrics.yml new file mode 100644 index 00000000000000..89532af42abb15 --- /dev/null +++ b/.rubocop/metrics.yml @@ -0,0 +1,23 @@ +--- +Metrics/AbcSize: + Exclude: + - lib/mastodon/cli/*.rb + +Metrics/BlockLength: + Enabled: false + +Metrics/ClassLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Exclude: + - lib/mastodon/cli/*.rb + +Metrics/MethodLength: + Enabled: false + +Metrics/ModuleLength: + Enabled: false + +Metrics/ParameterLists: + CountKeywordArgs: false diff --git a/.rubocop/naming.yml b/.rubocop/naming.yml new file mode 100644 index 00000000000000..da6ad4ac579a63 --- /dev/null +++ b/.rubocop/naming.yml @@ -0,0 +1,3 @@ +--- +Naming/BlockForwarding: + EnforcedStyle: explicit diff --git a/.rubocop/rails.yml b/.rubocop/rails.yml new file mode 100644 index 00000000000000..b83928dee6b3ef --- /dev/null +++ b/.rubocop/rails.yml @@ -0,0 +1,27 @@ +--- +Rails/FilePath: + EnforcedStyle: arguments + +Rails/HttpStatus: + EnforcedStyle: numeric + +Rails/LexicallyScopedActionFilter: + Exclude: + - app/controllers/auth/* # Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions + +Rails/NegateInclude: + Enabled: false + +Rails/RakeEnvironment: + Exclude: # Tasks are doing local work which do not need full env loaded + - lib/tasks/auto_annotate_models.rake + - lib/tasks/emojis.rake + - lib/tasks/mastodon.rake + - lib/tasks/repo.rake + - lib/tasks/statistics.rake + +Rails/SkipsModelValidations: + Enabled: false + +Rails/UnusedIgnoredColumns: + Enabled: false # Preserve ability to migrate from arbitrary old versions diff --git a/.rubocop/rspec.yml b/.rubocop/rspec.yml new file mode 100644 index 00000000000000..a6f8a7aee0f88b --- /dev/null +++ b/.rubocop/rspec.yml @@ -0,0 +1,17 @@ +--- +RSpec/ExampleLength: + CountAsOne: ['array', 'heredoc', 'method_call'] + +RSpec/NamedSubject: + EnforcedStyle: named_only + +RSpec/NotToNot: + EnforcedStyle: to_not + +RSpec/SpecFilePathFormat: + CustomTransform: + ActivityPub: activitypub + DeepL: deepl + FetchOEmbedService: fetch_oembed_service + OEmbedController: oembed_controller + OStatus: ostatus diff --git a/.rubocop/rspec_rails.yml b/.rubocop/rspec_rails.yml new file mode 100644 index 00000000000000..993a5689ad091e --- /dev/null +++ b/.rubocop/rspec_rails.yml @@ -0,0 +1,3 @@ +--- +RSpecRails/HttpStatus: + EnforcedStyle: numeric diff --git a/.rubocop/strict.yml b/.rubocop/strict.yml new file mode 100644 index 00000000000000..2222c6d8b93402 --- /dev/null +++ b/.rubocop/strict.yml @@ -0,0 +1,19 @@ +Lint/Debugger: # Remove any `binding.pry` + Enabled: true + Exclude: [] + +RSpec/Focus: # Require full spec run on CI + Enabled: true + Exclude: [] + +Rails/Output: # Remove any `puts` debugging + Enabled: true + Exclude: [] + +Rails/FindEach: # Using `each` could impact performance, use `find_each` + Enabled: true + Exclude: [] + +Rails/UniqBeforePluck: # Require `uniq.pluck` and not `pluck.uniq` + Enabled: true + Exclude: [] diff --git a/.rubocop/style.yml b/.rubocop/style.yml new file mode 100644 index 00000000000000..03e35a70ac43cd --- /dev/null +++ b/.rubocop/style.yml @@ -0,0 +1,47 @@ +--- +Style/ClassAndModuleChildren: + Enabled: false + +Style/Documentation: + Enabled: false + +Style/FormatStringToken: + AllowedMethods: + - redirect_with_vary # Route redirects are not token-formatted + inherit_mode: + merge: + - AllowedMethods + +Style/HashAsLastArrayItem: + Enabled: false + +Style/HashSyntax: + EnforcedShorthandSyntax: either + EnforcedStyle: ruby19_no_mixed_keys + +Style/NumericLiterals: + AllowedPatterns: + - \d{4}_\d{2}_\d{2}_\d{6} + +Style/PercentLiteralDelimiters: + PreferredDelimiters: + '%i': () + '%w': () + +Style/RedundantBegin: + Enabled: false + +Style/RedundantFetchBlock: + Enabled: false + +Style/RescueStandardError: + EnforcedStyle: implicit + +Style/SymbolArray: + Enabled: false + +Style/TrailingCommaInArrayLiteral: + EnforcedStyleForMultiline: comma + +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: comma diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 00000000000000..369a05bedb5684 --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,27 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'rubocop' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +bundle_binstub = File.expand_path("bundle", __dir__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300).include?("This file was generated by Bundler") + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rubocop", "rubocop") diff --git a/lint-staged.config.js b/lint-staged.config.js index 06fe66d11e95b2..6740def512a98c 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1,7 +1,6 @@ const config = { '*': 'prettier --ignore-unknown --write', - 'Capfile|Gemfile|*.{rb,ruby,ru,rake}': - 'bundle exec rubocop --force-exclusion -a', + 'Capfile|Gemfile|*.{rb,ruby,ru,rake}': 'bin/rubocop --force-exclusion -a', '*.{js,jsx,ts,tsx}': 'eslint --fix', '*.{css,scss}': 'stylelint --fix', '*.haml': 'bundle exec haml-lint -a', From f0ca874b09e29feda0db3eb50aece86e95192575 Mon Sep 17 00:00:00 2001 From: Louis Brauer Date: Thu, 13 Jun 2024 16:37:43 +0200 Subject: [PATCH 60/90] Include crossorigin in inert css (#30687) --- app/views/layouts/application.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index ec6caa33ada799..a73287959ede01 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -29,7 +29,7 @@ = stylesheet_pack_tag 'common', media: 'all', crossorigin: 'anonymous' = theme_style_tags current_theme -# Needed for the wicg-inert polyfill. It needs to be on it's own