closed_registrations_message
open_deletion
timeline_preview
+ bootstrap_timeline_accounts
).freeze
BOOLEAN_SETTINGS = %w(
class Auth::ConfirmationsController < Devise::ConfirmationsController
layout 'auth'
+
+ def show
+ super do |user|
+ BootstrapTimelineWorker.perform_async(user.account_id) if user.errors.empty?
+ end
+ end
end
:open_deletion=,
:timeline_preview,
:timeline_preview=,
+ :bootstrap_timeline_accounts,
+ :bootstrap_timeline_accounts=,
to: Setting
)
end
--- /dev/null
+# frozen_string_literal: true
+
+class BootstrapTimelineService < BaseService
+ def call(source_account)
+ bootstrap_timeline_accounts.each do |target_account|
+ FollowService.new.call(source_account, target_account)
+ end
+ end
+
+ private
+
+ def bootstrap_timeline_accounts
+ return @bootstrap_timeline_accounts if defined?(@bootstrap_timeline_accounts)
+
+ @bootstrap_timeline_accounts = bootstrap_timeline_accounts_usernames.empty? ? admin_accounts : local_unlocked_accounts(bootstrap_timeline_accounts_usernames)
+ end
+
+ def bootstrap_timeline_accounts_usernames
+ @bootstrap_timeline_accounts_usernames ||= (Setting.bootstrap_timeline_accounts || '').split(',').map { |str| str.strip.gsub(/\A@/, '') }.reject(&:blank?)
+ end
+
+ def admin_accounts
+ User.admins
+ .includes(:account)
+ .where(accounts: { locked: false })
+ .map(&:account)
+ end
+
+ def local_unlocked_accounts(usernames)
+ Account.local
+ .where(username: usernames)
+ .where(locked: false)
+ end
+end
# Follow a remote user, notify remote user about the follow
# @param [Account] source_account From which to follow
- # @param [String] uri User URI to follow in the form of username@domain
+ # @param [String, Account] uri User URI to follow in the form of username@domain (or account record)
def call(source_account, uri)
- target_account = ResolveRemoteAccountService.new.call(uri)
+ target_account = uri.is_a?(Account) ? uri : ResolveRemoteAccountService.new.call(uri)
raise ActiveRecord::RecordNotFound if target_account.nil? || target_account.id == source_account.id || target_account.suspended?
raise Mastodon::NotPermittedError if target_account.blocking?(source_account) || source_account.blocking?(target_account)
= f.input :site_extended_description, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_description_extended.title'), hint: t('admin.settings.site_description_extended.desc_html'), input_html: { rows: 8 }
= f.input :site_terms, wrapper: :with_block_label, as: :text, label: t('admin.settings.site_terms.title'), hint: t('admin.settings.site_terms.desc_html'), input_html: { rows: 8 }
+ %hr/
+
+ .fields-group
+ = f.input :bootstrap_timeline_accounts, wrapper: :with_block_label, label: t('admin.settings.bootstrap_timeline_accounts.title'), hint: t('admin.settings.bootstrap_timeline_accounts.desc_html')
+
.actions
= f.button :button, t('generic.save_changes'), type: :submit
--- /dev/null
+# frozen_string_literal: true
+
+class BootstrapTimelineWorker
+ include Sidekiq::Worker
+
+ def perform(account_id)
+ BootstrapTimelineService.new.call(Account.find(account_id))
+ end
+end
unresolved: Unresolved
view: View
settings:
+ bootstrap_timeline_accounts:
+ desc_html: Separate multiple usernames by comma. Only local and unlocked accounts will work. Default when empty is all local admins.
+ title: Default follows for new users
contact_information:
email: Business e-mail
username: Contact username
- root
- webmaster
- administrator
+ bootstrap_timeline_accounts: ''
development:
<<: *defaults
expect(response).to have_http_status(:success)
end
end
+
+ describe 'GET #show' do
+ let!(:user) { Fabricate(:user, confirmation_token: 'foobar', confirmed_at: nil) }
+
+ before do
+ allow(BootstrapTimelineWorker).to receive(:perform_async)
+ @request.env['devise.mapping'] = Devise.mappings[:user]
+ get :show, params: { confirmation_token: 'foobar' }
+ end
+
+ it 'redirects to login' do
+ expect(response).to redirect_to(new_user_session_path)
+ end
+
+ it 'queues up bootstrapping of home timeline' do
+ expect(BootstrapTimelineWorker).to have_received(:perform_async).with(user.account_id)
+ end
+ end
end
--- /dev/null
+require 'rails_helper'
+
+RSpec.describe BootstrapTimelineService do
+ subject { described_class.new }
+
+ describe '#call' do
+ let(:source_account) { Fabricate(:account) }
+
+ context 'when setting is empty' do
+ let!(:admin) { Fabricate(:user, admin: true) }
+
+ before do
+ Setting.bootstrap_timeline_accounts = nil
+ subject.call(source_account)
+ end
+
+ it 'follows admin accounts from account' do
+ expect(source_account.following?(admin.account)).to be true
+ end
+ end
+
+ context 'when setting is set' do
+ let!(:alice) { Fabricate(:account, username: 'alice') }
+ let!(:bob) { Fabricate(:account, username: 'bob') }
+
+ before do
+ Setting.bootstrap_timeline_accounts = 'alice, bob'
+ subject.call(source_account)
+ end
+
+ it 'follows found accounts from account' do
+ expect(source_account.following?(alice)).to be true
+ expect(source_account.following?(bob)).to be true
+ end
+ end
+ end
+end