From abc91e5fa6a0c9d621e798ae3e2de7377696dfc0 Mon Sep 17 00:00:00 2001
From: "Y.Yamashiro" <shukukei@mojizuri.jp>
Date: Wed, 2 Sep 2020 07:17:58 +0900
Subject: [PATCH 1/7] Change S3 ACL in "tootctl media remove-orphans
 --fix-permissions" from fixed value to environment file's value. (#14715)

---
 lib/mastodon/media_cli.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/mastodon/media_cli.rb b/lib/mastodon/media_cli.rb
index 31135f7fc62..5f4a414b1a5 100644
--- a/lib/mastodon/media_cli.rb
+++ b/lib/mastodon/media_cli.rb
@@ -67,6 +67,7 @@ module Mastodon
       when :s3
         paperclip_instance = MediaAttachment.new.file
         s3_interface       = paperclip_instance.s3_interface
+        s3_permissions     = Paperclip::Attachment.default_options[:s3_permissions]
         bucket             = s3_interface.bucket(Paperclip::Attachment.default_options[:s3_credentials][:bucket])
         last_key           = options[:start_after]
 
@@ -87,7 +88,7 @@ module Mastodon
           record_map = preload_records_from_mixed_objects(objects)
 
           objects.each do |object|
-            object.acl.put(acl: 'public-read') if options[:fix_permissions] && !options[:dry_run]
+            object.acl.put(acl: s3_permissions) if options[:fix_permissions] && !options[:dry_run]
 
             path_segments = object.key.split('/')
             path_segments.delete('cache')

From 17340365bbf057314d3cb19ec20c5d74b52c6395 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Wed, 2 Sep 2020 02:11:12 +0200
Subject: [PATCH 2/7] Add featured hashtags as an ActivityPub collection
 (#11595)

---
 .../activitypub/collections_controller.rb     | 32 +++++++++++--------
 app/lib/activitypub/adapter.rb                |  2 +-
 .../activitypub/actor_serializer.rb           |  6 +++-
 .../activitypub/collection_serializer.rb      |  2 ++
 .../activitypub/hashtag_serializer.rb         | 23 +++++++++++++
 5 files changed, 49 insertions(+), 16 deletions(-)
 create mode 100644 app/serializers/activitypub/hashtag_serializer.rb

diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb
index 380de54f5dc..c8b6dcc88d4 100644
--- a/app/controllers/activitypub/collections_controller.rb
+++ b/app/controllers/activitypub/collections_controller.rb
@@ -12,7 +12,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
 
   def show
     expires_in 3.minutes, public: public_fetch_mode?
-    render_with_cache json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, skip_activities: true
+    render_with_cache json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter
   end
 
   private
@@ -20,17 +20,9 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
   def set_items
     case params[:id]
     when 'featured'
-      @items = begin
-        # Because in public fetch mode we cache the response, there would be no
-        # benefit from performing the check below, since a blocked account or domain
-        # would likely be served the cache from the reverse proxy anyway
-
-        if authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
-          []
-        else
-          cache_collection(@account.pinned_statuses, Status)
-        end
-      end
+      @items = for_signed_account { cache_collection(@account.pinned_statuses, Status) }
+    when 'tags'
+      @items = for_signed_account { @account.featured_tags }
     when 'devices'
       @items = @account.devices
     else
@@ -40,7 +32,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
 
   def set_size
     case params[:id]
-    when 'featured', 'devices'
+    when 'featured', 'devices', 'tags'
       @size = @items.size
     else
       not_found
@@ -51,7 +43,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
     case params[:id]
     when 'featured'
       @type = :ordered
-    when 'devices'
+    when 'devices', 'tags'
       @type = :unordered
     else
       not_found
@@ -66,4 +58,16 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
       items: @items
     )
   end
+
+  def for_signed_account
+    # Because in public fetch mode we cache the response, there would be no
+    # benefit from performing the check below, since a blocked account or domain
+    # would likely be served the cache from the reverse proxy anyway
+
+    if authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
+      []
+    else
+      yield
+    end
+  end
 end
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb
index 634ed29fa3d..9a786c9a42c 100644
--- a/app/lib/activitypub/adapter.rb
+++ b/app/lib/activitypub/adapter.rb
@@ -13,7 +13,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
     moved_to: { 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' } },
     also_known_as: { 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' } },
     emoji: { 'toot' => 'http://joinmastodon.org/ns#', 'Emoji' => 'toot:Emoji' },
-    featured: { 'toot' => 'http://joinmastodon.org/ns#', 'featured' => { '@id' => 'toot:featured', '@type' => '@id' } },
+    featured: { 'toot' => 'http://joinmastodon.org/ns#', 'featured' => { '@id' => 'toot:featured', '@type' => '@id' }, 'featuredTags' => { '@id' => 'toot:featuredTags', '@type' => '@id' } },
     property_value: { 'schema' => 'http://schema.org#', 'PropertyValue' => 'schema:PropertyValue', 'value' => 'schema:value' },
     atom_uri: { 'ostatus' => 'http://ostatus.org#', 'atomUri' => 'ostatus:atomUri' },
     conversation: { 'ostatus' => 'http://ostatus.org#', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation' },
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
index 627d4446b99..da4a9272834 100644
--- a/app/serializers/activitypub/actor_serializer.rb
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -10,7 +10,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
                      :discoverable, :olm
 
   attributes :id, :type, :following, :followers,
-             :inbox, :outbox, :featured,
+             :inbox, :outbox, :featured, :featured_tags,
              :preferred_username, :name, :summary,
              :url, :manually_approves_followers,
              :discoverable
@@ -81,6 +81,10 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
     account_collection_url(object, :featured)
   end
 
+  def featured_tags
+    account_collection_url(object, :tags)
+  end
+
   def endpoints
     object
   end
diff --git a/app/serializers/activitypub/collection_serializer.rb b/app/serializers/activitypub/collection_serializer.rb
index ea7af543320..34026a6b5be 100644
--- a/app/serializers/activitypub/collection_serializer.rb
+++ b/app/serializers/activitypub/collection_serializer.rb
@@ -16,6 +16,8 @@ class ActivityPub::CollectionSerializer < ActivityPub::Serializer
       ActivityPub::NoteSerializer
     when 'Device'
       ActivityPub::DeviceSerializer
+    when 'FeaturedTag'
+      ActivityPub::HashtagSerializer
     when 'ActivityPub::CollectionPresenter'
       ActivityPub::CollectionSerializer
     when 'String'
diff --git a/app/serializers/activitypub/hashtag_serializer.rb b/app/serializers/activitypub/hashtag_serializer.rb
new file mode 100644
index 00000000000..1a56e4dfe4c
--- /dev/null
+++ b/app/serializers/activitypub/hashtag_serializer.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class ActivityPub::HashtagSerializer < ActivityPub::Serializer
+  include RoutingHelper
+
+  attributes :type, :href, :name
+
+  def type
+    'Hashtag'
+  end
+
+  def name
+    "##{object.name}"
+  end
+
+  def href
+    if object.class.name == 'FeaturedTag'
+      short_account_tag_url(object.account, object.tag)
+    else
+      tag_url(object)
+    end
+  end
+end

From 33ad850c982bbe03214e2e2870751920721c23af Mon Sep 17 00:00:00 2001
From: Takeshi Umeda <noel.yoshiba@gmail.com>
Date: Wed, 2 Sep 2020 09:13:10 +0900
Subject: [PATCH 3/7] Added account featured tags API (#11817)

---
 .../v1/accounts/featured_tags_controller.rb   | 22 +++++++++++++++++++
 .../rest/account_featured_tag_serializer.rb   | 19 ++++++++++++++++
 config/routes.rb                              |  1 +
 3 files changed, 42 insertions(+)
 create mode 100644 app/controllers/api/v1/accounts/featured_tags_controller.rb
 create mode 100644 app/serializers/rest/account_featured_tag_serializer.rb

diff --git a/app/controllers/api/v1/accounts/featured_tags_controller.rb b/app/controllers/api/v1/accounts/featured_tags_controller.rb
new file mode 100644
index 00000000000..d6277261d45
--- /dev/null
+++ b/app/controllers/api/v1/accounts/featured_tags_controller.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class Api::V1::Accounts::FeaturedTagsController < Api::BaseController
+  before_action :set_account
+  before_action :set_featured_tags
+
+  respond_to :json
+
+  def index
+    render json: @featured_tags, each_serializer: REST::AccountFeaturedTagSerializer
+  end
+
+  private
+
+  def set_account
+    @account = Account.find(params[:account_id])
+  end
+
+  def set_featured_tags
+    @featured_tags = @account.featured_tags
+  end
+end
diff --git a/app/serializers/rest/account_featured_tag_serializer.rb b/app/serializers/rest/account_featured_tag_serializer.rb
new file mode 100644
index 00000000000..d8d5fd68c5c
--- /dev/null
+++ b/app/serializers/rest/account_featured_tag_serializer.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class REST::AccountFeaturedTagSerializer < ActiveModel::Serializer
+  include RoutingHelper
+
+  attributes :id, :name, :url
+
+  def id
+    object.tag.id.to_s
+  end
+
+  def name
+    "##{object.name}"
+  end
+
+  def url
+    short_account_tag_url(object.account, object.tag)
+  end
+end
diff --git a/config/routes.rb b/config/routes.rb
index 2c39b36ed3f..8940101a4ae 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -430,6 +430,7 @@ Rails.application.routes.draw do
         resources :following, only: :index, controller: 'accounts/following_accounts'
         resources :lists, only: :index, controller: 'accounts/lists'
         resources :identity_proofs, only: :index, controller: 'accounts/identity_proofs'
+        resources :featured_tags, only: :index, controller: 'accounts/featured_tags'
 
         member do
           post :follow

From abee40b2322f191ce5da040c60cea1b0f09eee78 Mon Sep 17 00:00:00 2001
From: ThibG <thib@sitedethib.com>
Date: Wed, 2 Sep 2020 18:42:50 +0200
Subject: [PATCH 4/7] Add outbox attribute to instance actor (#14721)

It's not useful for now, but it's required by ActivityPub
---
 .../activitypub/outboxes_controller.rb        | 20 +++++++++++++++----
 app/controllers/instance_actors_controller.rb |  2 +-
 .../activitypub/actor_serializer.rb           |  2 +-
 config/routes.rb                              |  1 +
 4 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb
index c33c15255e1..e066860bfed 100644
--- a/app/controllers/activitypub/outboxes_controller.rb
+++ b/app/controllers/activitypub/outboxes_controller.rb
@@ -20,9 +20,9 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
   def outbox_presenter
     if page_requested?
       ActivityPub::CollectionPresenter.new(
-        id: account_outbox_url(@account, page_params),
+        id: outbox_url(page_params),
         type: :ordered,
-        part_of: account_outbox_url(@account),
+        part_of: outbox_url,
         prev: prev_page,
         next: next_page,
         items: @statuses
@@ -32,12 +32,20 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
         id: account_outbox_url(@account),
         type: :ordered,
         size: @account.statuses_count,
-        first: account_outbox_url(@account, page: true),
-        last: account_outbox_url(@account, page: true, min_id: 0)
+        first: outbox_url(page: true),
+        last: outbox_url(page: true, min_id: 0)
       )
     end
   end
 
+  def outbox_url(**kwargs)
+    if params[:account_username].present?
+      account_outbox_url(@account, **kwargs)
+    else
+      instance_actor_outbox_url(**kwargs)
+    end
+  end
+
   def next_page
     account_outbox_url(@account, page: true, max_id: @statuses.last.id) if @statuses.size == LIMIT
   end
@@ -65,4 +73,8 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
   def page_params
     { page: true, max_id: params[:max_id], min_id: params[:min_id] }.compact
   end
+
+  def set_account
+    @account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative
+  end
 end
diff --git a/app/controllers/instance_actors_controller.rb b/app/controllers/instance_actors_controller.rb
index 6f02d6a358f..4b074ca1926 100644
--- a/app/controllers/instance_actors_controller.rb
+++ b/app/controllers/instance_actors_controller.rb
@@ -17,6 +17,6 @@ class InstanceActorsController < ApplicationController
   end
 
   def restrict_fields_to
-    %i(id type preferred_username inbox public_key endpoints url manually_approves_followers)
+    %i(id type preferred_username inbox outbox public_key endpoints url manually_approves_followers)
   end
 end
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
index da4a9272834..5d2741b1742 100644
--- a/app/serializers/activitypub/actor_serializer.rb
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -74,7 +74,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   end
 
   def outbox
-    account_outbox_url(object)
+    object.instance_actor? ? instance_actor_outbox_url : account_outbox_url(object)
   end
 
   def featured
diff --git a/config/routes.rb b/config/routes.rb
index 8940101a4ae..c281a86e348 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -37,6 +37,7 @@ Rails.application.routes.draw do
 
   resource :instance_actor, path: 'actor', only: [:show] do
     resource :inbox, only: [:create], module: :activitypub
+    resource :outbox, only: [:show], module: :activitypub
   end
 
   devise_scope :user do

From 272aa4a10940db182c47e7523a34da951fd89f02 Mon Sep 17 00:00:00 2001
From: Takeshi Umeda <noel.yoshiba@gmail.com>
Date: Fri, 4 Sep 2020 15:49:56 +0900
Subject: [PATCH 5/7] Fix direct visibility style for light theme (#14727)

---
 app/javascript/styles/mastodon-light/diff.scss | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss
index 8c8d69fc47e..6b81e762370 100644
--- a/app/javascript/styles/mastodon-light/diff.scss
+++ b/app/javascript/styles/mastodon-light/diff.scss
@@ -256,14 +256,6 @@ html {
   background: $ui-base-color;
 }
 
-.status.status-direct {
-  background: lighten($ui-base-color, 4%);
-}
-
-.focusable:focus .status.status-direct {
-  background: lighten($ui-base-color, 8%);
-}
-
 .detailed-status,
 .detailed-status__action-bar {
   background: $white;

From 68d3b160de4305884c27410c8104fe3389401620 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Fri, 4 Sep 2020 20:22:26 +0200
Subject: [PATCH 6/7] Fix various warnings in rspec (#14729)

---
 spec/lib/feed_manager_spec.rb                         | 4 ++--
 spec/lib/spam_check_spec.rb                           | 8 ++++----
 spec/services/unallow_domain_service_spec.rb          | 6 +++---
 spec/workers/scheduler/feed_cleanup_scheduler_spec.rb | 4 ++--
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/spec/lib/feed_manager_spec.rb b/spec/lib/feed_manager_spec.rb
index 7219e0e5ba4..5088d174299 100644
--- a/spec/lib/feed_manager_spec.rb
+++ b/spec/lib/feed_manager_spec.rb
@@ -441,7 +441,7 @@ RSpec.describe FeedManager do
       FeedManager.instance.push_to_home(receiver, another_status)
 
       # We should have a tracking set and an entry in reblogs.
-      expect(Redis.current.exists(reblog_set_key)).to be true
+      expect(Redis.current.exists?(reblog_set_key)).to be true
       expect(Redis.current.zrange(reblogs_key, 0, -1)).to eq [reblogged.id.to_s]
 
       # Push everything off the end of the feed.
@@ -454,7 +454,7 @@ RSpec.describe FeedManager do
       FeedManager.instance.trim('home', receiver.id)
 
       # We should not have any reblog tracking data.
-      expect(Redis.current.exists(reblog_set_key)).to be false
+      expect(Redis.current.exists?(reblog_set_key)).to be false
       expect(Redis.current.zrange(reblogs_key, 0, -1)).to be_empty
     end
   end
diff --git a/spec/lib/spam_check_spec.rb b/spec/lib/spam_check_spec.rb
index d4d66a49930..159d8325735 100644
--- a/spec/lib/spam_check_spec.rb
+++ b/spec/lib/spam_check_spec.rb
@@ -150,9 +150,9 @@ RSpec.describe SpamCheck do
     let(:redis_key) { spam_check.send(:redis_key) }
 
     it 'remembers' do
-      expect(Redis.current.exists(redis_key)).to be true
+      expect(Redis.current.exists?(redis_key)).to be true
       spam_check.remember!
-      expect(Redis.current.exists(redis_key)).to be true
+      expect(Redis.current.exists?(redis_key)).to be true
     end
   end
 
@@ -166,9 +166,9 @@ RSpec.describe SpamCheck do
     end
 
     it 'resets' do
-      expect(Redis.current.exists(redis_key)).to be true
+      expect(Redis.current.exists?(redis_key)).to be true
       spam_check.reset!
-      expect(Redis.current.exists(redis_key)).to be false
+      expect(Redis.current.exists?(redis_key)).to be false
     end
   end
 
diff --git a/spec/services/unallow_domain_service_spec.rb b/spec/services/unallow_domain_service_spec.rb
index 559e152fb25..b93945b9a2a 100644
--- a/spec/services/unallow_domain_service_spec.rb
+++ b/spec/services/unallow_domain_service_spec.rb
@@ -55,9 +55,9 @@ RSpec.describe UnallowDomainService, type: :service do
       end
 
       it 'removes the remote accounts\'s statuses and media attachments' do
-        expect { bad_status1.reload }.to_not raise_exception ActiveRecord::RecordNotFound
-        expect { bad_status2.reload }.to_not raise_exception ActiveRecord::RecordNotFound
-        expect { bad_attachment.reload }.to_not raise_exception ActiveRecord::RecordNotFound
+        expect { bad_status1.reload }.to_not raise_error
+        expect { bad_status2.reload }.to_not raise_error
+        expect { bad_attachment.reload }.to_not raise_error
       end
     end
   end
diff --git a/spec/workers/scheduler/feed_cleanup_scheduler_spec.rb b/spec/workers/scheduler/feed_cleanup_scheduler_spec.rb
index 7fae680ba66..914eed829d2 100644
--- a/spec/workers/scheduler/feed_cleanup_scheduler_spec.rb
+++ b/spec/workers/scheduler/feed_cleanup_scheduler_spec.rb
@@ -16,8 +16,8 @@ describe Scheduler::FeedCleanupScheduler do
 
     expect(Redis.current.zcard(feed_key_for(inactive_user))).to eq 0
     expect(Redis.current.zcard(feed_key_for(active_user))).to eq 1
-    expect(Redis.current.exists(feed_key_for(inactive_user, 'reblogs'))).to be false
-    expect(Redis.current.exists(feed_key_for(inactive_user, 'reblogs:2'))).to be false
+    expect(Redis.current.exists?(feed_key_for(inactive_user, 'reblogs'))).to be false
+    expect(Redis.current.exists?(feed_key_for(inactive_user, 'reblogs:2'))).to be false
   end
 
   def feed_key_for(user, subtype = nil)

From a6121a159c5305ea9faa95743a50babb23ab41cd Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Fri, 4 Sep 2020 20:22:40 +0200
Subject: [PATCH 7/7] Remove obsolete IndexedDB operations from web UI (#14730)

Storing objects in IndexedDB was disabled in #7932, but we were
still trying to read objects from it before making an API call
---
 app/javascript/mastodon/actions/accounts.js | 37 +-----------
 app/javascript/mastodon/actions/statuses.js | 64 +--------------------
 2 files changed, 5 insertions(+), 96 deletions(-)

diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js
index cb2c682a45b..d28f7dad88b 100644
--- a/app/javascript/mastodon/actions/accounts.js
+++ b/app/javascript/mastodon/actions/accounts.js
@@ -1,6 +1,5 @@
 import api, { getLinks } from '../api';
-import openDB from '../storage/db';
-import { importAccount, importFetchedAccount, importFetchedAccounts } from './importer';
+import { importFetchedAccount, importFetchedAccounts } from './importer';
 
 export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
 export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
@@ -74,45 +73,13 @@ export const FOLLOW_REQUEST_REJECT_REQUEST = 'FOLLOW_REQUEST_REJECT_REQUEST';
 export const FOLLOW_REQUEST_REJECT_SUCCESS = 'FOLLOW_REQUEST_REJECT_SUCCESS';
 export const FOLLOW_REQUEST_REJECT_FAIL    = 'FOLLOW_REQUEST_REJECT_FAIL';
 
-function getFromDB(dispatch, getState, index, id) {
-  return new Promise((resolve, reject) => {
-    const request = index.get(id);
-
-    request.onerror = reject;
-
-    request.onsuccess = () => {
-      if (!request.result) {
-        reject();
-        return;
-      }
-
-      dispatch(importAccount(request.result));
-      resolve(request.result.moved && getFromDB(dispatch, getState, index, request.result.moved));
-    };
-  });
-}
-
 export function fetchAccount(id) {
   return (dispatch, getState) => {
     dispatch(fetchRelationships([id]));
-
-    if (getState().getIn(['accounts', id], null) !== null) {
-      return;
-    }
-
     dispatch(fetchAccountRequest(id));
 
-    openDB().then(db => getFromDB(
-      dispatch,
-      getState,
-      db.transaction('accounts', 'read').objectStore('accounts').index('id'),
-      id,
-    ).then(() => db.close(), error => {
-      db.close();
-      throw error;
-    })).catch(() => api(getState).get(`/api/v1/accounts/${id}`).then(response => {
+    api(getState).get(`/api/v1/accounts/${id}`).then(response => {
       dispatch(importFetchedAccount(response.data));
-    })).then(() => {
       dispatch(fetchAccountSuccess());
     }).catch(error => {
       dispatch(fetchAccountFail(id, error));
diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js
index e565e0b0ab5..3fc7c07023d 100644
--- a/app/javascript/mastodon/actions/statuses.js
+++ b/app/javascript/mastodon/actions/statuses.js
@@ -1,9 +1,7 @@
 import api from '../api';
-import openDB from '../storage/db';
-import { evictStatus } from '../storage/modifier';
 
 import { deleteFromTimelines } from './timelines';
-import { importFetchedStatus, importFetchedStatuses, importAccount, importStatus, importFetchedAccount } from './importer';
+import { importFetchedStatus, importFetchedStatuses, importFetchedAccount } from './importer';
 import { ensureComposeIsVisible } from './compose';
 
 export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
@@ -40,48 +38,6 @@ export function fetchStatusRequest(id, skipLoading) {
   };
 };
 
-function getFromDB(dispatch, getState, accountIndex, index, id) {
-  return new Promise((resolve, reject) => {
-    const request = index.get(id);
-
-    request.onerror = reject;
-
-    request.onsuccess = () => {
-      const promises = [];
-
-      if (!request.result) {
-        reject();
-        return;
-      }
-
-      dispatch(importStatus(request.result));
-
-      if (getState().getIn(['accounts', request.result.account], null) === null) {
-        promises.push(new Promise((accountResolve, accountReject) => {
-          const accountRequest = accountIndex.get(request.result.account);
-
-          accountRequest.onerror = accountReject;
-          accountRequest.onsuccess = () => {
-            if (!request.result) {
-              accountReject();
-              return;
-            }
-
-            dispatch(importAccount(accountRequest.result));
-            accountResolve();
-          };
-        }));
-      }
-
-      if (request.result.reblog && getState().getIn(['statuses', request.result.reblog], null) === null) {
-        promises.push(getFromDB(dispatch, getState, accountIndex, index, request.result.reblog));
-      }
-
-      resolve(Promise.all(promises));
-    };
-  });
-}
-
 export function fetchStatus(id) {
   return (dispatch, getState) => {
     const skipLoading = getState().getIn(['statuses', id], null) !== null;
@@ -94,23 +50,10 @@ export function fetchStatus(id) {
 
     dispatch(fetchStatusRequest(id, skipLoading));
 
-    openDB().then(db => {
-      const transaction = db.transaction(['accounts', 'statuses'], 'read');
-      const accountIndex = transaction.objectStore('accounts').index('id');
-      const index = transaction.objectStore('statuses').index('id');
-
-      return getFromDB(dispatch, getState, accountIndex, index, id).then(() => {
-        db.close();
-      }, error => {
-        db.close();
-        throw error;
-      });
-    }).then(() => {
-      dispatch(fetchStatusSuccess(skipLoading));
-    }, () => api(getState).get(`/api/v1/statuses/${id}`).then(response => {
+    api(getState).get(`/api/v1/statuses/${id}`).then(response => {
       dispatch(importFetchedStatus(response.data));
       dispatch(fetchStatusSuccess(skipLoading));
-    })).catch(error => {
+    }).catch(error => {
       dispatch(fetchStatusFail(id, error, skipLoading));
     });
   };
@@ -152,7 +95,6 @@ export function deleteStatus(id, routerHistory, withRedraft = false) {
     dispatch(deleteStatusRequest(id));
 
     api(getState).delete(`/api/v1/statuses/${id}`).then(response => {
-      evictStatus(id);
       dispatch(deleteStatusSuccess(id));
       dispatch(deleteFromTimelines(id));
       dispatch(importFetchedAccount(response.data.account));