about summary refs log tree commit diff
path: root/app/services/notify_service.rb
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-11-14 21:12:57 +0100
committerGitHub <noreply@github.com>2017-11-14 21:12:57 +0100
commitfbef909c2a1ff8d24811f76237e62fbef6cc63cc (patch)
tree935c852c30ee793ce881a719ae367d49e4a8684a /app/services/notify_service.rb
parentc3ec1e87b8c19487c954b0cc571b426b4d5b53fa (diff)
Add option to block direct messages from people you don't follow (#5669)
* Add option to block direct messages from people you don't follow

Fix #5326

* If the DM responds to a toot by recipient, allow it through

* i18n: Update Polish translation (for #5669) (#5673)
Diffstat (limited to 'app/services/notify_service.rb')
-rw-r--r--app/services/notify_service.rb59
1 files changed, 50 insertions, 9 deletions
diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb
index ca53c61c5..6a24a8247 100644
--- a/app/services/notify_service.rb
+++ b/app/services/notify_service.rb
@@ -36,17 +36,58 @@ class NotifyService < BaseService
     false
   end
 
+  def following_sender?
+    return @following_sender if defined?(@following_sender)
+    @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account)
+  end
+
+  def optional_non_follower?
+    @recipient.user.settings.interactions['must_be_follower']  && !@notification.from_account.following?(@recipient)
+  end
+
+  def optional_non_following?
+    @recipient.user.settings.interactions['must_be_following'] && !following_sender?
+  end
+
+  def direct_message?
+    @notification.type == :mention && @notification.target_status.direct_visibility?
+  end
+
+  def response_to_recipient?
+    @notification.target_status.in_reply_to_account_id == @recipient.id
+  end
+
+  def optional_non_following_and_direct?
+    direct_message? &&
+      @recipient.user.settings.interactions['must_be_following_dm'] &&
+      !following_sender? &&
+      !response_to_recipient?
+  end
+
+  def hellbanned?
+    @notification.from_account.silenced? && !following_sender?
+  end
+
+  def from_self?
+    @recipient.id == @notification.from_account.id
+  end
+
+  def domain_blocking?
+    @recipient.domain_blocking?(@notification.from_account.domain) && !following_sender?
+  end
+
   def blocked?
-    blocked   = @recipient.suspended?                                                                                                # Skip if the recipient account is suspended anyway
-    blocked ||= @recipient.id == @notification.from_account.id                                                                       # Skip for interactions with self
-    blocked ||= @recipient.domain_blocking?(@notification.from_account.domain) && !@recipient.following?(@notification.from_account) # Skip for domain blocked accounts
-    blocked ||= @recipient.blocking?(@notification.from_account)                                                                     # Skip for blocked accounts
-    blocked ||= @recipient.muting?(@notification.from_account)                                                                       # Skip for muted accounts
-    blocked ||= (@notification.from_account.silenced? && !@recipient.following?(@notification.from_account))                         # Hellban
-    blocked ||= (@recipient.user.settings.interactions['must_be_follower']  && !@notification.from_account.following?(@recipient))   # Options
-    blocked ||= (@recipient.user.settings.interactions['must_be_following'] && !@recipient.following?(@notification.from_account))   # Options
+    blocked   = @recipient.suspended?                            # Skip if the recipient account is suspended anyway
+    blocked ||= from_self?                                       # Skip for interactions with self
+    blocked ||= domain_blocking?                                 # Skip for domain blocked accounts
+    blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
+    blocked ||= @recipient.muting?(@notification.from_account)   # Skip for muted accounts
+    blocked ||= hellbanned?                                      # Hellban
+    blocked ||= optional_non_follower?                           # Options
+    blocked ||= optional_non_following?                          # Options
+    blocked ||= optional_non_following_and_direct?               # Options
     blocked ||= conversation_muted?
-    blocked ||= send("blocked_#{@notification.type}?")                                                                               # Type-dependent filters
+    blocked ||= send("blocked_#{@notification.type}?")           # Type-dependent filters
     blocked
   end