about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorSurinna Curtis <ekiru.0@gmail.com>2017-11-16 01:38:26 -0600
committerGitHub <noreply@github.com>2017-11-16 01:38:26 -0600
commitee560abdbe7a2caf0f7ac6137faf248bbaff9a93 (patch)
treefcd9bdb5ba49ab7a6a79590c74db858ae77b4239 /app/models
parent88627fd7aa2493a6890d60a5965459e4c7fe6fe9 (diff)
parent35fbdc36f92b610e8a73e2acb220e87cf5fc83b0 (diff)
Merge pull request #216 from glitch-soc/merge-upstream-3023725
Merge upstream at commit 3023725
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb19
-rw-r--r--app/models/account_domain_block.rb4
-rw-r--r--app/models/account_moderation_note.rb6
-rw-r--r--app/models/block.rb6
-rw-r--r--app/models/concerns/account_interactions.rb5
-rw-r--r--app/models/conversation.rb2
-rw-r--r--app/models/conversation_mute.rb6
-rw-r--r--app/models/custom_emoji.rb4
-rw-r--r--app/models/domain_block.rb2
-rw-r--r--app/models/email_domain_block.rb25
-rw-r--r--app/models/favourite.rb6
-rw-r--r--app/models/follow.rb6
-rw-r--r--app/models/follow_request.rb10
-rw-r--r--app/models/import.rb4
-rw-r--r--app/models/media_attachment.rb6
-rw-r--r--app/models/mention.rb6
-rw-r--r--app/models/mute.rb6
-rw-r--r--app/models/notification.rb8
-rw-r--r--app/models/preview_card.rb2
-rw-r--r--app/models/report.rb8
-rw-r--r--app/models/session_activation.rb14
-rw-r--r--app/models/setting.rb4
-rw-r--r--app/models/site_upload.rb2
-rw-r--r--app/models/status.rb14
-rw-r--r--app/models/status_pin.rb6
-rw-r--r--app/models/stream_entry.rb6
-rw-r--r--app/models/subscription.rb4
-rw-r--r--app/models/tag.rb2
-rw-r--r--app/models/user.rb82
-rw-r--r--app/models/web/push_subscription.rb2
-rw-r--r--app/models/web/setting.rb4
31 files changed, 168 insertions, 113 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index 85684c259..863bfaa25 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -3,7 +3,7 @@
 #
 # Table name: accounts
 #
-#  id                      :integer          not null, primary key
+#  id                      :bigint           not null, primary key
 #  username                :string           default(""), not null
 #  domain                  :string
 #  secret                  :string           default(""), not null
@@ -41,10 +41,11 @@
 #  shared_inbox_url        :string           default(""), not null
 #  followers_url           :string           default(""), not null
 #  protocol                :integer          default("ostatus"), not null
+#  memorial                :boolean          default(FALSE), not null
 #
 
 class Account < ApplicationRecord
-  MENTION_RE = /(?:^|[^\/[:word:]])@(([a-z0-9_]+)(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
+  MENTION_RE = /(?<=^|[^\/[:word:]])@(([a-z0-9_]+)(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i
 
   include AccountAvatar
   include AccountFinderConcern
@@ -152,6 +153,20 @@ class Account < ApplicationRecord
     ResolveRemoteAccountService.new.call(acct)
   end
 
+  def unsuspend!
+    transaction do
+      user&.enable! if local?
+      update!(suspended: false)
+    end
+  end
+
+  def memorialize!
+    transaction do
+      user&.disable! if local?
+      update!(memorial: true)
+    end
+  end
+
   def keypair
     @keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
   end
diff --git a/app/models/account_domain_block.rb b/app/models/account_domain_block.rb
index fb695e473..9c98ec2a6 100644
--- a/app/models/account_domain_block.rb
+++ b/app/models/account_domain_block.rb
@@ -6,8 +6,8 @@
 #  domain     :string
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
-#  account_id :integer
-#  id         :integer          not null, primary key
+#  account_id :bigint
+#  id         :bigint           not null, primary key
 #
 
 class AccountDomainBlock < ApplicationRecord
diff --git a/app/models/account_moderation_note.rb b/app/models/account_moderation_note.rb
index 3ac9b1ac1..06f464850 100644
--- a/app/models/account_moderation_note.rb
+++ b/app/models/account_moderation_note.rb
@@ -3,10 +3,10 @@
 #
 # Table name: account_moderation_notes
 #
-#  id                :integer          not null, primary key
+#  id                :bigint           not null, primary key
 #  content           :text             not null
-#  account_id        :integer          not null
-#  target_account_id :integer          not null
+#  account_id        :bigint           not null
+#  target_account_id :bigint           not null
 #  created_at        :datetime         not null
 #  updated_at        :datetime         not null
 #
diff --git a/app/models/block.rb b/app/models/block.rb
index a913782ed..5778f7e90 100644
--- a/app/models/block.rb
+++ b/app/models/block.rb
@@ -5,9 +5,9 @@
 #
 #  created_at        :datetime         not null
 #  updated_at        :datetime         not null
-#  account_id        :integer          not null
-#  id                :integer          not null, primary key
-#  target_account_id :integer          not null
+#  account_id        :bigint           not null
+#  id                :bigint           not null, primary key
+#  target_account_id :bigint           not null
 #
 
 class Block < ApplicationRecord
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index a68f7c3d8..c41f92581 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -23,7 +23,7 @@ module AccountInteractions
     def muting_map(target_account_ids, account_id)
       Mute.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |mute, mapping|
         mapping[mute.target_account_id] = {
-          notifications: mute.hide_notifications?
+          notifications: mute.hide_notifications?,
         }
       end
     end
@@ -91,8 +91,7 @@ module AccountInteractions
     mute = mute_relationships.create_with(hide_notifications: notifications).find_or_create_by!(target_account: other_account)
     # When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't.
     if mute.hide_notifications? != notifications
-      mute.hide_notifications = notifications
-      mute.save!
+      mute.update!(hide_notifications: notifications)
     end
   end
 
diff --git a/app/models/conversation.rb b/app/models/conversation.rb
index 08c1ce945..e08532522 100644
--- a/app/models/conversation.rb
+++ b/app/models/conversation.rb
@@ -3,7 +3,7 @@
 #
 # Table name: conversations
 #
-#  id         :integer          not null, primary key
+#  id         :bigint           not null, primary key
 #  uri        :string
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
diff --git a/app/models/conversation_mute.rb b/app/models/conversation_mute.rb
index 8d2399adf..316865bd2 100644
--- a/app/models/conversation_mute.rb
+++ b/app/models/conversation_mute.rb
@@ -3,9 +3,9 @@
 #
 # Table name: conversation_mutes
 #
-#  conversation_id :integer          not null
-#  account_id      :integer          not null
-#  id              :integer          not null, primary key
+#  conversation_id :bigint           not null
+#  account_id      :bigint           not null
+#  id              :bigint           not null, primary key
 #
 
 class ConversationMute < ApplicationRecord
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index 28b6a2b0b..5723ebd5d 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -3,7 +3,7 @@
 #
 # Table name: custom_emojis
 #
-#  id                 :integer          not null, primary key
+#  id                 :bigint           not null, primary key
 #  shortcode          :string           default(""), not null
 #  domain             :string
 #  image_file_name    :string
@@ -25,6 +25,8 @@ class CustomEmoji < ApplicationRecord
     :(#{SHORTCODE_RE_FRAGMENT}):
     (?=[^[:alnum:]:]|$)/x
 
+  has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode
+
   has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce -strip' } }
 
   validates_attachment :image, content_type: { content_type: 'image/png' }, presence: true, size: { in: 0..50.kilobytes }
diff --git a/app/models/domain_block.rb b/app/models/domain_block.rb
index 1268290bc..557d0a19c 100644
--- a/app/models/domain_block.rb
+++ b/app/models/domain_block.rb
@@ -8,7 +8,7 @@
 #  updated_at   :datetime         not null
 #  severity     :integer          default("silence")
 #  reject_media :boolean          default(FALSE), not null
-#  id           :integer          not null, primary key
+#  id           :bigint           not null, primary key
 #
 
 class DomainBlock < ApplicationRecord
diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb
index 839038bea..2c348197c 100644
--- a/app/models/email_domain_block.rb
+++ b/app/models/email_domain_block.rb
@@ -3,15 +3,34 @@
 #
 # Table name: email_domain_blocks
 #
-#  id         :integer          not null, primary key
-#  domain     :string           not null
+#  id         :bigint           not null, primary key
+#  domain     :string           default(""), not null
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
 #
 
 class EmailDomainBlock < ApplicationRecord
+  before_validation :normalize_domain
+
+  validates :domain, presence: true, uniqueness: true
+
   def self.block?(email)
-    domain = email.gsub(/.+@([^.]+)/, '\1')
+    _, domain = email.split('@', 2)
+
+    return true if domain.nil?
+
+    begin
+      domain = TagManager.instance.normalize_domain(domain)
+    rescue Addressable::URI::InvalidURIError
+      return true
+    end
+
     where(domain: domain).exists?
   end
+
+  private
+
+  def normalize_domain
+    self.domain = TagManager.instance.normalize_domain(domain)
+  end
 end
diff --git a/app/models/favourite.rb b/app/models/favourite.rb
index d28d5c05b..f611aa6a9 100644
--- a/app/models/favourite.rb
+++ b/app/models/favourite.rb
@@ -5,9 +5,9 @@
 #
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
-#  account_id :integer          not null
-#  id         :integer          not null, primary key
-#  status_id  :integer          not null
+#  account_id :bigint           not null
+#  id         :bigint           not null, primary key
+#  status_id  :bigint           not null
 #
 
 class Favourite < ApplicationRecord
diff --git a/app/models/follow.rb b/app/models/follow.rb
index a8ddcb7f0..ea00a377a 100644
--- a/app/models/follow.rb
+++ b/app/models/follow.rb
@@ -5,9 +5,9 @@
 #
 #  created_at        :datetime         not null
 #  updated_at        :datetime         not null
-#  account_id        :integer          not null
-#  id                :integer          not null, primary key
-#  target_account_id :integer          not null
+#  account_id        :bigint          not null
+#  id                :bigint          not null, primary key
+#  target_account_id :bigint          not null
 #  show_reblogs      :boolean          default(TRUE), not null
 #
 
diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb
index 1a1c52382..962b61411 100644
--- a/app/models/follow_request.rb
+++ b/app/models/follow_request.rb
@@ -5,9 +5,9 @@
 #
 #  created_at        :datetime         not null
 #  updated_at        :datetime         not null
-#  account_id        :integer          not null
-#  id                :integer          not null, primary key
-#  target_account_id :integer          not null
+#  account_id        :bigint          not null
+#  id                :bigint          not null, primary key
+#  target_account_id :bigint          not null
 #  show_reblogs      :boolean          default(TRUE), not null
 #
 
@@ -28,7 +28,5 @@ class FollowRequest < ApplicationRecord
     destroy!
   end
 
-  def reject!
-    destroy!
-  end
+  alias reject! destroy!
 end
diff --git a/app/models/import.rb b/app/models/import.rb
index 8ae7e3a46..6f1278556 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -11,8 +11,8 @@
 #  data_content_type :string
 #  data_file_size    :integer
 #  data_updated_at   :datetime
-#  account_id        :integer          not null
-#  id                :integer          not null, primary key
+#  account_id        :bigint           not null
+#  id                :bigint           not null, primary key
 #
 
 class Import < ApplicationRecord
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index f6c8879c5..7a553f703 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -3,14 +3,14 @@
 #
 # Table name: media_attachments
 #
-#  id                :integer          not null, primary key
-#  status_id         :integer
+#  id                :bigint           not null, primary key
+#  status_id         :bigint
 #  file_file_name    :string
 #  file_content_type :string
 #  file_file_size    :integer
 #  file_updated_at   :datetime
 #  remote_url        :string           default(""), not null
-#  account_id        :integer
+#  account_id        :bigint
 #  created_at        :datetime         not null
 #  updated_at        :datetime         not null
 #  shortcode         :string
diff --git a/app/models/mention.rb b/app/models/mention.rb
index 3700c781c..fc089d365 100644
--- a/app/models/mention.rb
+++ b/app/models/mention.rb
@@ -3,11 +3,11 @@
 #
 # Table name: mentions
 #
-#  status_id  :integer
+#  status_id  :bigint
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
-#  account_id :integer
-#  id         :integer          not null, primary key
+#  account_id :bigint
+#  id         :bigint           not null, primary key
 #
 
 class Mention < ApplicationRecord
diff --git a/app/models/mute.rb b/app/models/mute.rb
index bcd3d247c..74b445c0b 100644
--- a/app/models/mute.rb
+++ b/app/models/mute.rb
@@ -3,11 +3,11 @@
 #
 # Table name: mutes
 #
+#  id                 :bigint          not null, primary key
 #  created_at         :datetime         not null
 #  updated_at         :datetime         not null
-#  account_id         :integer          not null
-#  id                 :integer          not null, primary key
-#  target_account_id  :integer          not null
+#  account_id         :bigint          not null
+#  target_account_id  :bigint          not null
 #  hide_notifications :boolean          default(TRUE), not null
 #
 
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 0a5d987cf..c88af9021 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -3,13 +3,13 @@
 #
 # Table name: notifications
 #
-#  id              :integer          not null, primary key
-#  account_id      :integer
-#  activity_id     :integer
+#  id              :bigint           not null, primary key
+#  account_id      :bigint
+#  activity_id     :bigint
 #  activity_type   :string
 #  created_at      :datetime         not null
 #  updated_at      :datetime         not null
-#  from_account_id :integer
+#  from_account_id :bigint
 #
 
 class Notification < ApplicationRecord
diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb
index e2bf65d94..63c04b410 100644
--- a/app/models/preview_card.rb
+++ b/app/models/preview_card.rb
@@ -3,7 +3,7 @@
 #
 # Table name: preview_cards
 #
-#  id                 :integer          not null, primary key
+#  id                 :bigint           not null, primary key
 #  url                :string           default(""), not null
 #  title              :string           default(""), not null
 #  description        :string           default(""), not null
diff --git a/app/models/report.rb b/app/models/report.rb
index bffb42b48..99c90b7dd 100644
--- a/app/models/report.rb
+++ b/app/models/report.rb
@@ -8,10 +8,10 @@
 #  action_taken               :boolean          default(FALSE), not null
 #  created_at                 :datetime         not null
 #  updated_at                 :datetime         not null
-#  account_id                 :integer          not null
-#  action_taken_by_account_id :integer
-#  id                         :integer          not null, primary key
-#  target_account_id          :integer          not null
+#  account_id                 :bigint           not null
+#  action_taken_by_account_id :bigint
+#  id                         :bigint           not null, primary key
+#  target_account_id          :bigint           not null
 #
 
 class Report < ApplicationRecord
diff --git a/app/models/session_activation.rb b/app/models/session_activation.rb
index c1645223b..59565f877 100644
--- a/app/models/session_activation.rb
+++ b/app/models/session_activation.rb
@@ -3,25 +3,25 @@
 #
 # Table name: session_activations
 #
-#  id                       :integer          not null, primary key
-#  user_id                  :integer          not null
+#  id                       :bigint           not null, primary key
+#  user_id                  :bigint           not null
 #  session_id               :string           not null
 #  created_at               :datetime         not null
 #  updated_at               :datetime         not null
 #  user_agent               :string           default(""), not null
 #  ip                       :inet
-#  access_token_id          :integer
-#  web_push_subscription_id :integer
+#  access_token_id          :bigint
+#  web_push_subscription_id :bigint
 #
 
-#  id              :integer          not null, primary key
-#  user_id         :integer          not null
+#  id              :bigint           not null, primary key
+#  user_id         :bigint           not null
 #  session_id      :string           not null
 #  created_at      :datetime         not null
 #  updated_at      :datetime         not null
 #  user_agent      :string           default(""), not null
 #  ip              :inet
-#  access_token_id :integer
+#  access_token_id :bigint
 #
 
 class SessionActivation < ApplicationRecord
diff --git a/app/models/setting.rb b/app/models/setting.rb
index a14f156a1..be68d3123 100644
--- a/app/models/setting.rb
+++ b/app/models/setting.rb
@@ -8,8 +8,8 @@
 #  thing_type :string
 #  created_at :datetime
 #  updated_at :datetime
-#  id         :integer          not null, primary key
-#  thing_id   :integer
+#  id         :bigint           not null, primary key
+#  thing_id   :bigint
 #
 
 class Setting < RailsSettings::Base
diff --git a/app/models/site_upload.rb b/app/models/site_upload.rb
index 8ffdc8313..ba2ca777b 100644
--- a/app/models/site_upload.rb
+++ b/app/models/site_upload.rb
@@ -3,7 +3,7 @@
 #
 # Table name: site_uploads
 #
-#  id                :integer          not null, primary key
+#  id                :bigint           not null, primary key
 #  var               :string           default(""), not null
 #  file_file_name    :string
 #  file_content_type :string
diff --git a/app/models/status.rb b/app/models/status.rb
index d78a921b5..1dda6594e 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -3,25 +3,25 @@
 #
 # Table name: statuses
 #
-#  id                     :integer          not null, primary key
+#  id                     :bigint           not null, primary key
 #  uri                    :string
-#  account_id             :integer          not null
+#  account_id             :bigint           not null
 #  text                   :text             default(""), not null
 #  created_at             :datetime         not null
 #  updated_at             :datetime         not null
-#  in_reply_to_id         :integer
-#  reblog_of_id           :integer
+#  in_reply_to_id         :bigint
+#  reblog_of_id           :bigint
 #  url                    :string
 #  sensitive              :boolean          default(FALSE), not null
 #  visibility             :integer          default("public"), not null
-#  in_reply_to_account_id :integer
-#  application_id         :integer
+#  in_reply_to_account_id :bigint
+#  application_id         :bigint
 #  spoiler_text           :text             default(""), not null
 #  reply                  :boolean          default(FALSE), not null
 #  favourites_count       :integer          default(0), not null
 #  reblogs_count          :integer          default(0), not null
 #  language               :string
-#  conversation_id        :integer
+#  conversation_id        :bigint
 #  local                  :boolean
 #
 
diff --git a/app/models/status_pin.rb b/app/models/status_pin.rb
index a72c19750..5795d07bf 100644
--- a/app/models/status_pin.rb
+++ b/app/models/status_pin.rb
@@ -3,9 +3,9 @@
 #
 # Table name: status_pins
 #
-#  id         :integer          not null, primary key
-#  account_id :integer          not null
-#  status_id  :integer          not null
+#  id         :bigint           not null, primary key
+#  account_id :bigint           not null
+#  status_id  :bigint           not null
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
 #
diff --git a/app/models/stream_entry.rb b/app/models/stream_entry.rb
index 720cd518c..2b812d826 100644
--- a/app/models/stream_entry.rb
+++ b/app/models/stream_entry.rb
@@ -3,13 +3,13 @@
 #
 # Table name: stream_entries
 #
-#  activity_id   :integer
+#  activity_id   :bigint
 #  activity_type :string
 #  created_at    :datetime         not null
 #  updated_at    :datetime         not null
 #  hidden        :boolean          default(FALSE), not null
-#  account_id    :integer
-#  id            :integer          not null, primary key
+#  account_id    :bigint
+#  id            :bigint           not null, primary key
 #
 
 class StreamEntry < ApplicationRecord
diff --git a/app/models/subscription.rb b/app/models/subscription.rb
index 39860196b..bc50c5317 100644
--- a/app/models/subscription.rb
+++ b/app/models/subscription.rb
@@ -11,8 +11,8 @@
 #  updated_at                  :datetime         not null
 #  last_successful_delivery_at :datetime
 #  domain                      :string
-#  account_id                  :integer          not null
-#  id                          :integer          not null, primary key
+#  account_id                  :bigint           not null
+#  id                          :bigint           not null, primary key
 #
 
 class Subscription < ApplicationRecord
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 0fa08e157..6ebaf1145 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -3,7 +3,7 @@
 #
 # Table name: tags
 #
-#  id         :integer          not null, primary key
+#  id         :bigint           not null, primary key
 #  name       :string           default(""), not null
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
diff --git a/app/models/user.rb b/app/models/user.rb
index 325e27f44..326b871a1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -3,9 +3,8 @@
 #
 # Table name: users
 #
-#  id                        :integer          not null, primary key
+#  id                        :bigint           not null, primary key
 #  email                     :string           default(""), not null
-#  account_id                :integer          not null
 #  created_at                :datetime         not null
 #  updated_at                :datetime         not null
 #  encrypted_password        :string           default(""), not null
@@ -31,10 +30,14 @@
 #  last_emailed_at           :datetime
 #  otp_backup_codes          :string           is an Array
 #  filtered_languages        :string           default([]), not null, is an Array
+#  account_id                :bigint           not null
+#  disabled                  :boolean          default(FALSE), not null
+#  moderator                 :boolean          default(FALSE), not null
 #
 
 class User < ApplicationRecord
   include Settings::Extend
+
   ACTIVE_DURATION = 14.days
 
   devise :registerable, :recoverable,
@@ -51,8 +54,10 @@ class User < ApplicationRecord
   validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?
   validates_with BlacklistedEmailValidator, if: :email_changed?
 
-  scope :recent,    -> { order(id: :desc) }
-  scope :admins,    -> { where(admin: true) }
+  scope :recent, -> { order(id: :desc) }
+  scope :admins, -> { where(admin: true) }
+  scope :moderators, -> { where(moderator: true) }
+  scope :staff, -> { admins.or(moderators) }
   scope :confirmed, -> { where.not(confirmed_at: nil) }
   scope :inactive, -> { where(arel_table[:current_sign_in_at].lt(ACTIVE_DURATION.ago)) }
   scope :active, -> { confirmed.where(arel_table[:current_sign_in_at].gteq(ACTIVE_DURATION.ago)).joins(:account).where(accounts: { suspended: false }) }
@@ -68,54 +73,71 @@ class User < ApplicationRecord
 
   has_many :session_activations, dependent: :destroy
 
+  delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal,
+           :reduce_motion, :system_font_ui, :noindex, :theme,
+           to: :settings, prefix: :setting, allow_nil: false
+
   def confirmed?
     confirmed_at.present?
   end
 
-  def disable_two_factor!
-    self.otp_required_for_login = false
-    otp_backup_codes&.clear
-    save!
-  end
-
-  def setting_default_privacy
-    settings.default_privacy || (account.locked? ? 'private' : 'public')
+  def staff?
+    admin? || moderator?
   end
 
-  def setting_default_sensitive
-    settings.default_sensitive
+  def role
+    if admin?
+      'admin'
+    elsif moderator?
+      'moderator'
+    else
+      'user'
+    end
   end
 
-  def setting_unfollow_modal
-    settings.unfollow_modal
+  def disable!
+    update!(disabled: true,
+            last_sign_in_at: current_sign_in_at,
+            current_sign_in_at: nil)
   end
 
-  def setting_boost_modal
-    settings.boost_modal
+  def enable!
+    update!(disabled: false)
   end
 
-  def setting_delete_modal
-    settings.delete_modal
+  def confirm!
+    skip_confirmation!
+    save!
   end
 
-  def setting_auto_play_gif
-    settings.auto_play_gif
+  def promote!
+    if moderator?
+      update!(moderator: false, admin: true)
+    elsif !admin?
+      update!(moderator: true)
+    end
   end
 
-  def setting_reduce_motion
-    settings.reduce_motion
+  def demote!
+    if admin?
+      update!(admin: false, moderator: true)
+    elsif moderator?
+      update!(moderator: false)
+    end
   end
 
-  def setting_system_font_ui
-    settings.system_font_ui
+  def disable_two_factor!
+    self.otp_required_for_login = false
+    otp_backup_codes&.clear
+    save!
   end
 
-  def setting_noindex
-    settings.noindex
+  def active_for_authentication?
+    super && !disabled?
   end
 
-  def setting_theme
-    settings.theme
+  def setting_default_privacy
+    settings.default_privacy || (account.locked? ? 'private' : 'public')
   end
 
   def token_for_app(a)
diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb
index cb15dfa37..da67e7665 100644
--- a/app/models/web/push_subscription.rb
+++ b/app/models/web/push_subscription.rb
@@ -3,7 +3,7 @@
 #
 # Table name: web_push_subscriptions
 #
-#  id         :integer          not null, primary key
+#  id         :bigint           not null, primary key
 #  endpoint   :string           not null
 #  key_p256dh :string           not null
 #  key_auth   :string           not null
diff --git a/app/models/web/setting.rb b/app/models/web/setting.rb
index 1b0bfb2b7..6d08c4d35 100644
--- a/app/models/web/setting.rb
+++ b/app/models/web/setting.rb
@@ -6,8 +6,8 @@
 #  data       :json
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
-#  id         :integer          not null, primary key
-#  user_id    :integer
+#  id         :bigint           not null, primary key
+#  user_id    :bigint
 #
 
 class Web::Setting < ApplicationRecord