From d1ecc323e7d435d0ffb11056a53b52d3345868f0 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 3 Feb 2022 14:07:29 +0100 Subject: [PATCH 01/14] Compact JSON-LD signed incoming activities (#17426) Co-authored-by: Puck Meerburg --- app/helpers/context_helper.rb | 54 +++++++++++++++++++ app/helpers/jsonld_helper.rb | 8 +++ app/lib/activitypub/adapter.rb | 51 +----------------- .../activitypub/process_collection_service.rb | 2 + 4 files changed, 66 insertions(+), 49 deletions(-) create mode 100644 app/helpers/context_helper.rb diff --git a/app/helpers/context_helper.rb b/app/helpers/context_helper.rb new file mode 100644 index 000000000..08cfa9c6d --- /dev/null +++ b/app/helpers/context_helper.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module ContextHelper + NAMED_CONTEXT_MAP = { + activitystreams: 'https://www.w3.org/ns/activitystreams', + security: 'https://w3id.org/security/v1', + }.freeze + + CONTEXT_EXTENSION_MAP = { + manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' }, + sensitive: { 'sensitive' => 'as:sensitive' }, + hashtag: { 'Hashtag' => 'as:Hashtag' }, + moved_to: { 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' } }, + also_known_as: { 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' } }, + emoji: { 'toot' => 'http://joinmastodon.org/ns#', 'Emoji' => 'toot:Emoji' }, + featured: { 'toot' => 'http://joinmastodon.org/ns#', 'featured' => { '@id' => 'toot:featured', '@type' => '@id' }, 'featuredTags' => { '@id' => 'toot:featuredTags', '@type' => '@id' } }, + property_value: { 'schema' => 'http://schema.org#', 'PropertyValue' => 'schema:PropertyValue', 'value' => 'schema:value' }, + atom_uri: { 'ostatus' => 'http://ostatus.org#', 'atomUri' => 'ostatus:atomUri' }, + conversation: { 'ostatus' => 'http://ostatus.org#', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation' }, + focal_point: { 'toot' => 'http://joinmastodon.org/ns#', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } }, + blurhash: { 'toot' => 'http://joinmastodon.org/ns#', 'blurhash' => 'toot:blurhash' }, + discoverable: { 'toot' => 'http://joinmastodon.org/ns#', 'discoverable' => 'toot:discoverable' }, + voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' }, + olm: { 'toot' => 'http://joinmastodon.org/ns#', 'Device' => 'toot:Device', 'Ed25519Signature' => 'toot:Ed25519Signature', 'Ed25519Key' => 'toot:Ed25519Key', 'Curve25519Key' => 'toot:Curve25519Key', 'EncryptedMessage' => 'toot:EncryptedMessage', 'publicKeyBase64' => 'toot:publicKeyBase64', 'deviceId' => 'toot:deviceId', 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, 'messageFranking' => 'toot:messageFranking', 'messageType' => 'toot:messageType', 'cipherText' => 'toot:cipherText' }, + suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' }, + }.freeze + + def full_context + serialized_context(NAMED_CONTEXT_MAP, CONTEXT_EXTENSION_MAP) + end + + def serialized_context(named_contexts_map, context_extensions_map) + context_array = [] + + named_contexts = named_contexts_map.keys + context_extensions = context_extensions_map.keys + + named_contexts.each do |key| + context_array << NAMED_CONTEXT_MAP[key] + end + + extensions = context_extensions.each_with_object({}) do |key, h| + h.merge!(CONTEXT_EXTENSION_MAP[key]) + end + + context_array << extensions unless extensions.empty? + + if context_array.size == 1 + context_array.first + else + context_array + end + end +end diff --git a/app/helpers/jsonld_helper.rb b/app/helpers/jsonld_helper.rb index c24d2ddf1..841f27746 100644 --- a/app/helpers/jsonld_helper.rb +++ b/app/helpers/jsonld_helper.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true module JsonLdHelper + include ContextHelper + def equals_or_includes?(haystack, needle) haystack.is_a?(Array) ? haystack.include?(needle) : haystack == needle end @@ -69,6 +71,12 @@ module JsonLdHelper graph.dump(:normalize) end + def compact(json) + compacted = JSON::LD::API.compact(json.without('signature'), full_context, documentLoader: method(:load_jsonld_context)) + compacted['signature'] = json['signature'] + compacted + end + def fetch_resource(uri, id, on_behalf_of = nil) unless id json = fetch_resource_without_id_validation(uri, on_behalf_of) diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 776e1d3da..098b6296f 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -1,29 +1,7 @@ # frozen_string_literal: true class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base - NAMED_CONTEXT_MAP = { - activitystreams: 'https://www.w3.org/ns/activitystreams', - security: 'https://w3id.org/security/v1', - }.freeze - - CONTEXT_EXTENSION_MAP = { - manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' }, - sensitive: { 'sensitive' => 'as:sensitive' }, - hashtag: { 'Hashtag' => 'as:Hashtag' }, - moved_to: { 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' } }, - also_known_as: { 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' } }, - emoji: { 'toot' => 'http://joinmastodon.org/ns#', 'Emoji' => 'toot:Emoji' }, - featured: { 'toot' => 'http://joinmastodon.org/ns#', 'featured' => { '@id' => 'toot:featured', '@type' => '@id' }, 'featuredTags' => { '@id' => 'toot:featuredTags', '@type' => '@id' } }, - property_value: { 'schema' => 'http://schema.org#', 'PropertyValue' => 'schema:PropertyValue', 'value' => 'schema:value' }, - atom_uri: { 'ostatus' => 'http://ostatus.org#', 'atomUri' => 'ostatus:atomUri' }, - conversation: { 'ostatus' => 'http://ostatus.org#', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation' }, - focal_point: { 'toot' => 'http://joinmastodon.org/ns#', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } }, - blurhash: { 'toot' => 'http://joinmastodon.org/ns#', 'blurhash' => 'toot:blurhash' }, - discoverable: { 'toot' => 'http://joinmastodon.org/ns#', 'discoverable' => 'toot:discoverable' }, - voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' }, - olm: { 'toot' => 'http://joinmastodon.org/ns#', 'Device' => 'toot:Device', 'Ed25519Signature' => 'toot:Ed25519Signature', 'Ed25519Key' => 'toot:Ed25519Key', 'Curve25519Key' => 'toot:Curve25519Key', 'EncryptedMessage' => 'toot:EncryptedMessage', 'publicKeyBase64' => 'toot:publicKeyBase64', 'deviceId' => 'toot:deviceId', 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, 'messageFranking' => 'toot:messageFranking', 'messageType' => 'toot:messageType', 'cipherText' => 'toot:cipherText' }, - suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' }, - }.freeze + include ContextHelper def self.default_key_transform :camel_lower @@ -34,7 +12,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base end def serializable_hash(options = nil) - named_contexts = {} + named_contexts = { activitystreams: NAMED_CONTEXT_MAP['activitystreams'] } context_extensions = {} options = serialization_options(options) @@ -44,29 +22,4 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base { '@context' => serialized_context(named_contexts, context_extensions) }.merge(serialized_hash) end - - private - - def serialized_context(named_contexts_map, context_extensions_map) - context_array = [] - - named_contexts = [:activitystreams] + named_contexts_map.keys - context_extensions = context_extensions_map.keys - - named_contexts.each do |key| - context_array << NAMED_CONTEXT_MAP[key] - end - - extensions = context_extensions.each_with_object({}) do |key, h| - h.merge!(CONTEXT_EXTENSION_MAP[key]) - end - - context_array << extensions unless extensions.empty? - - if context_array.size == 1 - context_array.first - else - context_array - end - end end diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index 170e6709c..5f3d63bb3 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -8,6 +8,8 @@ class ActivityPub::ProcessCollectionService < BaseService @json = Oj.load(body, mode: :strict) @options = options + @json = compact(@json) if @json['signature'].is_a?(Hash) + return if !supported_context? || (different_actor? && verify_account!.nil?) || suspended_actor? || @account.local? case @json['type'] From 948235592aa31c63033f7dc2d20a82115ca50149 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 3 Feb 2022 14:07:43 +0100 Subject: [PATCH 02/14] Fix response_to_recipient? CTE (#17427) --- app/services/notify_service.rb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 09e28b76b..0f3516d28 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -73,9 +73,11 @@ class NotifyService < BaseService # Using an SQL CTE to avoid unneeded back-and-forth with SQL server in case of long threads !Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @notification.from_account.id]).zero? - WITH RECURSIVE ancestors(id, in_reply_to_id, replying_to_sender) AS ( + WITH RECURSIVE ancestors(id, in_reply_to_id, replying_to_sender, path) AS ( SELECT - s.id, s.in_reply_to_id, (CASE + s.id, + s.in_reply_to_id, + (CASE WHEN s.account_id = :recipient_id THEN EXISTS ( SELECT * @@ -84,7 +86,8 @@ class NotifyService < BaseService ) ELSE FALSE - END) + END), + ARRAY[s.id] FROM statuses s WHERE s.id = :id UNION ALL @@ -100,10 +103,11 @@ class NotifyService < BaseService ) ELSE FALSE - END) + END), + st.path || s.id FROM ancestors st JOIN statuses s ON s.id = st.in_reply_to_id - WHERE st.replying_to_sender IS FALSE + WHERE st.replying_to_sender IS FALSE AND NOT s.id = ANY(path) ) SELECT COUNT(*) FROM ancestors st From c8b1e72a4febd0922e22c3bdbba9165507de23bb Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 3 Feb 2022 14:09:04 +0100 Subject: [PATCH 03/14] Fix compacted JSON-LD possibly causing compatibility issues on forwarding (#17428) --- app/helpers/jsonld_helper.rb | 72 ++++++++++++++++ .../activitypub/process_collection_service.rb | 18 +++- spec/helpers/jsonld_helper_spec.rb | 82 +++++++++++++++++++ 3 files changed, 170 insertions(+), 2 deletions(-) diff --git a/app/helpers/jsonld_helper.rb b/app/helpers/jsonld_helper.rb index 841f27746..c6557817d 100644 --- a/app/helpers/jsonld_helper.rb +++ b/app/helpers/jsonld_helper.rb @@ -77,6 +77,78 @@ module JsonLdHelper compacted end + # Patches a JSON-LD document to avoid compatibility issues on redistribution + # + # Since compacting a JSON-LD document against Mastodon's built-in vocabulary + # means other extension namespaces will be expanded, malformed JSON-LD + # attributes lost, and some values “unexpectedly” compacted this method + # patches the following likely sources of incompatibility: + # - 'https://www.w3.org/ns/activitystreams#Public' being compacted to + # 'as:Public' (for instance, pre-3.4.0 Mastodon does not understand + # 'as:Public') + # - single-item arrays being compacted to the item itself (`[foo]` being + # compacted to `foo`) + # + # It is not always possible for `patch_for_forwarding!` to produce a document + # deemed safe for forwarding. Use `safe_for_forwarding?` to check the status + # of the output document. + # + # @param original [Hash] The original JSON-LD document used as reference + # @param compacted [Hash] The compacted JSON-LD document to be patched + # @return [void] + def patch_for_forwarding!(original, compacted) + original.without('@context', 'signature').each do |key, value| + next if value.nil? || !compacted.key?(key) + + compacted_value = compacted[key] + if value.is_a?(Hash) && compacted_value.is_a?(Hash) + patch_for_forwarding!(value, compacted_value) + elsif value.is_a?(Array) + compacted_value = [compacted_value] unless compacted_value.is_a?(Array) + return if value.size != compacted_value.size + + compacted[key] = value.zip(compacted_value).map do |v, vc| + if v.is_a?(Hash) && vc.is_a?(Hash) + patch_for_forwarding!(v, vc) + vc + elsif v == 'https://www.w3.org/ns/activitystreams#Public' && vc == 'as:Public' + v + else + vc + end + end + elsif value == 'https://www.w3.org/ns/activitystreams#Public' && compacted_value == 'as:Public' + compacted[key] = value + end + end + end + + # Tests whether a JSON-LD compaction is deemed safe for redistribution, + # that is, if it doesn't change its meaning to consumers that do not actually + # handle JSON-LD, but rely on values being serialized in a certain way. + # + # See `patch_for_forwarding!` for details. + # + # @param original [Hash] The original JSON-LD document used as reference + # @param compacted [Hash] The compacted JSON-LD document to be patched + # @return [Boolean] Whether the patched document is deemed safe + def safe_for_forwarding?(original, compacted) + original.without('@context', 'signature').all? do |key, value| + compacted_value = compacted[key] + return false unless value.class == compacted_value.class + + if value.is_a?(Hash) + safe_for_forwarding?(value, compacted_value) + elsif value.is_a?(Array) + value.zip(compacted_value).all? do |v, vc| + v.is_a?(Hash) ? (vc.is_a?(Hash) && safe_for_forwarding?(v, vc)) : v == vc + end + else + value == compacted_value + end + end + end + def fetch_resource(uri, id, on_behalf_of = nil) unless id json = fetch_resource_without_id_validation(uri, on_behalf_of) diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index 5f3d63bb3..eb008c40a 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -5,13 +5,27 @@ class ActivityPub::ProcessCollectionService < BaseService def call(body, account, **options) @account = account - @json = Oj.load(body, mode: :strict) + @json = original_json = Oj.load(body, mode: :strict) @options = options - @json = compact(@json) if @json['signature'].is_a?(Hash) + begin + @json = compact(@json) if @json['signature'].is_a?(Hash) + rescue JSON::LD::JsonLdError => e + Rails.logger.debug "Error when compacting JSON-LD document for #{value_or_id(@json['actor'])}: #{e.message}" + @json = original_json.without('signature') + end return if !supported_context? || (different_actor? && verify_account!.nil?) || suspended_actor? || @account.local? + if @json['signature'].present? + # We have verified the signature, but in the compaction step above, might + # have introduced incompatibilities with other servers that do not + # normalize the JSON-LD documents (for instance, previous Mastodon + # versions), so skip redistribution if we can't get a safe document. + patch_for_forwarding!(original_json, @json) + @json.delete('signature') unless safe_for_forwarding?(original_json, @json) + end + case @json['type'] when 'Collection', 'CollectionPage' process_items @json['items'] diff --git a/spec/helpers/jsonld_helper_spec.rb b/spec/helpers/jsonld_helper_spec.rb index 883a88b14..744a14f26 100644 --- a/spec/helpers/jsonld_helper_spec.rb +++ b/spec/helpers/jsonld_helper_spec.rb @@ -89,4 +89,86 @@ describe JsonLdHelper do expect(fetch_resource_without_id_validation('https://host.test/')).to eq({}) end end + + context 'compaction and forwarding' do + let(:json) do + { + '@context' => [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { + 'obsolete' => 'http://ostatus.org#', + 'convo' => 'obsolete:conversation', + 'new' => 'https://obscure-unreleased-test.joinmastodon.org/#', + }, + ], + 'type' => 'Create', + 'to' => ['https://www.w3.org/ns/activitystreams#Public'], + 'object' => { + 'id' => 'https://example.com/status', + 'type' => 'Note', + 'inReplyTo' => nil, + 'convo' => 'https://example.com/conversation', + 'tag' => [ + { + 'type' => 'Mention', + 'href' => ['foo'], + } + ], + }, + 'signature' => { + 'type' => 'RsaSignature2017', + 'created' => '2022-02-02T12:00:00Z', + 'creator' => 'https://example.com/actor#main-key', + 'signatureValue' => 'some-sig', + }, + } + end + + describe '#compact' do + it 'properly compacts JSON-LD with alternative context definitions' do + expect(compact(json).dig('object', 'conversation')).to eq 'https://example.com/conversation' + end + + it 'compacts single-item arrays' do + expect(compact(json).dig('object', 'tag', 'href')).to eq 'foo' + end + + it 'compacts the activistreams Public collection' do + expect(compact(json)['to']).to eq 'as:Public' + end + + it 'properly copies signature' do + expect(compact(json)['signature']).to eq json['signature'] + end + end + + describe 'patch_for_forwarding!' do + it 'properly patches incompatibilities' do + json['object'].delete('convo') + compacted = compact(json) + patch_for_forwarding!(json, compacted) + expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] + expect(compacted.dig('object', 'tag', 0, 'href')).to eq ['foo'] + expect(safe_for_forwarding?(json, compacted)).to eq true + end + end + + describe 'safe_for_forwarding?' do + it 'deems a safe compacting as such' do + json['object'].delete('convo') + compacted = compact(json) + deemed_compatible = patch_for_forwarding!(json, compacted) + expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] + expect(safe_for_forwarding?(json, compacted)).to eq true + end + + it 'deems an unsafe compacting as such' do + compacted = compact(json) + deemed_compatible = patch_for_forwarding!(json, compacted) + expect(compacted['to']).to eq ['https://www.w3.org/ns/activitystreams#Public'] + expect(safe_for_forwarding?(json, compacted)).to eq false + end + end + end end From 3413f1c44bd95980292f7efae5bb940c5e477cfc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 3 Feb 2022 14:21:38 +0100 Subject: [PATCH 04/14] Forward-port version bump to 3.4.6 (#17434) --- CHANGELOG.md | 16 ++++++++++++++++ lib/mastodon/version.rb | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9deff5a0d..8e9d6ea1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,28 @@ Changelog All notable changes to this project will be documented in this file. +## [3.4.6] - 2022-02-03 +### Fixed + +- Fix `mastodon:webpush:generate_vapid_key` task requiring a functional environment ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17338)) +- Fix spurious errors when receiving an Add activity for a private post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17425)) + +### Security + +- Fix error-prone SQL queries ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/15828)) +- Fix not compacting incoming signed JSON-LD activities ([puckipedia](https://github.com/mastodon/mastodon/pull/17426), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/17428)) (CVE-2022-24307) +- Fix insufficient sanitization of report comments ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17430)) +- Fix stop condition of a Common Table Expression ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17427)) +- Disable legacy XSS filtering ([Wonderfall](https://github.com/mastodon/mastodon/pull/17289)) + ## [3.4.5] - 2022-01-31 ### Added + - Add more advanced migration tests ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17393)) - Add github workflow to build Docker images ([unasuke](https://github.com/mastodon/mastodon/pull/16973), [Gargron](https://github.com/mastodon/mastodon/pull/16980), [Gargron](https://github.com/mastodon/mastodon/pull/17000)) ### Fixed + - Fix some old migrations failing when skipping releases ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17394)) - Fix migrations script failing in certain edge cases ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17398)) - Fix Docker build ([tribela](https://github.com/mastodon/mastodon/pull/17188)) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 1ba45aeca..d71b5b4ac 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,7 +13,7 @@ module Mastodon end def patch - 5 + 6 end def flags From 50ab3f3dcb6b00109fa1462a5ca0228563abb99b Mon Sep 17 00:00:00 2001 From: Alexandra Catalina Date: Thu, 3 Feb 2022 12:29:20 -0800 Subject: [PATCH 05/14] Update tootsuite/mastodon Docker tag to v3.4.6 (#17436) Co-authored-by: Renovate Bot --- chart/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chart/values.yaml b/chart/values.yaml index caac3eba0..dc476b1c5 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -8,7 +8,7 @@ image: # built from the most recent commit # # tag: latest - tag: v3.4.5 + tag: v3.4.6 # use `Always` when using `latest` tag pullPolicy: IfNotPresent From e0263c73694a75a881d2fb18dd825135e4a5ca4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Feb 2022 13:02:42 +0900 Subject: [PATCH 06/14] Bump http-link-header from 1.0.3 to 1.0.4 (#17414) Bumps [http-link-header](https://github.com/jhermsmeier/node-http-link-header) from 1.0.3 to 1.0.4. - [Release notes](https://github.com/jhermsmeier/node-http-link-header/releases) - [Changelog](https://github.com/jhermsmeier/node-http-link-header/blob/master/CHANGELOG.md) - [Commits](https://github.com/jhermsmeier/node-http-link-header/compare/v1.0.3...v1.0.4) --- updated-dependencies: - dependency-name: http-link-header dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e6e9e7a64..74a0ddd63 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "font-awesome": "^4.7.0", "glob": "^7.2.0", "history": "^4.10.1", - "http-link-header": "^1.0.3", + "http-link-header": "^1.0.4", "immutable": "^4.0.0", "imports-loader": "^1.2.0", "intersection-observer": "^0.12.0", diff --git a/yarn.lock b/yarn.lock index 9d161c006..2f78fb1f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5471,10 +5471,10 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-link-header@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.0.3.tgz#abbc2cdc5e06dd7e196a4983adac08a2d085ec90" - integrity sha512-nARK1wSKoBBrtcoESlHBx36c1Ln/gnbNQi1eB6MeTUefJIT3NvUOsV15bClga0k38f0q/kN5xxrGSDS3EFnm9w== +http-link-header@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.0.4.tgz#f4efc76c6151ed0ba0d1a2d679798a18854a4a99" + integrity sha512-Cnv3Q+FF+35avekdnH/ML8dls++tdnSgrvUIWw0YEszrWeLSuw5Iq1vyCVTb5v0rEUgFTy0x4shxXyrO0MDUzw== "http-parser-js@>=0.4.0 <0.4.11": version "0.4.10" From e001e116da86733d6179ffc3a2ead1e7a3cf8410 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Feb 2022 13:02:57 +0900 Subject: [PATCH 07/14] Bump sidekiq-scheduler from 3.1.0 to 3.1.1 (#17407) Bumps [sidekiq-scheduler](https://github.com/moove-it/sidekiq-scheduler) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/moove-it/sidekiq-scheduler/releases) - [Commits](https://github.com/moove-it/sidekiq-scheduler/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: sidekiq-scheduler dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index dc5b33964..f2e053765 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -208,7 +208,7 @@ GEM multi_json encryptor (3.0.0) erubi (1.10.0) - et-orbi (1.2.4) + et-orbi (1.2.6) tzinfo excon (0.76.0) fabrication (2.24.0) @@ -252,7 +252,7 @@ GEM fog-json (>= 1.0) ipaddress (>= 0.8) formatador (0.2.5) - fugit (1.4.5) + fugit (1.5.2) et-orbi (~> 1.1, >= 1.1.8) raabro (~> 1.4) fuubar (2.5.1) @@ -551,7 +551,7 @@ GEM nokogiri (>= 1.10.5) rexml ruby2_keywords (0.0.5) - rufus-scheduler (3.7.0) + rufus-scheduler (3.8.1) fugit (~> 1.1, >= 1.1.6) safety_net_attestation (0.4.0) jwt (~> 2.0) @@ -569,7 +569,7 @@ GEM redis (>= 4.2.0) sidekiq-bulk (0.2.0) sidekiq - sidekiq-scheduler (3.1.0) + sidekiq-scheduler (3.1.1) e2mmap redis (>= 3, < 5) rufus-scheduler (~> 3.2) From bfe5ad5fee3e0ccc8ab480b311af1cf3c8fdcb2c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Feb 2022 13:03:06 +0900 Subject: [PATCH 08/14] Bump redis from 4.0.2 to 4.0.3 (#17412) Bumps [redis](https://github.com/redis/node-redis) from 4.0.2 to 4.0.3. - [Release notes](https://github.com/redis/node-redis/releases) - [Changelog](https://github.com/redis/node-redis/blob/master/CHANGELOG.md) - [Commits](https://github.com/redis/node-redis/compare/redis@4.0.2...redis@4.0.3) --- updated-dependencies: - dependency-name: redis dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 40 +++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 74a0ddd63..ebbec6afc 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "react-swipeable-views": "^0.14.0", "react-textarea-autosize": "^8.3.3", "react-toggle": "^4.1.2", - "redis": "^4.0.2", + "redis": "^4.0.3", "redux": "^4.1.2", "redux-immutable": "^4.0.0", "redux-thunk": "^2.4.1", diff --git a/yarn.lock b/yarn.lock index 2f78fb1f7..158d3a1b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1384,32 +1384,37 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@node-redis/bloom@^1.0.0": +"@node-redis/bloom@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@node-redis/bloom/-/bloom-1.0.1.tgz#144474a0b7dc4a4b91badea2cfa9538ce0a1854e" integrity sha512-mXEBvEIgF4tUzdIN89LiYsbi6//EdpFA7L8M+DHCvePXg+bfHWi+ct5VI6nHUFQE5+ohm/9wmgihCH3HSkeKsw== -"@node-redis/client@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@node-redis/client/-/client-1.0.2.tgz#7f09fb739675728fbc6e73536f7cd1be99bf7b8f" - integrity sha512-C+gkx68pmTnxfV+y4pzasvCH3s4UGHNOAUNhdJxGI27aMdnXNDZct7ffDHBL7bAZSGv9FSwCP5PeYvEIEKGbiA== +"@node-redis/client@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@node-redis/client/-/client-1.0.3.tgz#ece282b7ee07283d744e6ab1fa72f2d47641402c" + integrity sha512-IXNgOG99PHGL3NxN3/e8J8MuX+H08I+OMNmheGmZBXngE0IntaCQwwrd7NzmiHA+zH3SKHiJ+6k3P7t7XYknMw== dependencies: cluster-key-slot "1.1.0" generic-pool "3.8.2" redis-parser "3.0.0" yallist "4.0.0" -"@node-redis/json@^1.0.2": +"@node-redis/graph@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@node-redis/graph/-/graph-1.0.0.tgz#baf8eaac4a400f86ea04d65ec3d65715fd7951ab" + integrity sha512-mRSo8jEGC0cf+Rm7q8mWMKKKqkn6EAnA9IA2S3JvUv/gaWW/73vil7GLNwion2ihTptAm05I9LkepzfIXUKX5g== + +"@node-redis/json@1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@node-redis/json/-/json-1.0.2.tgz#8ad2d0f026698dc1a4238cc3d1eb099a3bee5ab8" integrity sha512-qVRgn8WfG46QQ08CghSbY4VhHFgaTY71WjpwRBGEuqGPfWwfRcIf3OqSpR7Q/45X+v3xd8mvYjywqh0wqJ8T+g== -"@node-redis/search@^1.0.2": +"@node-redis/search@1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@node-redis/search/-/search-1.0.2.tgz#8cfc91006ea787df801d41410283e1f59027f818" integrity sha512-gWhEeji+kTAvzZeguUNJdMSZNH2c5dv3Bci8Nn2f7VGuf6IvvwuZDSBOuOlirLVgayVuWzAG7EhwaZWK1VDnWQ== -"@node-redis/time-series@^1.0.1": +"@node-redis/time-series@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@node-redis/time-series/-/time-series-1.0.1.tgz#703149f8fa4f6fff377c61a0873911e7c1ba5cc3" integrity sha512-+nTn6EewVj3GlUXPuD3dgheWqo219jTxlo6R+pg24OeVvFHx9aFGGiyOgj3vBPhWUdRZ0xMcujXV5ki4fbLyMw== @@ -9147,16 +9152,17 @@ redis-parser@3.0.0: dependencies: redis-errors "^1.0.0" -redis@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/redis/-/redis-4.0.2.tgz#096cf716842731a24f34c7c3a996c143e2b133bb" - integrity sha512-Ip1DJ/lwuvtJz9AZ6pl1Bv33fWzk5d3iQpGzsXpi04ErkT4fq0pfGOm4k/p9DHmPGieEIOWvJ9xmIeQMooLybg== +redis@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/redis/-/redis-4.0.3.tgz#f60931175de6f5b5727240a08e58a9ed5cf0f9de" + integrity sha512-SJMRXvgiQUYN0HaWwWv002J5ZgkhYXOlbLomzcrL3kP42yRNZ8Jx5nvLYhVpgmf10xcDpanFOxxJkphu2eyIFQ== dependencies: - "@node-redis/bloom" "^1.0.0" - "@node-redis/client" "^1.0.2" - "@node-redis/json" "^1.0.2" - "@node-redis/search" "^1.0.2" - "@node-redis/time-series" "^1.0.1" + "@node-redis/bloom" "1.0.1" + "@node-redis/client" "1.0.3" + "@node-redis/graph" "1.0.0" + "@node-redis/json" "1.0.2" + "@node-redis/search" "1.0.2" + "@node-redis/time-series" "1.0.1" redux-immutable@^4.0.0: version "4.0.0" From 6a649e91311b69d7a0c7c71dbb2e9662e6b06662 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Feb 2022 13:03:12 +0900 Subject: [PATCH 09/14] Bump brakeman from 5.2.0 to 5.2.1 (#17410) Bumps [brakeman](https://github.com/presidentbeef/brakeman) from 5.2.0 to 5.2.1. - [Release notes](https://github.com/presidentbeef/brakeman/releases) - [Changelog](https://github.com/presidentbeef/brakeman/blob/main/CHANGES.md) - [Commits](https://github.com/presidentbeef/brakeman/compare/v5.2.0...v5.2.1) --- updated-dependencies: - dependency-name: brakeman dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index f2e053765..5ecddec12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -106,7 +106,7 @@ GEM ffi (~> 1.14) bootsnap (1.10.2) msgpack (~> 1.2) - brakeman (5.2.0) + brakeman (5.2.1) browser (4.2.0) brpoplpush-redis_script (0.1.2) concurrent-ruby (~> 1.0, >= 1.0.5) From e03e7ac290f1458e105acc1bcfd7c0a3b04826ff Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 Feb 2022 05:06:34 +0100 Subject: [PATCH 10/14] Fix error on account relationships page in admin UI (#17444) --- .../admin/relationships_controller.rb | 3 ++- app/views/admin/relationships/index.html.haml | 23 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/controllers/admin/relationships_controller.rb b/app/controllers/admin/relationships_controller.rb index f8a95cfc8..085ded21c 100644 --- a/app/controllers/admin/relationships_controller.rb +++ b/app/controllers/admin/relationships_controller.rb @@ -9,7 +9,8 @@ module Admin def index authorize :account, :index? - @accounts = RelationshipFilter.new(@account, filter_params).results.page(params[:page]).per(PER_PAGE) + @accounts = RelationshipFilter.new(@account, filter_params).results.includes(:account_stat, user: [:ips, :invite_request]).page(params[:page]).per(PER_PAGE) + @form = Form::AccountBatch.new end private diff --git a/app/views/admin/relationships/index.html.haml b/app/views/admin/relationships/index.html.haml index 907477f24..60b9b5b25 100644 --- a/app/views/admin/relationships/index.html.haml +++ b/app/views/admin/relationships/index.html.haml @@ -24,16 +24,17 @@ %hr.spacer/ -.table-wrapper - %table.table - %thead - %tr - %th= t('admin.accounts.username') - %th= t('admin.accounts.role') - %th= t('admin.accounts.most_recent_ip') - %th= t('admin.accounts.most_recent_activity') - %th - %tbody - = render partial: 'admin/accounts/account', collection: @accounts += form_for(@form, url: batch_admin_accounts_path) do |f| + .batch-table + .batch-table__toolbar + %label.batch-table__toolbar__select.batch-checkbox-all + = check_box_tag :batch_checkbox_all, nil, false + .batch-table__toolbar__actions + = f.button safe_join([fa_icon('lock'), t('admin.accounts.perform_full_suspension')]), name: :suspend, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + .batch-table__body + - if @accounts.empty? + = nothing_here 'nothing-here--under-tabs' + - else + = render partial: 'admin/accounts/account', collection: @accounts, locals: { f: f } = paginate @accounts From 5f48ec9e4264065072d3ad67a1224df76cb892da Mon Sep 17 00:00:00 2001 From: Claire Date: Sat, 5 Feb 2022 10:27:24 +0100 Subject: [PATCH 11/14] Make theme-selection fall back to default ones if configured is not found --- app/controllers/application_controller.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 08cca0734..42f3081f1 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -137,13 +137,12 @@ class ApplicationController < ActionController::Base end def current_flavour - return Setting.flavour unless Themes.instance.flavours.include? current_user&.setting_flavour - current_user.setting_flavour + [current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) } end def current_skin - return Setting.skin unless Themes.instance.skins_for(current_flavour).include? current_user&.setting_skin - current_user.setting_skin + skins = Themes.instance.skins_for(current_flavour) + [current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } end def respond_with_error(code) From 08f44d1953d465825fd250452efbca6fc8d82dc3 Mon Sep 17 00:00:00 2001 From: Claire Date: Sat, 5 Feb 2022 10:58:51 +0100 Subject: [PATCH 12/14] Move glitch-soc-specific theming methods to ThemingConcern --- app/controllers/application_controller.rb | 9 --------- app/controllers/concerns/theming_concern.rb | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 42f3081f1..0f948ff5f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -136,15 +136,6 @@ class ApplicationController < ActionController::Base @current_session = SessionActivation.find_by(session_id: cookies.signed['_session_id']) if cookies.signed['_session_id'].present? end - def current_flavour - [current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) } - end - - def current_skin - skins = Themes.instance.skins_for(current_flavour) - [current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } - end - def respond_with_error(code) respond_to do |format| format.any do diff --git a/app/controllers/concerns/theming_concern.rb b/app/controllers/concerns/theming_concern.rb index 1ee3256c0..425554072 100644 --- a/app/controllers/concerns/theming_concern.rb +++ b/app/controllers/concerns/theming_concern.rb @@ -10,6 +10,15 @@ module ThemingConcern private + def current_flavour + [current_user&.setting_flavour, Setting.flavour, 'glitch', 'vanilla'].find { |flavour| Themes.instance.flavours.include?(flavour) } + end + + def current_skin + skins = Themes.instance.skins_for(current_flavour) + [current_user&.setting_skin, Setting.skin, 'default'].find { |skin| skins.include?(skin) } + end + def valid_pack_data?(data, pack_name) data['pack'].is_a?(Hash) && [String, Hash].any? { |c| data['pack'][pack_name].is_a?(c) } end From 097c4903f1755f6657631759cbcf237f2966ede3 Mon Sep 17 00:00:00 2001 From: potpro Date: Sun, 6 Feb 2022 01:29:54 +0900 Subject: [PATCH 13/14] Update build-image.yml (#17454) --- .github/workflows/build-image.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index 58f2813d3..0aaea6b1f 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - uses: docker/setup-qemu-action@v1 - uses: docker/setup-buildx-action@v1 - uses: docker/login-action@v1 with: @@ -28,6 +29,7 @@ jobs: - uses: docker/build-push-action@v2 with: context: . + platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} cache-from: type=registry,ref=tootsuite/mastodon:latest From 92658f0fb0cf6cb582126f41f7132bde80f77657 Mon Sep 17 00:00:00 2001 From: Claire Date: Sun, 6 Feb 2022 15:31:03 +0100 Subject: [PATCH 14/14] Fix instance actor not being dereferenceable (#17457) * Add tests * Fix instance actor not being dereferenceable * Fix tests * Fix tests for real --- app/controllers/instance_actors_controller.rb | 1 + .../instance_actors_controller_spec.rb | 55 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 spec/controllers/instance_actors_controller_spec.rb diff --git a/app/controllers/instance_actors_controller.rb b/app/controllers/instance_actors_controller.rb index b3b5476e2..0853897f2 100644 --- a/app/controllers/instance_actors_controller.rb +++ b/app/controllers/instance_actors_controller.rb @@ -3,6 +3,7 @@ class InstanceActorsController < ApplicationController include AccountControllerConcern + skip_before_action :check_account_confirmation skip_around_action :set_locale def show diff --git a/spec/controllers/instance_actors_controller_spec.rb b/spec/controllers/instance_actors_controller_spec.rb new file mode 100644 index 000000000..f64a7d2ca --- /dev/null +++ b/spec/controllers/instance_actors_controller_spec.rb @@ -0,0 +1,55 @@ +require 'rails_helper' + +RSpec.describe InstanceActorsController, type: :controller do + describe 'GET #show' do + context 'as JSON' do + let(:format) { 'json' } + + shared_examples 'shared behavior' do + before do + get :show, params: { format: format } + end + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns application/activity+json' do + expect(response.media_type).to eq 'application/activity+json' + end + + it 'does not set cookies' do + expect(response.cookies).to be_empty + expect(response.headers['Set-Cookies']).to be nil + end + + it 'does not set sessions' do + expect(session).to be_empty + end + + it 'returns public Cache-Control header' do + expect(response.headers['Cache-Control']).to include 'public' + end + + it 'renders account' do + json = body_as_json + expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey, :inbox, :outbox, :url) + end + end + + before do + allow(controller).to receive(:authorized_fetch_mode?).and_return(authorized_fetch_mode) + end + + context 'without authorized fetch mode' do + let(:authorized_fetch_mode) { false } + it_behaves_like 'shared behavior' + end + + context 'with authorized fetch mode' do + let(:authorized_fetch_mode) { true } + it_behaves_like 'shared behavior' + end + end + end +end