about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb53
-rw-r--r--app/models/concerns/account_associations.rb1
-rw-r--r--app/models/concerns/account_finder_concern.rb2
-rw-r--r--app/models/concerns/streamable.rb43
-rw-r--r--app/models/form/admin_settings.rb2
-rw-r--r--app/models/media_attachment.rb16
-rw-r--r--app/models/status.rb13
-rw-r--r--app/models/stream_entry.rb59
-rw-r--r--app/models/tag.rb4
-rw-r--r--app/models/user.rb2
10 files changed, 48 insertions, 147 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index 9cfacc1c0..63b026467 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -55,6 +55,7 @@
 #  force_private           :boolean          default(FALSE), not null
 #  unboostable             :boolean          default(FALSE), not null
 #  block_anon              :boolean          default(FALSE), not null
+#  trust_level             :integer
 #
 
 class Account < ApplicationRecord
@@ -77,6 +78,13 @@ class Account < ApplicationRecord
   MAX_FIELDS = (ENV['MAX_PROFILE_FIELDS'] || 4).to_i
 
   LOCAL_DOMAINS = ENV.fetch('LOCAL_DOMAINS', '').chomp.split(/\.?\s+/).freeze
+  TRUST_LEVELS = {
+    untrusted: 0,
+    trusted: 1,
+  }.freeze
+
+# TODO: Remove this line if commenting it doesn't cause the server to catch on fire
+#  enum protocol: [:ostatus, :activitypub]
 
   validates :username, presence: true
 
@@ -85,7 +93,7 @@ class Account < ApplicationRecord
   validates :username, format: { with: /\A#{USERNAME_RE}\z/i }, if: -> { !local? && will_save_change_to_username? }
 
   # Local user validations
-  validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 66 }, if: -> { local? && will_save_change_to_username? }
+  validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 66 }, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' }
   validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? }
   validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
   validates :display_name, length: { maximum: MAX_DISPLAY_NAME_LENGTH }, if: -> { local? && will_save_change_to_display_name? }
@@ -191,6 +199,10 @@ class Account < ApplicationRecord
     %w(Application Service).include? actor_type
   end
 
+  def instance_actor?
+    id == -99
+  end
+
   alias bot bot?
 
   def bot=(val)
@@ -217,9 +229,12 @@ class Account < ApplicationRecord
     last_webfingered_at.nil? || last_webfingered_at <= 1.day.ago
   end
 
+  def trust_level
+    self[:trust_level] || 0
+  end
+
   def refresh!
-    return if local?
-    ResolveAccountService.new.call(acct)
+    ResolveAccountService.new.call(acct) unless local?
   end
 
   def mark_unknown!
@@ -276,21 +291,19 @@ class Account < ApplicationRecord
     silenced_at.present?
   end
 
-  def silence!(date = nil)
-    date ||= Time.now.utc
+  def silence!(date = Time.now.utc)
     update!(silenced_at: date)
   end
 
   def unsilence!
-    update!(silenced_at: nil)
+    update!(silenced_at: nil, trust_level: trust_level == TRUST_LEVELS[:untrusted] ? TRUST_LEVELS[:trusted] : trust_level)
   end
 
   def suspended?
     suspended_at.present?
   end
 
-  def suspend!(date = nil)
-    date ||= Time.now.utc
+  def suspend!(date = Time.now.utc)
     transaction do
       user&.disable! if local?
       update!(suspended_at: date)
@@ -400,24 +413,14 @@ class Account < ApplicationRecord
     self.fields = tmp
   end
 
+## TODO: See if I need to follow the below advice
   # needs to be removed after migration
-  def vars
-    self[:vars]
-  end
-
-  def magic_key
-    modulus, exponent = [keypair.public_key.n, keypair.public_key.e].map do |component|
-      result = []
-
-      until component.zero?
-        result << [component % 256].pack('C')
-        component >>= 8
-      end
-
-      result.reverse.join
-    end
+#  def vars
+#    self[:vars]
+#  end
 
-    (['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.')
+  def subscription(webhook_url)
+    @subscription ||= OStatus2::Subscription.new(remote_url, secret: secret, webhook: webhook_url, hub: hub_url)
   end
 
   def save_with_optional_media!
@@ -626,7 +629,7 @@ class Account < ApplicationRecord
   end
 
   def generate_keys
-    return unless local? && !Rails.env.test?
+    return unless local? && private_key.blank? && public_key.blank?
 
     keypair = OpenSSL::PKey::RSA.new(2048)
     self.private_key = keypair.to_pem
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
index 19190f0c5..f60edbfcb 100644
--- a/app/models/concerns/account_associations.rb
+++ b/app/models/concerns/account_associations.rb
@@ -11,7 +11,6 @@ module AccountAssociations
     has_many :identity_proofs, class_name: 'AccountIdentityProof', dependent: :destroy, inverse_of: :account
 
     # Timelines
-    has_many :stream_entries, inverse_of: :account, dependent: :destroy
     has_many :statuses, inverse_of: :account, dependent: :destroy
     has_many :favourites, inverse_of: :account, dependent: :destroy
     has_many :bookmarks, inverse_of: :account, dependent: :destroy
diff --git a/app/models/concerns/account_finder_concern.rb b/app/models/concerns/account_finder_concern.rb
index ccd7bfa12..a54c2174d 100644
--- a/app/models/concerns/account_finder_concern.rb
+++ b/app/models/concerns/account_finder_concern.rb
@@ -13,7 +13,7 @@ module AccountFinderConcern
     end
 
     def representative
-      find_local(Setting.site_contact_username.strip.gsub(/\A@/, '')) || Account.local.without_suspended.first
+      Account.find(-99)
     end
 
     def find_local(username)
diff --git a/app/models/concerns/streamable.rb b/app/models/concerns/streamable.rb
deleted file mode 100644
index 7c9edb8ef..000000000
--- a/app/models/concerns/streamable.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module Streamable
-  extend ActiveSupport::Concern
-
-  included do
-    has_one :stream_entry, as: :activity
-
-    after_create do
-      account.stream_entries.create!(activity: self, hidden: hidden?) if needs_stream_entry?
-    end
-  end
-
-  def title
-    super
-  end
-
-  def content
-    title
-  end
-
-  def target
-    super
-  end
-
-  def object_type
-    :activity
-  end
-
-  def thread
-    super
-  end
-
-  def hidden?
-    false
-  end
-
-  private
-
-  def needs_stream_entry?
-    account.local?
-  end
-end
diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb
index 8eea46b18..f4631f901 100644
--- a/app/models/form/admin_settings.rb
+++ b/app/models/form/admin_settings.rb
@@ -37,6 +37,7 @@ class Form::AdminSettings
     auto_reject_unknown
     auto_mark_known
     werewolf_status
+    spam_check_enabled
   ).freeze
 
   BOOLEAN_KEYS = %i(
@@ -55,6 +56,7 @@ class Form::AdminSettings
     auto_reject_unknown
     auto_mark_known
     werewolf_status
+    spam_check_enabled
   ).freeze
 
   UPLOAD_KEYS = %i(
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index b5f7741b6..2c195c523 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -26,14 +26,14 @@ class MediaAttachment < ApplicationRecord
 
   enum type: [:image, :gifv, :video, :audio, :unknown]
 
-  IMAGE_FILE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp'].freeze
-  VIDEO_FILE_EXTENSIONS = ['.webm', '.mp4', '.m4v', '.mov'].freeze
-  AUDIO_FILE_EXTENSIONS = ['.mp3', '.m4a', '.wav', '.ogg', '.aac'].freeze
-
-  IMAGE_MIME_TYPES             = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
-  VIDEO_MIME_TYPES             = ['video/webm', 'video/mp4', 'video/quicktime'].freeze
-  VIDEO_CONVERTIBLE_MIME_TYPES = ['video/webm', 'video/quicktime'].freeze
-  AUDIO_MIME_TYPES             = ['audio/mpeg', 'audio/mp3', 'audio/mp4', 'audio/vnd.wav', 'audio/wav', 'audio/x-wav', 'audio/x-wave', 'audio/ogg', 'audio/flac',].freeze
+  IMAGE_FILE_EXTENSIONS = %w(.jpg .jpeg .png .gif .webp).freeze
+  VIDEO_FILE_EXTENSIONS = %w(.webm .mp4 .m4v .mov).freeze
+  AUDIO_FILE_EXTENSIONS = %w(.ogg .oga .mp3 .wav .flac .opus .aac .m4a .3gp).freeze
+
+  IMAGE_MIME_TYPES             = %w(image/jpeg image/png image/gif image/webp).freeze
+  VIDEO_MIME_TYPES             = %w(video/webm video/mp4 video/quicktime video/ogg).freeze
+  VIDEO_CONVERTIBLE_MIME_TYPES = %w(video/webm video/quicktime).freeze
+  AUDIO_MIME_TYPES             = %w(audio/wave audio/wav audio/x-wav audio/x-pn-wave audio/ogg audio/mpeg audio/mp3 audio/webm audio/flac audio/aac audio/m4a audio/3gpp).freeze
 
   BLURHASH_OPTIONS = {
     x_comp: 4,
diff --git a/app/models/status.rb b/app/models/status.rb
index 5954e7868..1c1f533bf 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -37,7 +37,6 @@ class Status < ApplicationRecord
   before_destroy :unlink_from_conversations
 
   include Paginable
-  include Streamable
   include Cacheable
   include StatusThreadingConcern
 
@@ -78,7 +77,6 @@ class Status < ApplicationRecord
   has_and_belongs_to_many :preview_cards
 
   has_one :notification, as: :activity, dependent: :destroy
-  has_one :stream_entry, as: :activity, inverse_of: :status
   has_one :status_stat, inverse_of: :status
   has_one :poll, inverse_of: :status, dependent: :destroy
   has_one :destructing_status, inverse_of: :status, dependent: :destroy
@@ -148,13 +146,11 @@ class Status < ApplicationRecord
                    :status_stat,
                    :tags,
                    :preview_cards,
-                   :stream_entry,
                    :preloadable_poll,
                    account: :account_stat,
                    active_mentions: { account: :account_stat },
                    reblog: [
                      :application,
-                     :stream_entry,
                      :tags,
                      :preview_cards,
                      :media_attachments,
@@ -253,7 +249,7 @@ class Status < ApplicationRecord
   end
 
   def hidden?
-    private_visibility? || direct_visibility? || limited_visibility?
+    !distributable?
   end
 
   def distributable?
@@ -750,7 +746,8 @@ class Status < ApplicationRecord
   end
 
   def update_statistics
-    return unless public_visibility? || unlisted_visibility?
+    return unless distributable?
+
     ActivityTracker.increment('activity:statuses:local')
   end
 
@@ -759,7 +756,7 @@ class Status < ApplicationRecord
 
     account&.increment_count!(:statuses_count)
     reblog&.increment_count!(:reblogs_count) if reblog?
-    thread&.increment_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
+    thread&.increment_count!(:replies_count) if in_reply_to_id.present? && distributable?
   end
 
   def decrement_counter_caches
@@ -767,7 +764,7 @@ class Status < ApplicationRecord
 
     account&.decrement_count!(:statuses_count)
     reblog&.decrement_count!(:reblogs_count) if reblog?
-    thread&.decrement_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
+    thread&.decrement_count!(:replies_count) if in_reply_to_id.present? && distributable?
   end
 
   def unlink_from_conversations
diff --git a/app/models/stream_entry.rb b/app/models/stream_entry.rb
deleted file mode 100644
index edd30487e..000000000
--- a/app/models/stream_entry.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-# == Schema Information
-#
-# Table name: stream_entries
-#
-#  id            :bigint(8)        not null, primary key
-#  activity_id   :bigint(8)
-#  activity_type :string
-#  created_at    :datetime         not null
-#  updated_at    :datetime         not null
-#  hidden        :boolean          default(FALSE), not null
-#  account_id    :bigint(8)
-#
-
-class StreamEntry < ApplicationRecord
-  include Paginable
-
-  belongs_to :account, inverse_of: :stream_entries
-  belongs_to :activity, polymorphic: true
-  belongs_to :status, foreign_type: 'Status', foreign_key: 'activity_id', inverse_of: :stream_entry
-
-  validates :account, :activity, presence: true
-
-  STATUS_INCLUDES = [:account, :stream_entry, :conversation, :media_attachments, :tags, mentions: :account, reblog: [:stream_entry, :account, :conversation, :media_attachments, :tags, mentions: :account], thread: [:stream_entry, :account]].freeze
-
-  default_scope { where(activity_type: 'Status') }
-  scope :recent, -> { reorder(id: :desc) }
-  scope :with_includes, -> { includes(:account, status: STATUS_INCLUDES) }
-
-  delegate :target, :title, :content, :thread, :local_only?,
-           to: :status,
-           allow_nil: true
-
-  def object_type
-    orphaned? || targeted? ? :activity : status.object_type
-  end
-
-  def verb
-    orphaned? ? :delete : status.verb
-  end
-
-  def targeted?
-    [:follow, :request_friend, :authorize, :reject, :unfollow, :block, :unblock, :share, :favorite].include? verb
-  end
-
-  def threaded?
-    (verb == :favorite || object_type == :comment) && !thread.nil?
-  end
-
-  def mentions
-    orphaned? ? [] : status.active_mentions.map(&:account)
-  end
-
-  private
-
-  def orphaned?
-    status.nil?
-  end
-end
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 87894a7b2..a1265b2a5 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -21,10 +21,10 @@ class Tag < ApplicationRecord
 
   has_one :account_tag_stat, dependent: :destroy
 
-  HASHTAG_NAME_RE = '[[:word:]:._\-]*[[:alpha:]:._·\-][[:word:]:._\-]*'
+  HASHTAG_NAME_RE = '([[:word:]_][[:word:]_·]*[[:alpha:]_·][[:word:]_·]*[[:word:]_])|([[:word:]_]*[[:alpha:]][[:word:]_]*)'
   HASHTAG_RE = /(?:^|[^\/\)\w])#(#{HASHTAG_NAME_RE})/i
 
-  validates :name, presence: true, uniqueness: true, format: { with: /\A#{HASHTAG_NAME_RE}\z/i }
+  validates :name, presence: true, uniqueness: true, format: { with: /\A(#{HASHTAG_NAME_RE})\z/i }
 
   scope :discoverable, -> { joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).where(account_tag_stats: { hidden: false }).order(Arel.sql('account_tag_stats.accounts_count desc')) }
   scope :hidden, -> { where(account_tag_stats: { hidden: true }) }
diff --git a/app/models/user.rb b/app/models/user.rb
index 96b6f1f58..733a34ef4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -179,6 +179,8 @@ class User < ApplicationRecord
     :aggregate_reblogs,
     :show_application,
     :default_content_type,
+    :use_blurhash,
+    :use_pending_items,
 
     :theme,
     :advanced_layout,