Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix most backend issues #4

21 changes: 10 additions & 11 deletions app/lib/activitypub/activity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -179,23 +179,20 @@ def reject_payload!
nil
end

# Ensure all emojis declared in the activity's tags are
# Ensure emoji declared in the activity's tags are
# present in the database and downloaded to the local cache.
# 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_emoji_tags(name, tags)
tag = as_array(tags).find { |item| item['type'] == 'Emoji' }
return if tag.nil?

def process_single_emoji(tag)
custom_emoji_parser = ActivityPub::Parser::CustomEmojiParser.new(tag)
return if custom_emoji_parser.shortcode.blank? || custom_emoji_parser.image_remote_url.blank?
return if custom_emoji_parser.shortcode.blank? || custom_emoji_parser.image_remote_url.blank? || !name.eql?(custom_emoji_parser.shortcode)

emoji = CustomEmoji.find_by(shortcode: custom_emoji_parser.shortcode, domain: @account.domain)
return unless emoji.nil? ||
custom_emoji_parser.image_remote_url != emoji.image_remote_url ||
(custom_emoji_parser.updated_at && custom_emoji_parser.updated_at >= emoji.updated_at)
return emoji unless emoji.nil? ||
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,
Expand All @@ -205,6 +202,8 @@ def process_single_emoji(tag)
emoji.save
rescue Seahorse::Client::NetworkingError => e
Rails.logger.warn "Error fetching emoji: #{e}"
return
end
emoji
end
end
13 changes: 7 additions & 6 deletions app/lib/activitypub/activity/emoji_react.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ def perform
name = @json['content']
return if original_status.nil? ||
!original_status.account.local? ||
delete_arrived_first?(@json['id']) ||
@account.reacted?(original_status, name)
delete_arrived_first?(@json['id'])

custom_emoji = nil
if /^:.*:$/.match?(name)
process_emoji_tags(@json['tag'])

name.delete! ':'
custom_emoji = CustomEmoji.find_by(shortcode: name, domain: @account.domain)
custom_emoji = process_emoji_tags(@json['tag'])

return if custom_emoji.nil?
end

return if @account.reacted?(original_status, name, custom_emoji)

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')
rescue ActiveRecord::RecordInvalid
nil
end
end
16 changes: 9 additions & 7 deletions app/lib/activitypub/activity/like.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ def perform
original_status = status_from_uri(object_uri)
return if original_status.nil? || !original_status.account.local? || delete_arrived_first?(@json['id'])

return if maybe_process_misskey_reaction(original_status)
return if maybe_process_misskey_reaction

return if @account.favourited?(original_status)

Expand All @@ -17,22 +17,24 @@ def perform

# Misskey delivers reactions as likes with the emoji in _misskey_reaction
# see https://misskey-hub.net/ns.html#misskey-reaction for details
def maybe_process_misskey_reaction(original_status)
def maybe_process_misskey_reaction
original_status = status_from_uri(object_uri)
name = @json['_misskey_reaction']
return false if name.nil?

custom_emoji = nil
if /^:.*:$/.match?(name)
process_emoji_tags(@json['tag'])

name.delete! ':'
custom_emoji = CustomEmoji.find_by(shortcode: name, domain: @account.domain)
custom_emoji = process_emoji_tags(@json['tag'])

return false if custom_emoji.nil? # invalid custom emoji, treat it as a regular like
end
return true if @account.reacted?(original_status, name)
return true if @account.reacted?(original_status, name, custom_emoji)

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')
true
# account tried to react with disabled custom emoji. Returning true to discard activity.
rescue ActiveRecord::RecordInvalid
true
end
end
13 changes: 11 additions & 2 deletions app/lib/activitypub/activity/undo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,29 @@ def undo_like
if @account.favourited?(status)
favourite = status.favourites.where(account: @account).first
favourite&.destroy
elsif @object['_misskey_reaction'].present?
undo_emoji_react
else
delete_later!(object_uri)
end
end

def undo_emoji_react
name = @object['content']
name = @object['content'] || @object['_misskey_reaction']
return if name.nil?

status = status_from_uri(target_uri)

return if status.nil? || !status.account.local?

if @account.reacted?(status, name.delete(':'))
if /^:.*:$/.match?(name)
name.delete! ':'
custom_emoji = process_emoji_tags(name, @object['tag'])

return if custom_emoji.nil?
end

if @account.reacted?(status, name, custom_emoji)
reaction = status.status_reactions.where(account: @account, name: name).first
reaction&.destroy
else
Expand Down
4 changes: 2 additions & 2 deletions app/models/concerns/account_interactions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ def favourited?(status)
status.proper.favourites.where(account: self).exists?
end

def reacted?(status, name)
status.proper.status_reactions.where(account: self, name: name).exists?
def reacted?(status, name, custom_emoji = nil)
status.proper.status_reactions.where(account: self, name: name, custom_emoji: custom_emoji).exists?
end

def bookmarked?(status)
Expand Down
2 changes: 1 addition & 1 deletion app/models/status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def reactions(account = nil)
if account.nil?
scope.select('name, custom_emoji_id, count(*) as count, false as me')
else
scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from status_reactions r where r.account_id = #{account.id} and r.status_id = status_reactions.status_id and r.name = status_reactions.name) as me")
scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from status_reactions r where r.account_id = #{account.id} and r.status_id = status_reactions.status_id and r.name = status_reactions.name and (r.custom_emoji_id = status_reactions.custom_emoji_id or r.custom_emoji_id is null and status_reactions.custom_emoji_id is null)) as me")
end
end

Expand Down
3 changes: 2 additions & 1 deletion app/models/status_reaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class StatusReaction < ApplicationRecord

private

# Sets custom_emoji to nil when disabled
def set_custom_emoji
self.custom_emoji = CustomEmoji.find_by(shortcode: name, domain: account.domain) if name.blank?
self.custom_emoji = CustomEmoji.find_by(disabled: false, shortcode: name, domain: custom_emoji.domain) if name.present? && custom_emoji.present?
end
end
2 changes: 2 additions & 0 deletions app/services/react_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def call(account, status, emoji)
authorize_with account, status, :react?

name, domain = emoji.split('@')
return unless domain.nil? || status.local?

custom_emoji = CustomEmoji.find_by(shortcode: name, domain: domain)
reaction = StatusReaction.find_by(account: account, status: status, name: name, custom_emoji: custom_emoji)
return reaction unless reaction.nil?
Expand Down
2 changes: 1 addition & 1 deletion app/validators/status_reaction_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def unicode_emoji?(name)
end

def new_reaction?(reaction)
!reaction.status.status_reactions.exists?(status: reaction.status, account: reaction.account, name: reaction.name)
!reaction.status.status_reactions.exists?(status: reaction.status, account: reaction.account, name: reaction.name, custom_emoji: reaction.custom_emoji)
end

def limit_reached?(reaction)
Expand Down