From a688a0b880a14eae4853641cb2dba45e137254ff Mon Sep 17 00:00:00 2001 From: fef Date: Sat, 3 Dec 2022 10:22:15 +0000 Subject: [PATCH] handle incoming custom emoji reactions properly --- app/lib/activitypub/activity.rb | 23 ++++++++++++--------- app/lib/activitypub/activity/emoji_react.rb | 8 ++++--- app/lib/activitypub/activity/like.rb | 6 +++--- app/models/concerns/account_interactions.rb | 4 ++-- app/models/status_reaction.rb | 7 ++++++- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index 29df445061..8324dfe715 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -179,24 +179,27 @@ class ActivityPub::Activity # Ensure all emojis declared in the activity's tags are # present in the database and downloaded to the local cache. - def process_emoji_tags - as_array(@object['tag']).each do |tag| - process_single_emoji(tag) if tag['type'] == 'Emoji' + # Required by EmojiReact and Like for emoji reactions. + def process_emoji_tags(tags) + as_array(tags).each do |tag| + process_single_emoji tag if tag['type'] == 'Emoji' end end def process_single_emoji(tag) - parser = ActivityPub::Parser::CustomEmojiParser.new(tag) - return if parser.shortcode.blank? || parser.image_remote_url.blank? + custom_emoji_parser = ActivityPub::Parser::CustomEmojiParser.new(tag) + return if custom_emoji_parser.shortcode.blank? || custom_emoji_parser.image_remote_url.blank? - emoji = CustomEmoji.find_by(shortcode: parser.shortcode, domain: @account.domain) + emoji = CustomEmoji.find_by(shortcode: custom_emoji_parser.shortcode, domain: @account.domain) return unless emoji.nil? || - parser.image_remote_url != emoji.image_remote_url || - (parser.updated_at && parser.updated_at >= emoji.updated_at) + custom_emoji_parser.image_remote_url != emoji.image_remote_url || + (custom_emoji_parser.updated_at && custom_emoji_parser.updated_at >= emoji.updated_at) begin - emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: parser.shortcode, uri: parser.uri) - emoji.image_remote_url = parser.image_remote_url + emoji ||= CustomEmoji.new(domain: @account.domain, + shortcode: custom_emoji_parser.shortcode, + uri: custom_emoji_parser.uri) + emoji.image_remote_url = custom_emoji_parser.image_remote_url emoji.save rescue Seahorse::Client::NetworkingError => e Rails.logger.warn "Error fetching emoji: #{e}" diff --git a/app/lib/activitypub/activity/emoji_react.rb b/app/lib/activitypub/activity/emoji_react.rb index c3d50b1e05..2730270fc7 100644 --- a/app/lib/activitypub/activity/emoji_react.rb +++ b/app/lib/activitypub/activity/emoji_react.rb @@ -9,14 +9,16 @@ class ActivityPub::Activity::EmojiReact < ActivityPub::Activity delete_arrived_first?(@json['id']) || @account.reacted?(original_status, name) + custom_emoji = nil if name =~ /^:.*:$/ - process_emoji_tags + process_emoji_tags(@json['tag']) name.delete! ':' - return if CustomEmoji.find_by(shortcode: name, domain: @account.domain).nil? + custom_emoji = CustomEmoji.find_by(shortcode: name, domain: @account.domain) + return if custom_emoji.nil? end - reaction = original_status.status_reactions.create!(account: @account, name: name) + reaction = original_status.status_reactions.create!(account: @account, name: name, custom_emoji: custom_emoji) LocalNotificationWorker.perform_async(original_status.account_id, reaction.id, 'StatusReaction', 'reaction') end diff --git a/app/lib/activitypub/activity/like.rb b/app/lib/activitypub/activity/like.rb index 311a58d3cd..66d8e59c8f 100644 --- a/app/lib/activitypub/activity/like.rb +++ b/app/lib/activitypub/activity/like.rb @@ -23,16 +23,16 @@ class ActivityPub::Activity::Like < ActivityPub::Activity custom_emoji = nil if name =~ /^:.*:$/ - process_emoji_tags + process_emoji_tags(@json['tag']) name.delete! ':' custom_emoji = CustomEmoji.find_by(shortcode: name, domain: @account.domain) return false if custom_emoji.nil? # invalid custom emoji, treat it as a regular like end - return true if @account.reacted?(original_status, name, custom_emoji) + return true if @account.reacted?(original_status, name) reaction = original_status.status_reactions.create!(account: @account, name: name, custom_emoji: custom_emoji) LocalNotificationWorker.perform_async(original_status.account_id, reaction.id, 'StatusReaction', 'reaction') - return true + true end end diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb index b8dd7e4d01..f93dfecc59 100644 --- a/app/models/concerns/account_interactions.rb +++ b/app/models/concerns/account_interactions.rb @@ -235,8 +235,8 @@ module AccountInteractions status.proper.favourites.where(account: self).exists? end - def reacted?(status, name, custom_emoji = nil) - status.proper.status_reactions.where(account: self, name: name, custom_emoji: custom_emoji).exists? + def reacted?(status, name) + status.proper.status_reactions.where(account: self, name: name).exists? end def bookmarked?(status) diff --git a/app/models/status_reaction.rb b/app/models/status_reaction.rb index 32cb9edd4a..4793ff9aa3 100644 --- a/app/models/status_reaction.rb +++ b/app/models/status_reaction.rb @@ -24,6 +24,11 @@ class StatusReaction < ApplicationRecord private def set_custom_emoji - self.custom_emoji = CustomEmoji.local.find_by(disabled: false, shortcode: name) if name.present? + return if name.blank? + self.custom_emoji = if account.local? + CustomEmoji.local.find_by(disabled: false, shortcode: name) + else + CustomEmoji.find_by(shortcode: name, domain: account.domain) + end end end