about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2021-11-26 05:58:18 +0100
committerGitHub <noreply@github.com>2021-11-26 05:58:18 +0100
commit7de0ee7aba86cffeaeffded7e0699214fb64364e (patch)
tree117d92cf2099a0b4c9b8e730ef18be80dc0e6f9a /app
parent12b3ff6c6d70df1ce34f4b103b519250c9e2d2c8 (diff)
Remove Keybase integration (#17045)
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/proofs_controller.rb23
-rw-r--r--app/controllers/api/v1/accounts/identity_proofs_controller.rb3
-rw-r--r--app/controllers/settings/identity_proofs_controller.rb60
-rw-r--r--app/controllers/well_known/keybase_proof_config_controller.rb9
-rw-r--r--app/javascript/mastodon/actions/identity_proofs.js31
-rw-r--r--app/javascript/mastodon/features/account/components/header.js16
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/header.js4
-rw-r--r--app/javascript/mastodon/features/account_timeline/containers/header_container.js2
-rw-r--r--app/javascript/mastodon/features/account_timeline/index.js2
-rw-r--r--app/javascript/mastodon/reducers/identity_proofs.js25
-rw-r--r--app/javascript/mastodon/reducers/index.js2
-rw-r--r--app/javascript/styles/mastodon/forms.scss62
-rw-r--r--app/lib/activitypub/adapter.rb1
-rw-r--r--app/lib/proof_provider.rb12
-rw-r--r--app/lib/proof_provider/keybase.rb69
-rw-r--r--app/lib/proof_provider/keybase/badge.rb45
-rw-r--r--app/lib/proof_provider/keybase/config_serializer.rb76
-rw-r--r--app/lib/proof_provider/keybase/serializer.rb25
-rw-r--r--app/lib/proof_provider/keybase/verifier.rb59
-rw-r--r--app/lib/proof_provider/keybase/worker.rb32
-rw-r--r--app/models/account_identity_proof.rb46
-rw-r--r--app/models/concerns/account_associations.rb3
-rw-r--r--app/models/concerns/account_merging.rb2
-rw-r--r--app/serializers/activitypub/actor_serializer.rb5
-rw-r--r--app/serializers/rest/identity_proof_serializer.rb17
-rw-r--r--app/services/activitypub/process_account_service.rb26
-rw-r--r--app/services/delete_account_service.rb2
-rw-r--r--app/views/accounts/_bio.html.haml10
-rw-r--r--app/views/admin/accounts/show.html.haml12
-rw-r--r--app/views/settings/identity_proofs/_proof.html.haml21
-rw-r--r--app/views/settings/identity_proofs/index.html.haml17
-rw-r--r--app/views/settings/identity_proofs/new.html.haml36
32 files changed, 11 insertions, 744 deletions
diff --git a/app/controllers/api/proofs_controller.rb b/app/controllers/api/proofs_controller.rb
deleted file mode 100644
index dd32cd577..000000000
--- a/app/controllers/api/proofs_controller.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-class Api::ProofsController < Api::BaseController
-  include AccountOwnedConcern
-
-  skip_before_action :require_authenticated_user!
-
-  before_action :set_provider
-
-  def index
-    render json: @account, serializer: @provider.serializer_class
-  end
-
-  private
-
-  def set_provider
-    @provider = ProofProvider.find(params[:provider]) || raise(ActiveRecord::RecordNotFound)
-  end
-
-  def username_param
-    params[:username]
-  end
-end
diff --git a/app/controllers/api/v1/accounts/identity_proofs_controller.rb b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
index 4b5f6902c..48f293f47 100644
--- a/app/controllers/api/v1/accounts/identity_proofs_controller.rb
+++ b/app/controllers/api/v1/accounts/identity_proofs_controller.rb
@@ -5,8 +5,7 @@ class Api::V1::Accounts::IdentityProofsController < Api::BaseController
   before_action :set_account
 
   def index
-    @proofs = @account.suspended? ? [] : @account.identity_proofs.active
-    render json: @proofs, each_serializer: REST::IdentityProofSerializer
+    render json: []
   end
 
   private
diff --git a/app/controllers/settings/identity_proofs_controller.rb b/app/controllers/settings/identity_proofs_controller.rb
deleted file mode 100644
index bf2899da6..000000000
--- a/app/controllers/settings/identity_proofs_controller.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: true
-
-class Settings::IdentityProofsController < Settings::BaseController
-  before_action :check_required_params, only: :new
-
-  def index
-    @proofs = AccountIdentityProof.where(account: current_account).order(provider: :asc, provider_username: :asc)
-    @proofs.each(&:refresh!)
-  end
-
-  def new
-    @proof = current_account.identity_proofs.new(
-      token: params[:token],
-      provider: params[:provider],
-      provider_username: params[:provider_username]
-    )
-
-    if current_account.username.casecmp(params[:username]).zero?
-      render layout: 'auth'
-    else
-      redirect_to settings_identity_proofs_path, alert: I18n.t('identity_proofs.errors.wrong_user', proving: params[:username], current: current_account.username)
-    end
-  end
-
-  def create
-    @proof = current_account.identity_proofs.where(provider: resource_params[:provider], provider_username: resource_params[:provider_username]).first_or_initialize(resource_params)
-    @proof.token = resource_params[:token]
-
-    if @proof.save
-      PostStatusService.new.call(current_user.account, text: post_params[:status_text]) if publish_proof?
-      redirect_to @proof.on_success_path(params[:user_agent])
-    else
-      redirect_to settings_identity_proofs_path, alert: I18n.t('identity_proofs.errors.failed', provider: @proof.provider.capitalize)
-    end
-  end
-
-  def destroy
-    @proof = current_account.identity_proofs.find(params[:id])
-    @proof.destroy!
-    redirect_to settings_identity_proofs_path, success: I18n.t('identity_proofs.removed')
-  end
-
-  private
-
-  def check_required_params
-    redirect_to settings_identity_proofs_path unless [:provider, :provider_username, :username, :token].all? { |k| params[k].present? }
-  end
-
-  def resource_params
-    params.require(:account_identity_proof).permit(:provider, :provider_username, :token)
-  end
-
-  def publish_proof?
-    ActiveModel::Type::Boolean.new.cast(post_params[:post_status])
-  end
-
-  def post_params
-    params.require(:account_identity_proof).permit(:post_status, :status_text)
-  end
-end
diff --git a/app/controllers/well_known/keybase_proof_config_controller.rb b/app/controllers/well_known/keybase_proof_config_controller.rb
deleted file mode 100644
index e1d43ecbe..000000000
--- a/app/controllers/well_known/keybase_proof_config_controller.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-module WellKnown
-  class KeybaseProofConfigController < ActionController::Base
-    def show
-      render json: {}, serializer: ProofProvider::Keybase::ConfigSerializer, root: 'keybase_config'
-    end
-  end
-end
diff --git a/app/javascript/mastodon/actions/identity_proofs.js b/app/javascript/mastodon/actions/identity_proofs.js
deleted file mode 100644
index 103983956..000000000
--- a/app/javascript/mastodon/actions/identity_proofs.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import api from '../api';
-
-export const IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST = 'IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST';
-export const IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS = 'IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS';
-export const IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL    = 'IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL';
-
-export const fetchAccountIdentityProofs = accountId => (dispatch, getState) => {
-  dispatch(fetchAccountIdentityProofsRequest(accountId));
-
-  api(getState).get(`/api/v1/accounts/${accountId}/identity_proofs`)
-    .then(({ data }) => dispatch(fetchAccountIdentityProofsSuccess(accountId, data)))
-    .catch(err => dispatch(fetchAccountIdentityProofsFail(accountId, err)));
-};
-
-export const fetchAccountIdentityProofsRequest = id => ({
-  type: IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST,
-  id,
-});
-
-export const fetchAccountIdentityProofsSuccess = (accountId, identity_proofs) => ({
-  type: IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS,
-  accountId,
-  identity_proofs,
-});
-
-export const fetchAccountIdentityProofsFail = (accountId, err) => ({
-  type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
-  accountId,
-  err,
-  skipNotFound: true,
-});
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 4d0a828c7..48ec49d81 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -123,7 +123,7 @@ class Header extends ImmutablePureComponent {
   }
 
   render () {
-    const { account, intl, domain, identity_proofs } = this.props;
+    const { account, intl, domain } = this.props;
 
     if (!account) {
       return null;
@@ -297,20 +297,8 @@ class Header extends ImmutablePureComponent {
 
           <div className='account__header__extra'>
             <div className='account__header__bio'>
-              {(fields.size > 0 || identity_proofs.size > 0) && (
+              {fields.size > 0 && (
                 <div className='account__header__fields'>
-                  {identity_proofs.map((proof, i) => (
-                    <dl key={i}>
-                      <dt dangerouslySetInnerHTML={{ __html: proof.get('provider') }} />
-
-                      <dd className='verified'>
-                        <a href={proof.get('proof_url')} target='_blank' rel='noopener noreferrer'><span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
-                          <Icon id='check' className='verified__mark' />
-                        </span></a>
-                        <a href={proof.get('profile_url')} target='_blank' rel='noopener noreferrer'><span dangerouslySetInnerHTML={{ __html: ' '+proof.get('provider_username') }} /></a>
-                      </dd>
-                    </dl>
-                  ))}
                   {fields.map((pair, i) => (
                     <dl key={i}>
                       <dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} className='translate' />
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index 17b693600..33bea4c17 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -11,7 +11,6 @@ export default class Header extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map,
-    identity_proofs: ImmutablePropTypes.list,
     onFollow: PropTypes.func.isRequired,
     onBlock: PropTypes.func.isRequired,
     onMention: PropTypes.func.isRequired,
@@ -92,7 +91,7 @@ export default class Header extends ImmutablePureComponent {
   }
 
   render () {
-    const { account, hideTabs, identity_proofs } = this.props;
+    const { account, hideTabs } = this.props;
 
     if (account === null) {
       return null;
@@ -104,7 +103,6 @@ export default class Header extends ImmutablePureComponent {
 
         <InnerHeader
           account={account}
-          identity_proofs={identity_proofs}
           onFollow={this.handleFollow}
           onBlock={this.handleBlock}
           onMention={this.handleMention}
diff --git a/app/javascript/mastodon/features/account_timeline/containers/header_container.js b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
index e12019547..b3f8521cb 100644
--- a/app/javascript/mastodon/features/account_timeline/containers/header_container.js
+++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
@@ -21,7 +21,6 @@ import { openModal } from '../../../actions/modal';
 import { blockDomain, unblockDomain } from '../../../actions/domain_blocks';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { unfollowModal } from '../../../initial_state';
-import { List as ImmutableList } from 'immutable';
 
 const messages = defineMessages({
   unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
@@ -34,7 +33,6 @@ const makeMapStateToProps = () => {
   const mapStateToProps = (state, { accountId }) => ({
     account: getAccount(state, accountId),
     domain: state.getIn(['meta', 'domain']),
-    identity_proofs: state.getIn(['identity_proofs', accountId], ImmutableList()),
   });
 
   return mapStateToProps;
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index 20f1dba9f..37df2818b 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -12,7 +12,6 @@ import ColumnBackButton from '../../components/column_back_button';
 import { List as ImmutableList } from 'immutable';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage } from 'react-intl';
-import { fetchAccountIdentityProofs } from '../../actions/identity_proofs';
 import MissingIndicator from 'mastodon/components/missing_indicator';
 import TimelineHint from 'mastodon/components/timeline_hint';
 import { me } from 'mastodon/initial_state';
@@ -80,7 +79,6 @@ class AccountTimeline extends ImmutablePureComponent {
     const { accountId, withReplies, dispatch } = this.props;
 
     dispatch(fetchAccount(accountId));
-    dispatch(fetchAccountIdentityProofs(accountId));
 
     if (!withReplies) {
       dispatch(expandAccountFeaturedTimeline(accountId));
diff --git a/app/javascript/mastodon/reducers/identity_proofs.js b/app/javascript/mastodon/reducers/identity_proofs.js
deleted file mode 100644
index 58af0a5fa..000000000
--- a/app/javascript/mastodon/reducers/identity_proofs.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Map as ImmutableMap, fromJS } from 'immutable';
-import {
-  IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST,
-  IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS,
-  IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
-} from '../actions/identity_proofs';
-
-const initialState = ImmutableMap();
-
-export default function identityProofsReducer(state = initialState, action) {
-  switch(action.type) {
-  case IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST:
-    return state.set('isLoading', true);
-  case IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL:
-    return state.set('isLoading', false);
-  case IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS:
-    return state.update(identity_proofs => identity_proofs.withMutations(map => {
-      map.set('isLoading', false);
-      map.set('loaded', true);
-      map.set(action.accountId, fromJS(action.identity_proofs));
-    }));
-  default:
-    return state;
-  }
-};
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index e518c8228..53e2dd681 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -32,7 +32,6 @@ import filters from './filters';
 import conversations from './conversations';
 import suggestions from './suggestions';
 import polls from './polls';
-import identity_proofs from './identity_proofs';
 import trends from './trends';
 import missed_updates from './missed_updates';
 import announcements from './announcements';
@@ -69,7 +68,6 @@ const reducers = {
   notifications,
   height_cache,
   custom_emojis,
-  identity_proofs,
   lists,
   listEditor,
   listAdder,
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index 5b71b6334..65f53471d 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -999,68 +999,6 @@ code {
   }
 }
 
-.connection-prompt {
-  margin-bottom: 25px;
-
-  .fa-link {
-    background-color: darken($ui-base-color, 4%);
-    border-radius: 100%;
-    font-size: 24px;
-    padding: 10px;
-  }
-
-  &__column {
-    align-items: center;
-    display: flex;
-    flex: 1;
-    flex-direction: column;
-    flex-shrink: 1;
-    max-width: 50%;
-
-    &-sep {
-      align-self: center;
-      flex-grow: 0;
-      overflow: visible;
-      position: relative;
-      z-index: 1;
-    }
-
-    p {
-      word-break: break-word;
-    }
-  }
-
-  .account__avatar {
-    margin-bottom: 20px;
-  }
-
-  &__connection {
-    background-color: lighten($ui-base-color, 8%);
-    box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
-    border-radius: 4px;
-    padding: 25px 10px;
-    position: relative;
-    text-align: center;
-
-    &::after {
-      background-color: darken($ui-base-color, 4%);
-      content: '';
-      display: block;
-      height: 100%;
-      left: 50%;
-      position: absolute;
-      top: 0;
-      width: 1px;
-    }
-  }
-
-  &__row {
-    align-items: flex-start;
-    display: flex;
-    flex-direction: row;
-  }
-}
-
 .input.user_confirm_password,
 .input.user_website {
   &:not(.field_with_errors) {
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb
index 2d6b87659..776e1d3da 100644
--- a/app/lib/activitypub/adapter.rb
+++ b/app/lib/activitypub/adapter.rb
@@ -18,7 +18,6 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
     atom_uri: { 'ostatus' => 'http://ostatus.org#', 'atomUri' => 'ostatus:atomUri' },
     conversation: { 'ostatus' => 'http://ostatus.org#', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation' },
     focal_point: { 'toot' => 'http://joinmastodon.org/ns#', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } },
-    identity_proof: { 'toot' => 'http://joinmastodon.org/ns#', 'IdentityProof' => 'toot:IdentityProof' },
     blurhash: { 'toot' => 'http://joinmastodon.org/ns#', 'blurhash' => 'toot:blurhash' },
     discoverable: { 'toot' => 'http://joinmastodon.org/ns#', 'discoverable' => 'toot:discoverable' },
     voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' },
diff --git a/app/lib/proof_provider.rb b/app/lib/proof_provider.rb
deleted file mode 100644
index 102c50f4f..000000000
--- a/app/lib/proof_provider.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-module ProofProvider
-  SUPPORTED_PROVIDERS = %w(keybase).freeze
-
-  def self.find(identifier, proof = nil)
-    case identifier
-    when 'keybase'
-      ProofProvider::Keybase.new(proof)
-    end
-  end
-end
diff --git a/app/lib/proof_provider/keybase.rb b/app/lib/proof_provider/keybase.rb
deleted file mode 100644
index 8e51d7146..000000000
--- a/app/lib/proof_provider/keybase.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-class ProofProvider::Keybase
-  BASE_URL = ENV.fetch('KEYBASE_BASE_URL', 'https://keybase.io')
-  DOMAIN   = ENV.fetch('KEYBASE_DOMAIN', Rails.configuration.x.web_domain)
-
-  class Error < StandardError; end
-
-  class ExpectedProofLiveError < Error; end
-
-  class UnexpectedResponseError < Error; end
-
-  def initialize(proof = nil)
-    @proof = proof
-  end
-
-  def serializer_class
-    ProofProvider::Keybase::Serializer
-  end
-
-  def worker_class
-    ProofProvider::Keybase::Worker
-  end
-
-  def validate!
-    unless @proof.token&.size == 66
-      @proof.errors.add(:base, I18n.t('identity_proofs.errors.keybase.invalid_token'))
-      return
-    end
-
-    # Do not perform synchronous validation for remote accounts
-    return if @proof.provider_username.blank? || !@proof.account.local?
-
-    if verifier.valid?
-      @proof.verified = true
-      @proof.live     = false
-    else
-      @proof.errors.add(:base, I18n.t('identity_proofs.errors.keybase.verification_failed', kb_username: @proof.provider_username))
-    end
-  end
-
-  def refresh!
-    worker_class.new.perform(@proof)
-  rescue ProofProvider::Keybase::Error
-    nil
-  end
-
-  def on_success_path(user_agent = nil)
-    verifier.on_success_path(user_agent)
-  end
-
-  def badge
-    @badge ||= ProofProvider::Keybase::Badge.new(@proof.account.username, @proof.provider_username, @proof.token, domain)
-  end
-
-  def verifier
-    @verifier ||= ProofProvider::Keybase::Verifier.new(@proof.account.username, @proof.provider_username, @proof.token, domain)
-  end
-
-  private
-
-  def domain
-    if @proof.account.local?
-      DOMAIN
-    else
-      @proof.account.domain
-    end
-  end
-end
diff --git a/app/lib/proof_provider/keybase/badge.rb b/app/lib/proof_provider/keybase/badge.rb
deleted file mode 100644
index f587b1cc7..000000000
--- a/app/lib/proof_provider/keybase/badge.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-class ProofProvider::Keybase::Badge
-  include RoutingHelper
-
-  def initialize(local_username, provider_username, token, domain)
-    @local_username    = local_username
-    @provider_username = provider_username
-    @token             = token
-    @domain            = domain
-  end
-
-  def proof_url
-    "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}/sigchain\##{@token}"
-  end
-
-  def profile_url
-    "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}"
-  end
-
-  def icon_url
-    "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}/proof_badge/#{@token}?username=#{@local_username}&domain=#{@domain}"
-  end
-
-  def avatar_url
-    Rails.cache.fetch("proof_providers/keybase/#{@provider_username}/avatar_url", expires_in: 5.minutes) { remote_avatar_url } || default_avatar_url
-  end
-
-  private
-
-  def remote_avatar_url
-    request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/user/pic_url.json", params: { username: @provider_username })
-
-    request.perform do |res|
-      json = Oj.load(res.body_with_limit, mode: :strict)
-      json['pic_url'] if json.is_a?(Hash)
-    end
-  rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError
-    nil
-  end
-
-  def default_avatar_url
-    asset_pack_path('media/images/proof_providers/keybase.png')
-  end
-end
diff --git a/app/lib/proof_provider/keybase/config_serializer.rb b/app/lib/proof_provider/keybase/config_serializer.rb
deleted file mode 100644
index c6c364d31..000000000
--- a/app/lib/proof_provider/keybase/config_serializer.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-# frozen_string_literal: true
-
-class ProofProvider::Keybase::ConfigSerializer < ActiveModel::Serializer
-  include RoutingHelper
-  include ActionView::Helpers::TextHelper
-
-  attributes :version, :domain, :display_name, :username,
-             :brand_color, :logo, :description, :prefill_url,
-             :profile_url, :check_url, :check_path, :avatar_path,
-             :contact
-
-  def version
-    1
-  end
-
-  def domain
-    ProofProvider::Keybase::DOMAIN
-  end
-
-  def display_name
-    Setting.site_title
-  end
-
-  def logo
-    {
-      svg_black: full_asset_url(asset_pack_path('media/images/logo_transparent_black.svg')),
-      svg_white: full_asset_url(asset_pack_path('media/images/logo_transparent_white.svg')),
-      svg_full: full_asset_url(asset_pack_path('media/images/logo.svg')),
-      svg_full_darkmode: full_asset_url(asset_pack_path('media/images/logo.svg')),
-    }
-  end
-
-  def brand_color
-    '#282c37'
-  end
-
-  def description
-    strip_tags(Setting.site_short_description.presence || I18n.t('about.about_mastodon_html'))
-  end
-
-  def username
-    { min: 1, max: 30, re: '[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?' }
-  end
-
-  def prefill_url
-    params = {
-      provider: 'keybase',
-      token: '%{sig_hash}',
-      provider_username: '%{kb_username}',
-      username: '%{username}',
-      user_agent: '%{kb_ua}',
-    }
-
-    CGI.unescape(new_settings_identity_proof_url(params))
-  end
-
-  def profile_url
-    CGI.unescape(short_account_url('%{username}'))
-  end
-
-  def check_url
-    CGI.unescape(api_proofs_url(username: '%{username}', provider: 'keybase'))
-  end
-
-  def check_path
-    ['signatures']
-  end
-
-  def avatar_path
-    ['avatar']
-  end
-
-  def contact
-    [Setting.site_contact_email.presence || 'unknown'].compact
-  end
-end
diff --git a/app/lib/proof_provider/keybase/serializer.rb b/app/lib/proof_provider/keybase/serializer.rb
deleted file mode 100644
index d29283600..000000000
--- a/app/lib/proof_provider/keybase/serializer.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-class ProofProvider::Keybase::Serializer < ActiveModel::Serializer
-  include RoutingHelper
-
-  attribute :avatar
-
-  has_many :identity_proofs, key: :signatures
-
-  def avatar
-    full_asset_url(object.avatar_original_url)
-  end
-
-  class AccountIdentityProofSerializer < ActiveModel::Serializer
-    attributes :sig_hash, :kb_username
-
-    def sig_hash
-      object.token
-    end
-
-    def kb_username
-      object.provider_username
-    end
-  end
-end
diff --git a/app/lib/proof_provider/keybase/verifier.rb b/app/lib/proof_provider/keybase/verifier.rb
deleted file mode 100644
index af69b1bfc..000000000
--- a/app/lib/proof_provider/keybase/verifier.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-class ProofProvider::Keybase::Verifier
-  def initialize(local_username, provider_username, token, domain)
-    @local_username    = local_username
-    @provider_username = provider_username
-    @token             = token
-    @domain            = domain
-  end
-
-  def valid?
-    request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/sig/proof_valid.json", params: query_params)
-
-    request.perform do |res|
-      json = Oj.load(res.body_with_limit, mode: :strict)
-
-      if json.is_a?(Hash)
-        json.fetch('proof_valid', false)
-      else
-        false
-      end
-    end
-  rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError
-    false
-  end
-
-  def on_success_path(user_agent = nil)
-    url = Addressable::URI.parse("#{ProofProvider::Keybase::BASE_URL}/_/proof_creation_success")
-    url.query_values = query_params.merge(kb_ua: user_agent || 'unknown')
-    url.to_s
-  end
-
-  def status
-    request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/sig/proof_live.json", params: query_params)
-
-    request.perform do |res|
-      raise ProofProvider::Keybase::UnexpectedResponseError unless res.code == 200
-
-      json = Oj.load(res.body_with_limit, mode: :strict)
-
-      raise ProofProvider::Keybase::UnexpectedResponseError unless json.is_a?(Hash) && json.key?('proof_valid') && json.key?('proof_live')
-
-      json
-    end
-  rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError
-    raise ProofProvider::Keybase::UnexpectedResponseError
-  end
-
-  private
-
-  def query_params
-    {
-      domain: @domain,
-      kb_username: @provider_username,
-      username: @local_username,
-      sig_hash: @token,
-    }
-  end
-end
diff --git a/app/lib/proof_provider/keybase/worker.rb b/app/lib/proof_provider/keybase/worker.rb
deleted file mode 100644
index bcdd18cc5..000000000
--- a/app/lib/proof_provider/keybase/worker.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-class ProofProvider::Keybase::Worker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: 'pull', retry: 20, unique: :until_executed
-
-  sidekiq_retry_in do |count, exception|
-    # Retry aggressively when the proof is valid but not live in Keybase.
-    # This is likely because Keybase just hasn't noticed the proof being
-    # served from here yet.
-
-    if exception.class == ProofProvider::Keybase::ExpectedProofLiveError
-      case count
-      when 0..2 then 0.seconds
-      when 2..6 then 1.second
-      end
-    end
-  end
-
-  def perform(proof_id)
-    proof  = proof_id.is_a?(AccountIdentityProof) ? proof_id : AccountIdentityProof.find(proof_id)
-    status = proof.provider_instance.verifier.status
-
-    # If Keybase thinks the proof is valid, and it exists here in Mastodon,
-    # then it should be live. Keybase just has to notice that it's here
-    # and then update its state. That might take a couple seconds.
-    raise ProofProvider::Keybase::ExpectedProofLiveError if status['proof_valid'] && !status['proof_live']
-
-    proof.update!(verified: status['proof_valid'], live: status['proof_live'])
-  end
-end
diff --git a/app/models/account_identity_proof.rb b/app/models/account_identity_proof.rb
deleted file mode 100644
index 10b66cccf..000000000
--- a/app/models/account_identity_proof.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-# frozen_string_literal: true
-# == Schema Information
-#
-# Table name: account_identity_proofs
-#
-#  id                :bigint(8)        not null, primary key
-#  account_id        :bigint(8)
-#  provider          :string           default(""), not null
-#  provider_username :string           default(""), not null
-#  token             :text             default(""), not null
-#  verified          :boolean          default(FALSE), not null
-#  live              :boolean          default(FALSE), not null
-#  created_at        :datetime         not null
-#  updated_at        :datetime         not null
-#
-
-class AccountIdentityProof < ApplicationRecord
-  belongs_to :account
-
-  validates :provider, inclusion: { in: ProofProvider::SUPPORTED_PROVIDERS }
-  validates :provider_username, format: { with: /\A[a-z0-9_]+\z/i }, length: { minimum: 2, maximum: 30 }
-  validates :provider_username, uniqueness: { scope: [:account_id, :provider] }
-  validates :token, format: { with: /\A[a-f0-9]+\z/ }, length: { maximum: 66 }
-
-  validate :validate_with_provider, if: :token_changed?
-
-  scope :active, -> { where(verified: true, live: true) }
-
-  after_commit :queue_worker, if: :saved_change_to_token?
-
-  delegate :refresh!, :on_success_path, :badge, to: :provider_instance
-
-  def provider_instance
-    @provider_instance ||= ProofProvider.find(provider, self)
-  end
-
-  private
-
-  def queue_worker
-    provider_instance.worker_class.perform_async(id)
-  end
-
-  def validate_with_provider
-    provider_instance.validate!
-  end
-end
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
index f2a4eae77..f9e7a3bea 100644
--- a/app/models/concerns/account_associations.rb
+++ b/app/models/concerns/account_associations.rb
@@ -7,8 +7,7 @@ module AccountAssociations
     # Local users
     has_one :user, inverse_of: :account, dependent: :destroy
 
-    # Identity proofs
-    has_many :identity_proofs, class_name: 'AccountIdentityProof', dependent: :destroy, inverse_of: :account
+    # E2EE
     has_many :devices, dependent: :destroy, inverse_of: :account
 
     # Timelines
diff --git a/app/models/concerns/account_merging.rb b/app/models/concerns/account_merging.rb
index 8d37c6e56..119773e6b 100644
--- a/app/models/concerns/account_merging.rb
+++ b/app/models/concerns/account_merging.rb
@@ -13,7 +13,7 @@ module AccountMerging
 
     owned_classes = [
       Status, StatusPin, MediaAttachment, Poll, Report, Tombstone, Favourite,
-      Follow, FollowRequest, Block, Mute, AccountIdentityProof,
+      Follow, FollowRequest, Block, Mute,
       AccountModerationNote, AccountPin, AccountStat, ListAccount,
       PollVote, Mention, AccountDeletionRequest, AccountNote, FollowRecommendationSuppression
     ]
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
index a7d948976..48707aa16 100644
--- a/app/serializers/activitypub/actor_serializer.rb
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -6,8 +6,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   context :security
 
   context_extensions :manually_approves_followers, :featured, :also_known_as,
-                     :moved_to, :property_value, :identity_proof,
-                     :discoverable, :olm, :suspended
+                     :moved_to, :property_value, :discoverable, :olm, :suspended
 
   attributes :id, :type, :following, :followers,
              :inbox, :outbox, :featured, :featured_tags,
@@ -143,7 +142,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
   end
 
   def virtual_attachments
-    object.suspended? ? [] : (object.fields + object.identity_proofs.active)
+    object.suspended? ? [] : object.fields
   end
 
   def moved_to
diff --git a/app/serializers/rest/identity_proof_serializer.rb b/app/serializers/rest/identity_proof_serializer.rb
deleted file mode 100644
index 0e7415935..000000000
--- a/app/serializers/rest/identity_proof_serializer.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-class REST::IdentityProofSerializer < ActiveModel::Serializer
-  attributes :provider, :provider_username, :updated_at, :proof_url, :profile_url
-
-  def proof_url
-    object.badge.proof_url
-  end
-
-  def profile_url
-    object.badge.profile_url
-  end
-
-  def provider
-    object.provider.capitalize
-  end
-end
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index 4ab6912e5..ec5140720 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -27,7 +27,6 @@ class ActivityPub::ProcessAccountService < BaseService
         create_account if @account.nil?
         update_account
         process_tags
-        process_attachments
 
         process_duplicate_accounts! if @options[:verified_webfinger]
       else
@@ -301,23 +300,6 @@ class ActivityPub::ProcessAccountService < BaseService
     end
   end
 
-  def process_attachments
-    return if @json['attachment'].blank?
-
-    previous_proofs = @account.identity_proofs.to_a
-    current_proofs  = []
-
-    as_array(@json['attachment']).each do |attachment|
-      next unless equals_or_includes?(attachment['type'], 'IdentityProof')
-      current_proofs << process_identity_proof(attachment)
-    end
-
-    previous_proofs.each do |previous_proof|
-      next if current_proofs.any? { |current_proof| current_proof.id == previous_proof.id }
-      previous_proof.delete
-    end
-  end
-
   def process_emoji(tag)
     return if skip_download?
     return if tag['name'].blank? || tag['icon'].blank? || tag['icon']['url'].blank?
@@ -334,12 +316,4 @@ class ActivityPub::ProcessAccountService < BaseService
     emoji.image_remote_url = image_url
     emoji.save
   end
-
-  def process_identity_proof(attachment)
-    provider          = attachment['signatureAlgorithm']
-    provider_username = attachment['name']
-    token             = attachment['signatureValue']
-
-    @account.identity_proofs.where(provider: provider, provider_username: provider_username).find_or_create_by(provider: provider, provider_username: provider_username, token: token)
-  end
 end
diff --git a/app/services/delete_account_service.rb b/app/services/delete_account_service.rb
index ac571d7e2..0e3fedfe7 100644
--- a/app/services/delete_account_service.rb
+++ b/app/services/delete_account_service.rb
@@ -17,7 +17,6 @@ class DeleteAccountService < BaseService
     domain_blocks
     featured_tags
     follow_requests
-    identity_proofs
     list_accounts
     migrations
     mute_relationships
@@ -45,7 +44,6 @@ class DeleteAccountService < BaseService
     domain_blocks
     featured_tags
     follow_requests
-    identity_proofs
     list_accounts
     migrations
     mute_relationships
diff --git a/app/views/accounts/_bio.html.haml b/app/views/accounts/_bio.html.haml
index efc26d136..e8a49a1aa 100644
--- a/app/views/accounts/_bio.html.haml
+++ b/app/views/accounts/_bio.html.haml
@@ -1,16 +1,8 @@
-- proofs = account.identity_proofs.active
 - fields = account.fields
 
 .public-account-bio
-  - unless fields.empty? && proofs.empty?
+  - unless fields.empty?
     .account__header__fields
-      - proofs.each do |proof|
-        %dl
-          %dt= proof.provider.capitalize
-          %dd.verified
-            = link_to fa_icon('check'), proof.badge.proof_url, class: 'verified__mark', title: t('accounts.link_verified_on', date: l(proof.updated_at))
-            = link_to proof.provider_username, proof.badge.profile_url
-
       - fields.each do |field|
         %dl
           %dt.emojify{ title: field.name }= Formatter.instance.format_field(account, field.name, custom_emojify: true)
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index 66eb49342..2b6e28e8d 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -8,20 +8,12 @@
 = render 'application/card', account: @account
 
 - account = @account
-- proofs = account.identity_proofs.active
 - fields = account.fields
-- unless fields.empty? && proofs.empty? && account.note.blank?
+- unless fields.empty? && account.note.blank?
   .admin-account-bio
-    - unless fields.empty? && proofs.empty?
+    - unless fields.empty?
       %div
         .account__header__fields
-          - proofs.each do |proof|
-            %dl
-              %dt= proof.provider.capitalize
-              %dd.verified
-                = link_to fa_icon('check'), proof.badge.proof_url, class: 'verified__mark', title: t('accounts.link_verified_on', date: l(proof.updated_at))
-                = link_to proof.provider_username, proof.badge.profile_url
-
           - fields.each do |field|
             %dl
               %dt.emojify{ title: field.name }= Formatter.instance.format_field(account, field.name, custom_emojify: true)
diff --git a/app/views/settings/identity_proofs/_proof.html.haml b/app/views/settings/identity_proofs/_proof.html.haml
deleted file mode 100644
index 14e8e91be..000000000
--- a/app/views/settings/identity_proofs/_proof.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-%tr
-  %td
-    = link_to proof.badge.profile_url, class: 'name-tag' do
-      = image_tag proof.badge.avatar_url, width: 15, height: 15, alt: '', class: 'avatar'
-      %span.username
-        = proof.provider_username
-        %span= "(#{proof.provider.capitalize})"
-
-  %td
-    - if proof.live?
-      %span.positive-hint
-        = fa_icon 'check-circle fw'
-        = t('identity_proofs.active')
-    - else
-      %span.negative-hint
-        = fa_icon 'times-circle fw'
-        = t('identity_proofs.inactive')
-
-  %td
-    = table_link_to 'external-link', t('identity_proofs.view_proof'), proof.badge.proof_url if proof.badge.proof_url
-    = table_link_to 'trash', t('identity_proofs.remove'), settings_identity_proof_path(proof), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/settings/identity_proofs/index.html.haml b/app/views/settings/identity_proofs/index.html.haml
deleted file mode 100644
index d0ea03ecd..000000000
--- a/app/views/settings/identity_proofs/index.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
-- content_for :page_title do
-  = t('settings.identity_proofs')
-
-%p= t('identity_proofs.explanation_html')
-
-- unless @proofs.empty?
-  %hr.spacer/
-
-  .table-wrapper
-    %table.table
-      %thead
-        %tr
-          %th= t('identity_proofs.identity')
-          %th= t('identity_proofs.status')
-          %th
-      %tbody
-        = render partial: 'settings/identity_proofs/proof', collection: @proofs, as: :proof
diff --git a/app/views/settings/identity_proofs/new.html.haml b/app/views/settings/identity_proofs/new.html.haml
deleted file mode 100644
index 5e4e9895d..000000000
--- a/app/views/settings/identity_proofs/new.html.haml
+++ /dev/null
@@ -1,36 +0,0 @@
-- content_for :page_title do
-  = t('identity_proofs.authorize_connection_prompt')
-
-.form-container
-  .oauth-prompt
-    %h2= t('identity_proofs.authorize_connection_prompt')
-
-  = simple_form_for @proof, url: settings_identity_proofs_url, html: { method: :post } do |f|
-    = f.input :provider, as: :hidden
-    = f.input :provider_username, as: :hidden
-    = f.input :token, as: :hidden
-
-    = hidden_field_tag :user_agent, params[:user_agent]
-
-    .connection-prompt
-      .connection-prompt__row.connection-prompt__connection
-        .connection-prompt__column
-          = image_tag current_account.avatar.url(:original), size: 96, class: 'account__avatar'
-
-          %p= t('identity_proofs.i_am_html', username: content_tag(:strong,current_account.username), service: site_hostname)
-
-        .connection-prompt__column.connection-prompt__column-sep
-          = fa_icon 'link'
-
-        .connection-prompt__column
-          = image_tag @proof.badge.avatar_url, size: 96, class: 'account__avatar'
-
-          %p= t('identity_proofs.i_am_html', username: content_tag(:strong, @proof.provider_username), service: @proof.provider.capitalize)
-
-    .connection-prompt__post
-      = f.input :post_status, label: t('identity_proofs.publicize_checkbox'), as: :boolean, wrapper: :with_label, :input_html => { checked: true }
-
-      = f.input :status_text, as: :text, input_html: { value: t('identity_proofs.publicize_toot', username: @proof.provider_username, service: @proof.provider.capitalize, url: @proof.badge.proof_url), rows: 4 }
-
-    = f.button :button, t('identity_proofs.authorize'), type: :submit
-    = link_to t('simple_form.no'), settings_identity_proofs_url, class: 'button negative'