about summary refs log tree commit diff
path: root/app/serializers
diff options
context:
space:
mode:
authorStarfall <root@starfall.blue>2019-12-09 19:07:33 -0600
committerStarfall <root@starfall.blue>2019-12-09 19:09:31 -0600
commit6b34fcfef7566105e8d80ab5fee0a539c06cddbf (patch)
tree8fad2d47bf8be255d3c671c40cbfd04c2f55ed03 /app/serializers
parent9fbb4af7611aa7836e65ef9f544d341423c15685 (diff)
parent246addd5b33a172600342af3fb6fb5e4c80ad95e (diff)
Merge branch 'glitch'`
Diffstat (limited to 'app/serializers')
-rw-r--r--app/serializers/activitypub/activity_serializer.rb1
-rw-r--r--app/serializers/activitypub/actor_serializer.rb24
-rw-r--r--app/serializers/activitypub/move_serializer.rb26
-rw-r--r--app/serializers/activitypub/note_serializer.rb21
-rw-r--r--app/serializers/activitypub/update_poll_serializer.rb2
-rw-r--r--app/serializers/initial_state_serializer.rb37
-rw-r--r--app/serializers/manifest_serializer.rb2
-rw-r--r--app/serializers/nodeinfo/discovery_serializer.rb11
-rw-r--r--app/serializers/nodeinfo/serializer.rb45
-rw-r--r--app/serializers/rest/account_serializer.rb6
-rw-r--r--app/serializers/rest/admin/account_serializer.rb77
-rw-r--r--app/serializers/rest/admin/report_serializer.rb16
-rw-r--r--app/serializers/rest/credential_account_serializer.rb1
-rw-r--r--app/serializers/rest/custom_emoji_serializer.rb10
-rw-r--r--app/serializers/rest/featured_tag_serializer.rb9
-rw-r--r--app/serializers/rest/instance_serializer.rb12
-rw-r--r--app/serializers/rest/marker_serializer.rb13
-rw-r--r--app/serializers/rest/poll_serializer.rb7
-rw-r--r--app/serializers/rest/search_serializer.rb7
-rw-r--r--app/serializers/rest/status_serializer.rb10
-rw-r--r--app/serializers/rest/v2/search_serializer.rb7
-rw-r--r--app/serializers/rest/web_push_subscription_serializer.rb2
-rw-r--r--app/serializers/rss/account_serializer.rb14
-rw-r--r--app/serializers/rss/tag_serializer.rb5
-rw-r--r--app/serializers/webfinger_serializer.rb26
25 files changed, 324 insertions, 67 deletions
diff --git a/app/serializers/activitypub/activity_serializer.rb b/app/serializers/activitypub/activity_serializer.rb
index c06d5c87c..d0edad786 100644
--- a/app/serializers/activitypub/activity_serializer.rb
+++ b/app/serializers/activitypub/activity_serializer.rb
@@ -4,6 +4,7 @@ class ActivityPub::ActivitySerializer < ActivityPub::Serializer
   attributes :id, :type, :actor, :published, :to, :cc
 
   has_one :proper, key: :object, serializer: ActivityPub::NoteSerializer, if: :serialize_object?
+
   attribute :proper_uri, key: :object, unless: :serialize_object?
   attribute :atom_uri, if: :announce?
 
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
index 0644219fb..aa64936a7 100644
--- a/app/serializers/activitypub/actor_serializer.rb
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -6,12 +6,14 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   context :security
 
   context_extensions :manually_approves_followers, :featured, :also_known_as,
-                     :moved_to, :property_value, :hashtag, :emoji, :identity_proof
+                     :moved_to, :property_value, :identity_proof,
+                     :discoverable
 
   attributes :id, :type, :following, :followers,
              :inbox, :outbox, :featured,
              :preferred_username, :name, :summary,
-             :url, :manually_approves_followers
+             :url, :manually_approves_followers,
+             :discoverable
 
   has_one :public_key, serializer: ActivityPub::PublicKeySerializer
 
@@ -39,11 +41,19 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   delegate :moved?, to: :object
 
   def id
-    account_url(object)
+    object.instance_actor? ? instance_actor_url : account_url(object)
   end
 
   def type
-    object.bot? ? 'Service' : 'Person'
+    if object.instance_actor?
+      'Application'
+    elsif object.bot?
+      'Service'
+    elsif object.group?
+      'Group'
+    else
+      'Person'
+    end
   end
 
   def following
@@ -55,7 +65,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   end
 
   def inbox
-    account_inbox_url(object)
+    object.instance_actor? ? instance_actor_inbox_url : account_inbox_url(object)
   end
 
   def outbox
@@ -95,7 +105,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   end
 
   def url
-    short_account_url(object)
+    object.instance_actor? ? about_more_url(instance_actor: true) : short_account_url(object)
   end
 
   def avatar_exists?
@@ -130,6 +140,8 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   end
 
   class TagSerializer < ActivityPub::Serializer
+    context_extensions :hashtag
+
     include RoutingHelper
 
     attributes :type, :href, :name
diff --git a/app/serializers/activitypub/move_serializer.rb b/app/serializers/activitypub/move_serializer.rb
new file mode 100644
index 000000000..5675875fa
--- /dev/null
+++ b/app/serializers/activitypub/move_serializer.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class ActivityPub::MoveSerializer < ActivityPub::Serializer
+  attributes :id, :type, :target, :actor
+  attribute :virtual_object, key: :object
+
+  def id
+    [ActivityPub::TagManager.instance.uri_for(object.account), '#moves/', object.id].join
+  end
+
+  def type
+    'Move'
+  end
+
+  def target
+    ActivityPub::TagManager.instance.uri_for(object.target_account)
+  end
+
+  def virtual_object
+    ActivityPub::TagManager.instance.uri_for(object.account)
+  end
+
+  def actor
+    ActivityPub::TagManager.instance.uri_for(object.account)
+  end
+end
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index 7225b2319..dce506fa2 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -1,8 +1,7 @@
 # frozen_string_literal: true
 
 class ActivityPub::NoteSerializer < ActivityPub::Serializer
-  context_extensions :atom_uri, :conversation, :sensitive,
-                     :hashtag, :emoji, :focal_point, :blurhash
+  context_extensions :atom_uri, :conversation, :sensitive, :voters_count
 
   attributes :id, :type, :summary,
              :in_reply_to, :published, :url,
@@ -24,8 +23,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
   attribute :end_time, if: :poll_and_expires?
   attribute :closed, if: :poll_and_expired?
 
+  attribute :voters_count, if: :poll_and_voters_count?
+
   def id
-    raise Mastodon::NotPermittedError, 'Local-only statuses should not be serialized' if object.local_only?
+    raise Mastodon::NotPermittedError, 'Local-only statuses should not be serialized' if object.local_only? && !instance_options[:allow_local_only]
     ActivityPub::TagManager.instance.uri_for(object)
   end
 
@@ -56,7 +57,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
         type: :unordered,
         part_of: ActivityPub::TagManager.instance.replies_uri_for(object),
         items: replies.map(&:second),
-        next: last_id ? ActivityPub::TagManager.instance.replies_uri_for(object, page: true, min_id: last_id) : nil
+        next: last_id ? ActivityPub::TagManager.instance.replies_uri_for(object, page: true, min_id: last_id) : ActivityPub::TagManager.instance.replies_uri_for(object, page: true, only_other_accounts: true)
       )
     )
   end
@@ -143,6 +144,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
 
   alias end_time closed
 
+  def voters_count
+    object.preloadable_poll.voters_count
+  end
+
   def poll_and_expires?
     object.preloadable_poll&.expires_at&.present?
   end
@@ -151,7 +156,13 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
     object.preloadable_poll&.expired?
   end
 
+  def poll_and_voters_count?
+    object.preloadable_poll&.voters_count
+  end
+
   class MediaAttachmentSerializer < ActivityPub::Serializer
+    context_extensions :blurhash, :focal_point
+
     include RoutingHelper
 
     attributes :type, :media_type, :url, :name, :blurhash
@@ -199,6 +210,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
   end
 
   class TagSerializer < ActivityPub::Serializer
+    context_extensions :hashtag
+
     include RoutingHelper
 
     attributes :type, :href, :name
diff --git a/app/serializers/activitypub/update_poll_serializer.rb b/app/serializers/activitypub/update_poll_serializer.rb
index b894f309f..1d47b9764 100644
--- a/app/serializers/activitypub/update_poll_serializer.rb
+++ b/app/serializers/activitypub/update_poll_serializer.rb
@@ -14,7 +14,7 @@ class ActivityPub::UpdatePollSerializer < ActivityPub::Serializer
   end
 
   def actor
-    ActivityPub::TagManager.instance.uri_for(object)
+    ActivityPub::TagManager.instance.uri_for(object.account)
   end
 
   def to
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index efed199f3..e5e88c200 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -26,6 +26,7 @@ class InitialStateSerializer < ActiveModel::Serializer
       access_token: object.token,
       locale: I18n.locale,
       domain: Rails.configuration.x.local_domain,
+      title: instance_presenter.site_title,
       admin: object.admin&.id&.to_s,
       search_enabled: Chewy.enabled?,
       repository: Mastodon::Version.repository,
@@ -34,21 +35,33 @@ class InitialStateSerializer < ActiveModel::Serializer
       invites_enabled: Setting.min_invite_role == 'user',
       mascot: instance_presenter.mascot&.file&.url,
       profile_directory: Setting.profile_directory,
+      trends: Setting.trends,
     }
 
     if object.current_account
-      store[:me]              = object.current_account.id.to_s
-      store[:unfollow_modal]  = object.current_account.user.setting_unfollow_modal
-      store[:boost_modal]     = object.current_account.user.setting_boost_modal
-      store[:favourite_modal] = object.current_account.user.setting_favourite_modal
-      store[:delete_modal]    = object.current_account.user.setting_delete_modal
-      store[:auto_play_gif]   = object.current_account.user.setting_auto_play_gif
-      store[:display_media]   = object.current_account.user.setting_display_media
-      store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
-      store[:reduce_motion]   = object.current_account.user.setting_reduce_motion
-      store[:advanced_layout] = object.current_account.user.setting_advanced_layout
-      store[:is_staff]        = object.current_account.user.staff?
+      store[:me]                = object.current_account.id.to_s
+      store[:unfollow_modal]    = object.current_account.user.setting_unfollow_modal
+      store[:boost_modal]       = object.current_account.user.setting_boost_modal
+      store[:favourite_modal]   = object.current_account.user.setting_favourite_modal
+      store[:delete_modal]      = object.current_account.user.setting_delete_modal
+      store[:auto_play_gif]     = object.current_account.user.setting_auto_play_gif
+      store[:display_media]     = object.current_account.user.setting_display_media
+      store[:expand_spoilers]   = object.current_account.user.setting_expand_spoilers
+      store[:reduce_motion]     = object.current_account.user.setting_reduce_motion
+      store[:advanced_layout]   = object.current_account.user.setting_advanced_layout
+      store[:use_blurhash]      = object.current_account.user.setting_use_blurhash
+      store[:use_pending_items] = object.current_account.user.setting_use_pending_items
+      store[:is_staff]          = object.current_account.user.staff?
+      store[:trends]            = Setting.trends && object.current_account.user.setting_trends
       store[:default_content_type] = object.current_account.user.setting_default_content_type
+      store[:system_emoji_font] = object.current_account.user.setting_system_emoji_font
+      store[:crop_images]       = object.current_account.user.setting_crop_images
+    else
+      store[:auto_play_gif] = Setting.auto_play_gif
+      store[:display_media] = Setting.display_media
+      store[:reduce_motion] = Setting.reduce_motion
+      store[:use_blurhash]  = Setting.use_blurhash
+      store[:crop_images]   = Setting.crop_images
     end
 
     store
@@ -76,7 +89,7 @@ class InitialStateSerializer < ActiveModel::Serializer
   end
 
   def media_attachments
-    { accept_content_types: MediaAttachment::IMAGE_FILE_EXTENSIONS + MediaAttachment::VIDEO_FILE_EXTENSIONS + MediaAttachment::AUDIO_FILE_EXTENSIONS + MediaAttachment::IMAGE_MIME_TYPES + MediaAttachment::VIDEO_MIME_TYPES + MediaAttachment::AUDIO_MIME_TYPES }
+    { accept_content_types: MediaAttachment.supported_file_extensions + MediaAttachment.supported_mime_types }
   end
 
   private
diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb
index 28127437d..21ec0d4be 100644
--- a/app/serializers/manifest_serializer.rb
+++ b/app/serializers/manifest_serializer.rb
@@ -55,6 +55,8 @@ class ManifestSerializer < ActiveModel::Serializer
     {
       url_template: 'share?title={title}&text={text}&url={url}',
       action: 'share',
+      method: 'GET',
+      enctype: 'application/x-www-form-urlencoded',
       params: {
         title: 'title',
         text: 'text',
diff --git a/app/serializers/nodeinfo/discovery_serializer.rb b/app/serializers/nodeinfo/discovery_serializer.rb
new file mode 100644
index 000000000..07ab2a6ee
--- /dev/null
+++ b/app/serializers/nodeinfo/discovery_serializer.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class NodeInfo::DiscoverySerializer < ActiveModel::Serializer
+  include RoutingHelper
+
+  attribute :links
+
+  def links
+    [{ rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0', href: nodeinfo_schema_url }]
+  end
+end
diff --git a/app/serializers/nodeinfo/serializer.rb b/app/serializers/nodeinfo/serializer.rb
new file mode 100644
index 000000000..7ff8aabec
--- /dev/null
+++ b/app/serializers/nodeinfo/serializer.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+class NodeInfo::Serializer < ActiveModel::Serializer
+  include RoutingHelper
+
+  attributes :version, :software, :protocols, :usage, :open_registrations
+
+  def version
+    '2.0'
+  end
+
+  def software
+    { name: 'mastodon', version: Mastodon::Version.to_s }
+  end
+
+  def services
+    { outbound: [], inbound: [] }
+  end
+
+  def protocols
+    %w(activitypub)
+  end
+
+  def usage
+    {
+      users: {
+        total: instance_presenter.user_count,
+        active_month: instance_presenter.active_user_count(4),
+        active_halfyear: instance_presenter.active_user_count(24),
+      },
+
+      local_posts: instance_presenter.status_count,
+    }
+  end
+
+  def open_registrations
+    Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
+  end
+
+  private
+
+  def instance_presenter
+    @instance_presenter ||= InstancePresenter.new
+  end
+end
diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb
index c34d23452..7bdb5d7ff 100644
--- a/app/serializers/rest/account_serializer.rb
+++ b/app/serializers/rest/account_serializer.rb
@@ -3,9 +3,9 @@
 class REST::AccountSerializer < ActiveModel::Serializer
   include RoutingHelper
 
-  attributes :id, :username, :acct, :display_name, :locked, :bot, :created_at,
+  attributes :id, :username, :acct, :display_name, :locked, :bot, :discoverable, :group, :created_at,
              :note, :url, :avatar, :avatar_static, :header, :header_static,
-             :followers_count, :following_count, :statuses_count
+             :followers_count, :following_count, :statuses_count, :last_status_at
 
   has_one :moved_to_account, key: :moved, serializer: REST::AccountSerializer, if: :moved_and_not_nested?
   has_many :emojis, serializer: REST::CustomEmojiSerializer
@@ -29,7 +29,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
   end
 
   def url
-    TagManager.instance.url_for(object)
+    ActivityPub::TagManager.instance.url_for(object)
   end
 
   def avatar
diff --git a/app/serializers/rest/admin/account_serializer.rb b/app/serializers/rest/admin/account_serializer.rb
new file mode 100644
index 000000000..f579d3302
--- /dev/null
+++ b/app/serializers/rest/admin/account_serializer.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+class REST::Admin::AccountSerializer < ActiveModel::Serializer
+  attributes :id, :username, :domain, :created_at,
+             :email, :ip, :role, :confirmed, :suspended,
+             :silenced, :disabled, :approved, :locale,
+             :invite_request
+
+  attribute :created_by_application_id, if: :created_by_application?
+  attribute :invited_by_account_id, if: :invited?
+
+  has_one :account, serializer: REST::AccountSerializer
+
+  def id
+    object.id.to_s
+  end
+
+  def email
+    object.user_email
+  end
+
+  def ip
+    object.user_current_sign_in_ip.to_s.presence
+  end
+
+  def role
+    object.user_role
+  end
+
+  def suspended
+    object.suspended?
+  end
+
+  def silenced
+    object.silenced?
+  end
+
+  def confirmed
+    object.user_confirmed?
+  end
+
+  def disabled
+    object.user_disabled?
+  end
+
+  def approved
+    object.user_approved?
+  end
+
+  def account
+    object
+  end
+
+  def locale
+    object.user_locale
+  end
+
+  def created_by_application_id
+    object.user&.created_by_application_id&.to_s&.presence
+  end
+
+  def invite_request
+    object.user&.invite_request&.text
+  end
+
+  def invited_by_account_id
+    object.user&.invite&.user&.account_id&.to_s&.presence
+  end
+
+  def invited?
+    object.user&.invited?
+  end
+
+  def created_by_application?
+    object.user&.created_by_application_id&.present?
+  end
+end
diff --git a/app/serializers/rest/admin/report_serializer.rb b/app/serializers/rest/admin/report_serializer.rb
new file mode 100644
index 000000000..7a77132c0
--- /dev/null
+++ b/app/serializers/rest/admin/report_serializer.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class REST::Admin::ReportSerializer < ActiveModel::Serializer
+  attributes :id, :action_taken, :comment, :created_at, :updated_at
+
+  has_one :account, serializer: REST::Admin::AccountSerializer
+  has_one :target_account, serializer: REST::Admin::AccountSerializer
+  has_one :assigned_account, serializer: REST::Admin::AccountSerializer
+  has_one :action_taken_by_account, serializer: REST::Admin::AccountSerializer
+
+  has_many :statuses, serializer: REST::StatusSerializer
+
+  def id
+    object.id.to_s
+  end
+end
diff --git a/app/serializers/rest/credential_account_serializer.rb b/app/serializers/rest/credential_account_serializer.rb
index fb195eb07..be0d763dc 100644
--- a/app/serializers/rest/credential_account_serializer.rb
+++ b/app/serializers/rest/credential_account_serializer.rb
@@ -12,6 +12,7 @@ class REST::CredentialAccountSerializer < REST::AccountSerializer
       language: user.setting_default_language,
       note: object.note,
       fields: object.fields.map(&:to_h),
+      follow_requests_count: FollowRequest.where(target_account: object).limit(40).count,
     }
   end
 end
diff --git a/app/serializers/rest/custom_emoji_serializer.rb b/app/serializers/rest/custom_emoji_serializer.rb
index 65686a866..aff58e4d9 100644
--- a/app/serializers/rest/custom_emoji_serializer.rb
+++ b/app/serializers/rest/custom_emoji_serializer.rb
@@ -5,6 +5,8 @@ class REST::CustomEmojiSerializer < ActiveModel::Serializer
 
   attributes :shortcode, :url, :static_url, :visible_in_picker
 
+  attribute :category, if: :category_loaded?
+
   def url
     full_asset_url(object.image.url)
   end
@@ -12,4 +14,12 @@ class REST::CustomEmojiSerializer < ActiveModel::Serializer
   def static_url
     full_asset_url(object.image.url(:static))
   end
+
+  def category
+    object.category.name
+  end
+
+  def category_loaded?
+    object.association(:category).loaded? && object.category.present?
+  end
 end
diff --git a/app/serializers/rest/featured_tag_serializer.rb b/app/serializers/rest/featured_tag_serializer.rb
new file mode 100644
index 000000000..08121ff16
--- /dev/null
+++ b/app/serializers/rest/featured_tag_serializer.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class REST::FeaturedTagSerializer < ActiveModel::Serializer
+  attributes :id, :name, :statuses_count, :last_status_at
+
+  def id
+    object.id.to_s
+  end
+end
diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb
index 98c53c84a..e913f0c64 100644
--- a/app/serializers/rest/instance_serializer.rb
+++ b/app/serializers/rest/instance_serializer.rb
@@ -3,9 +3,9 @@
 class REST::InstanceSerializer < ActiveModel::Serializer
   include RoutingHelper
 
-  attributes :uri, :title, :description, :email,
+  attributes :uri, :title, :short_description, :description, :email,
              :version, :urls, :stats, :thumbnail, :max_toot_chars, :poll_limits,
-             :languages, :registrations
+             :languages, :registrations, :approval_required
 
   has_one :contact_account, serializer: REST::AccountSerializer
 
@@ -19,6 +19,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer
     Setting.site_title
   end
 
+  def short_description
+    Setting.site_short_description
+  end
+
   def description
     Setting.site_description
   end
@@ -68,6 +72,10 @@ class REST::InstanceSerializer < ActiveModel::Serializer
     Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
   end
 
+  def approval_required
+    Setting.registrations_mode == 'approved'
+  end
+
   private
 
   def instance_presenter
diff --git a/app/serializers/rest/marker_serializer.rb b/app/serializers/rest/marker_serializer.rb
new file mode 100644
index 000000000..2eaf3d507
--- /dev/null
+++ b/app/serializers/rest/marker_serializer.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class REST::MarkerSerializer < ActiveModel::Serializer
+  attributes :last_read_id, :version, :updated_at
+
+  def last_read_id
+    object.last_read_id.to_s
+  end
+
+  def version
+    object.lock_version
+  end
+end
diff --git a/app/serializers/rest/poll_serializer.rb b/app/serializers/rest/poll_serializer.rb
index 356c45b83..df6ebd0d4 100644
--- a/app/serializers/rest/poll_serializer.rb
+++ b/app/serializers/rest/poll_serializer.rb
@@ -2,12 +2,13 @@
 
 class REST::PollSerializer < ActiveModel::Serializer
   attributes :id, :expires_at, :expired,
-             :multiple, :votes_count
+             :multiple, :votes_count, :voters_count
 
   has_many :loaded_options, key: :options
   has_many :emojis, serializer: REST::CustomEmojiSerializer
 
   attribute :voted, if: :current_user?
+  attribute :own_votes, if: :current_user?
 
   def id
     object.id.to_s
@@ -21,6 +22,10 @@ class REST::PollSerializer < ActiveModel::Serializer
     object.voted?(current_user.account)
   end
 
+  def own_votes
+    object.own_votes(current_user.account)
+  end
+
   def current_user?
     !current_user.nil?
   end
diff --git a/app/serializers/rest/search_serializer.rb b/app/serializers/rest/search_serializer.rb
index 157f543ae..ee9b421eb 100644
--- a/app/serializers/rest/search_serializer.rb
+++ b/app/serializers/rest/search_serializer.rb
@@ -1,12 +1,7 @@
 # frozen_string_literal: true
 
 class REST::SearchSerializer < ActiveModel::Serializer
-  attributes :hashtags
-
   has_many :accounts, serializer: REST::AccountSerializer
   has_many :statuses, serializer: REST::StatusSerializer
-
-  def hashtags
-    object.hashtags.map(&:name)
-  end
+  has_many :hashtags, serializer: REST::TagSerializer
 end
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index b07937014..023913028 100644
--- a/app/serializers/rest/status_serializer.rb
+++ b/app/serializers/rest/status_serializer.rb
@@ -61,7 +61,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
   end
 
   def uri
-    OStatus::TagManager.instance.uri_for(object)
+    ActivityPub::TagManager.instance.uri_for(object)
   end
 
   def content
@@ -69,7 +69,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
   end
 
   def url
-    TagManager.instance.url_for(object)
+    ActivityPub::TagManager.instance.url_for(object)
   end
 
   def favourited
@@ -97,8 +97,8 @@ class REST::StatusSerializer < ActiveModel::Serializer
   end
 
   def bookmarked
-    if instance_options && instance_options[:bookmarks]
-      instance_options[:bookmarks].bookmarks_map[object.id] || false
+    if instance_options && instance_options[:relationships]
+      instance_options[:relationships].bookmarks_map[object.id] || false
     else
       current_user.account.bookmarked?(object)
     end
@@ -143,7 +143,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
     end
 
     def url
-      TagManager.instance.url_for(object.account)
+      ActivityPub::TagManager.instance.url_for(object.account)
     end
 
     def acct
diff --git a/app/serializers/rest/v2/search_serializer.rb b/app/serializers/rest/v2/search_serializer.rb
deleted file mode 100644
index cdb6b3a53..000000000
--- a/app/serializers/rest/v2/search_serializer.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-class REST::V2::SearchSerializer < ActiveModel::Serializer
-  has_many :accounts, serializer: REST::AccountSerializer
-  has_many :statuses, serializer: REST::StatusSerializer
-  has_many :hashtags, serializer: REST::TagSerializer
-end
diff --git a/app/serializers/rest/web_push_subscription_serializer.rb b/app/serializers/rest/web_push_subscription_serializer.rb
index 7fd952a56..194cc0a8c 100644
--- a/app/serializers/rest/web_push_subscription_serializer.rb
+++ b/app/serializers/rest/web_push_subscription_serializer.rb
@@ -4,7 +4,7 @@ class REST::WebPushSubscriptionSerializer < ActiveModel::Serializer
   attributes :id, :endpoint, :alerts, :server_key
 
   def alerts
-    object.data&.dig('alerts') || {}
+    (object.data&.dig('alerts') || {}).each_with_object({}) { |(k, v), h| h[k] = ActiveModel::Type::Boolean.new.cast(v) }
   end
 
   def server_key
diff --git a/app/serializers/rss/account_serializer.rb b/app/serializers/rss/account_serializer.rb
index 88eca79ed..ee972ff96 100644
--- a/app/serializers/rss/account_serializer.rb
+++ b/app/serializers/rss/account_serializer.rb
@@ -2,15 +2,15 @@
 
 class RSS::AccountSerializer
   include ActionView::Helpers::NumberHelper
-  include StreamEntriesHelper
+  include AccountsHelper
   include RoutingHelper
 
-  def render(account, statuses)
+  def render(account, statuses, tag)
     builder = RSSBuilder.new
 
     builder.title("#{display_name(account)} (@#{account.local_username_and_domain})")
            .description(account_description(account))
-           .link(TagManager.instance.url_for(account))
+           .link(tag.present? ? short_account_tag_url(account, tag) : short_account_url(account))
            .logo(full_pack_url('media/images/logo.svg'))
            .accent_color('2b90d9')
 
@@ -20,12 +20,12 @@ class RSS::AccountSerializer
     statuses.each do |status|
       builder.item do |item|
         item.title(status.title)
-            .link(TagManager.instance.url_for(status))
+            .link(ActivityPub::TagManager.instance.url_for(status))
             .pub_date(status.created_at)
             .description(status.spoiler_text.presence || Formatter.instance.format(status, inline_poll_options: true).to_str)
 
         status.media_attachments.each do |media|
-          item.enclosure(full_asset_url(media.file.url(:original, false)), media.file.content_type, length: media.file.size)
+          item.enclosure(full_asset_url(media.file.url(:original, false)), media.file.content_type, media.file.size)
         end
       end
     end
@@ -33,7 +33,7 @@ class RSS::AccountSerializer
     builder.to_xml
   end
 
-  def self.render(account, statuses)
-    new.render(account, statuses)
+  def self.render(account, statuses, tag)
+    new.render(account, statuses, tag)
   end
 end
diff --git a/app/serializers/rss/tag_serializer.rb b/app/serializers/rss/tag_serializer.rb
index 644380149..ea26189a2 100644
--- a/app/serializers/rss/tag_serializer.rb
+++ b/app/serializers/rss/tag_serializer.rb
@@ -3,7 +3,6 @@
 class RSS::TagSerializer
   include ActionView::Helpers::NumberHelper
   include ActionView::Helpers::SanitizeHelper
-  include StreamEntriesHelper
   include RoutingHelper
 
   def render(tag, statuses)
@@ -18,12 +17,12 @@ class RSS::TagSerializer
     statuses.each do |status|
       builder.item do |item|
         item.title(status.title)
-            .link(TagManager.instance.url_for(status))
+            .link(ActivityPub::TagManager.instance.url_for(status))
             .pub_date(status.created_at)
             .description(status.spoiler_text.presence || Formatter.instance.format(status).to_str)
 
         status.media_attachments.each do |media|
-          item.enclosure(full_asset_url(media.file.url(:original, false)), media.file.content_type, length: media.file.size)
+          item.enclosure(full_asset_url(media.file.url(:original, false)), media.file.content_type, media.file.size)
         end
       end
     end
diff --git a/app/serializers/webfinger_serializer.rb b/app/serializers/webfinger_serializer.rb
index 8c0b07702..c67363b8f 100644
--- a/app/serializers/webfinger_serializer.rb
+++ b/app/serializers/webfinger_serializer.rb
@@ -10,17 +10,25 @@ class WebfingerSerializer < ActiveModel::Serializer
   end
 
   def aliases
-    [short_account_url(object), account_url(object)]
+    if object.instance_actor?
+      [instance_actor_url]
+    else
+      [short_account_url(object), account_url(object)]
+    end
   end
 
   def links
-    [
-      { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: short_account_url(object) },
-      { rel: 'http://schemas.google.com/g/2010#updates-from', type: 'application/atom+xml', href: account_url(object, format: 'atom') },
-      { rel: 'self', type: 'application/activity+json', href: account_url(object) },
-      { rel: 'salmon', href: api_salmon_url(object.id) },
-      { rel: 'magic-public-key', href: "data:application/magic-public-key,#{object.magic_key}" },
-      { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" },
-    ]
+    if object.instance_actor?
+      [
+        { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: about_more_url(instance_actor: true) },
+        { rel: 'self', type: 'application/activity+json', href: instance_actor_url },
+      ]
+    else
+      [
+        { rel: 'http://webfinger.net/rel/profile-page', type: 'text/html', href: short_account_url(object) },
+        { rel: 'self', type: 'application/activity+json', href: account_url(object) },
+        { rel: 'http://ostatus.org/schema/1.0/subscribe', template: "#{authorize_interaction_url}?uri={uri}" },
+      ]
+    end
   end
 end